iOS SDK

SDK Guide for iOS

Demo project

SDK iOS Installation / Usage

Cocoapod

You can download MFSDK by adding this line to your Podfile

pod 'MyFatoorah'
pod repo update
pod install
pod 'MyFatoorah'
pod repo update
pod install

Swift Package Manager

You can download MFSDK by adding the https://dev.azure.com/myfatoorahsc/_git/MF-SDK-iOS-Demo repository as a Swift Package

Import framework in AppDelegate:

import MFSDK
import MFSDK

Add below code in the didFinishLaunchingWithOptions method:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// set up your My Fatoorah Merchant details
MFSettings.shared.configure(token: <#Put your token here#>, country: <# Country of your account #>, environment: <# Test or Live #>)


// you can change color and title of nvgigation bar
let them = MFTheme(navigationTintColor: .white, navigationBarTintColor: .lightGray, navigationTitle: "Payment", cancelButtonTitle: "Cancel")
MFSettings.shared.setTheme(theme: them)
return true
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// set up your My Fatoorah Merchant details
    [[MFSettings shared] configureWithToken:@<#Put your token here#> country: <#Country of your account#>  environment:<#Live or Test#>];


// you can change color and title of nvgigation bar
MFTheme* theme = [[MFTheme alloc] initWithNavigationTintColor:[UIColor whiteColor] navigationBarTintColor:[UIColor lightGrayColor] navigationTitle:@"Payment" cancelButtonTitle:@"Cancel"];
[[MFSettings shared] setThemeWithTheme:theme];

return YES;
}

📘

Updating Your System:

Starting from release '2.0.132', MyFatoorah will not call the callbackurl or errorurl. To update your system, share the invoiceId with the backend side, and call GetPaymentStatus to receive the updated status.

Moreover, It is highly recommended to implement the webhook as well to receive events for all transaction status changes directly from MyFatoorah side.


Initiate/Execute Payment

As described earlier for the Gateway Integration, we are going to have the SDK integrated with the same steps to make a successful integration with the SDK.

🚧

Initiate Payment

As a good practice, you don't have to call the Initiate Payment function every time you need to execute payment, but you have to call it at least once to save the PaymentMethodId that you will need to call Execute Payment

Initiate Payment

// initiatePayment 
        let invoiceValue = 5.0
        var selectedPaymentMethod = 1
        let initiatePayment = MFInitiatePaymentRequest(invoiceAmount: invoiceValue, currencyIso: .kuwait_KWD)
        MFPaymentRequest.shared.initiatePayment(request: initiatePayment, apiLanguage: .english) { [weak self] (response) in
            switch response {
            case .success(let initiatePaymentResponse):
                var paymentMethods = initiatePaymentResponse.paymentMethods
                if let paymentMethods = initiatePaymentResponse.paymentMethods, !paymentMethods.isEmpty {
                    selectedPaymentMethod = paymentMethods[0].paymentMethodId
                }
            case .failure(let failError):
                print(failError)
            }
        }
			double invoiceValue = 5.0;
        MFInitiatePaymentRequest* initiatePayment = [[MFInitiatePaymentRequest alloc] initWithInvoiceAmount:invoiceValue currencyIso:MFCurrencyISOKuwait_KWD];
        [[MFPaymentRequest shared] initiatePaymentWithRequest:initiatePayment apiLanguage:MFAPILanguageEnglish completion:^(MFInitiatePaymentResponse * initiatePaymentResponse, MFFailResponse * failResponse) {
            if (initiatePaymentResponse != NULL) {
                if ([initiatePaymentResponse.paymentMethods count] > 0) {
                    NSLog(@"%@",initiatePaymentResponse);
                }
            } else {
                    NSLog(@"%@",failResponse);
                    
                }
            }
        }];

Execute Payment

        let request = MFExecutePaymentRequest(invoiceValue: invoiceValue, paymentMethod: paymentMethod.paymentMethodId)
        
        // Uncomment this to add ptoducts for your invoice
        // var productList = [MFProduct]()
        // let product = MFProduct(name: "ABC", unitPrice: 1, quantity: 2)
        // productList.append(product)
        // request.invoiceItems = productList
        
        MFPaymentRequest.shared.executePayment(request: request, apiLanguage: .english) { [weak self] (response,invoiceId) in
            switch response {
            case .success(let executePaymentResponse):
                print("\(executePaymentResponse.invoiceStatus ?? "")")
            case .failure(let failError):
                print(failError)
            }
        }


 
        MFExecutePaymentRequest* request = [[MFExecutePaymentRequest alloc] initWithInvoiceValue:invoiceValue paymentMethod:_paymentMethodId];
        //         Uncomment this to add ptoducts for your invoice
        // NSMutableArray* productList = [[NSMutableArray alloc] init];
        // MFProduct* product = [[MFProduct alloc] initWithName:@"ABC" unitPrice:1 quantity:2];
        // [productList addObject:product];
        // request.invoiceItems = productList;
        [[MFPaymentRequest shared] executePaymentWithRequest:request apiLanguage:MFAPILanguageEnglish completion:^(MFPaymentStatusResponse * paymentStatusResponse, MFFailResponse * failResponse, NSString* invoiceId) {
            if (paymentStatusResponse != NULL) {
                NSLog(@"%@",paymentStatusResponse);
            } else {
                NSLog(@"%@",failResponse);
            }
        }];

MFPaymentDelegate

// ```MFPaymentDelegate```
// You can conform this protocol to listen for invoice status, now this protocol has `didInvoiceCreated`
// method to get the invoice id immediately after creating the invoice. 
class ViewController: UIViewController {
    override func viewDidLoad() {
        // Set delegate for your view controller
        MFSettings.shared.delegate = self
}


// conforms ```MFPaymentDelegate```
extension ViewController: MFPaymentDelegate {
    func didInvoiceCreated(invoiceId: String) {
        print("#\(invoiceId)")
    }
}   

// ```MFPaymentDelegate```
// You can conform this protocol to listen for invoice status, now this protocol has `didInvoiceCreated`
// method to get the invoice id immediately after creating the invoice. 

// ViewController.h
@interface ViewController : UIViewController<MFPaymentDelegate>
.
.
@end


// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [MFSettings shared].delegate = self;
}

// conforms `MFPaymentDelegate`
- (void)didInvoiceCreatedWithInvoiceId:(NSString * _Nonnull)invoiceId {
    NSLog(@"invoice id: %@", invoiceId);
}

In-App Apple Pay iOS

1-Create variable from MFApplePayButton, you can create it from code or storyboard as you like.

let applePayButton = MFApplePayButton()
view.addSubview(applePayButton)
applePayButton.translatesAutoresizingMaskIntoConstraints = false
applePayButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
applePayButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
applePayButton.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
applePayButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
applePayButton.heightAnchor.constraint(equalToConstant: 80).isActive = true

2- Initiate session and get sessionId to handle Apple Pay

let invoiceValue = Decimal(string: amountTextField.text ?? "0") ?? 0
let request = MFExecutePaymentRequest(invoiceValue: invoiceValue, displayCurrencyIso: .kuwait_KWD)
MFPaymentRequest.shared.initiateSession(apiLanguage: .english) { [weak self] response in
     switch response {
      case .success(let session):
        self?.applePayButton.load(session, request, .english, startLoading: {
            self?.activityIndicator.startAnimating()
    }, completion: { response, invoiceId in
            self?.activityIndicator.stopAnimating()
            switch response {
             case .success(let executePaymentResponse):
              if let invoiceStatus = executePaymentResponse.invoiceStatus {
                self?.showSuccess(invoiceStatus)
              }
             case .failure(let error):
                    self?.showFailError(error)
                    }
                })
      case .failure(let error):
                print("#initiate session", error.localizedDescription)
        }
}

3- (Optional) Configure Apple Pay Button

let applePayConfigure = MFInApplePayConfigureBuilder.default
        applePayConfigure.setHeight(50) // set height to Apple Pay Button
        applePayConfigure.setBorderRadius(20) // set border radius to Apple Pay Button
        applePayConfigure.setButtonText("Buy with") // set the text before Apple icon
        applePayConfigure.hideLoadingIndicator(true) // hide loading indicator, default is false

📘

For the button text which is before the Apple icon you should choose one from those texts ["", "Buy with", "Pay with", "Check Out with", "Continue with", "Book with", "Donate with", "Subscribe with", "Reload with", "Add Money with", "Top Up with", "Order with", "Rent with", "Support with", "Contribute with", "Tip with", "Set Up"],

In-Browser Apple Pay

To use Apple Pay payment, your account should have the Apple Pay payment method enabled.
For iOS 13.0 and above

let invoiceValue = 5.0
    let paymentMethod = 2 // if you don't Know this you have to call initiatePayment
    let request = MFExecutePaymentRequest(invoiceValue: invoiceValue, paymentMethod: 2)
    MFPaymentRequest.shared.executeApplePayPayment(request: request, apiLanguage: .arabic) { [weak self] response, invoiceId  in
        switch response {
        case .success(let executePaymentResponse):
            if let invoiceStatus = executePaymentResponse.invoiceStatus {
                self?.showSuccess(invoiceStatus)
            }
        case .failure(let failError):
            self?.showFailError(failError)
        }
    }
NSDecimalNumber * decimalNumber = [NSDecimalNumber decimalNumberWithString:self.amountTextField.text];
    NSDecimal invoiceValue = [decimalNumber decimalValue];
    
    MFExecutePaymentRequest* request = [[MFExecutePaymentRequest alloc] initWithInvoiceValue:invoiceValue paymentMethod:paymentMethodId];
    [[MFPaymentRequest shared] executeApplePayPaymentWithRequest:request apiLanguage:MFAPILanguageEnglish completion:^(MFPaymentStatusResponse * response, MFFailResponse * error, NSString * invoiceId) {
        [self stopLoading];
        if (response != NULL) {
            if (response.invoiceStatus != NULL) {
                [self showSuccess:response.invoiceStatus];
            } else {
                [self showFailError:error];
            }
        }  else {
                [self showFailError:error];
        }
    }];

If your app supports iOS versions below iOS 13.0, follow these steps:
1- Open your project on Xcode go to your app target, click Info tab, scroll bottom, add URL type, set identifier filed with your bundle id or anything else, and add URL Schemes saying urlScheme. Make sure it is a unique URL schema for your APP. Finally, Copy the URL for the next steps.
2- Call InitiatePayment endpoint and take Apple Pay 'PaymentMethodId'
3- Create your request and call the 'executeApplePayPayment' method, please note you have to pass the urlScheme argument with URL schemes from the first step.

let invoiceValue = 5.0
    let urlScheme = "urlschema" //urlSchema from step one 
    let paymentMethod = 2 // if you don't Know this you have to call initiatePayment
    let request = MFExecutePaymentRequest(invoiceValue: invoiceValue, paymentMethod: 2)
    MFPaymentRequest.shared.executeApplePayPayment(request: request, urlScheme: urlScheme, apiLanguage: .arabic) { [weak self] response, invoiceId  in
        switch response {
        case .success(let executePaymentResponse):
            if let invoiceStatus = executePaymentResponse.invoiceStatus {
                self?.showSuccess(invoiceStatus)
            }
        case .failure(let failError):
            self?.showFailError(failError)
        }
    }
NSDecimalNumber * decimalNumber = [NSDecimalNumber decimalNumberWithString:self.amountTextField.text];
    NSDecimal invoiceValue = [decimalNumber decimalValue];
    NSString * urlScheme = @"applepay";
    MFExecutePaymentRequest* request = [[MFExecutePaymentRequest alloc] initWithInvoiceValue:invoiceValue paymentMethod:paymentMethodId];
    [[MFPaymentRequest shared] executeApplePayPaymentWithRequest:request urlScheme:urlScheme apiLanguage:MFAPILanguageEnglish completion:^(MFPaymentStatusResponse * response, MFFailResponse * error, NSString * invoiceId) {
        [self stopLoading];
        if (response != NULL) {
            if (response.invoiceStatus != NULL) {
                [self showSuccess:response.invoiceStatus];
            } else {
                [self showFailError:error];
            }
        }  else {
                [self showFailError:error];
        }
    }];

4- Go to your AppDelegate and implement:

application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

Add the following code inside it:

@UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    .
    .
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if let paymentId = url[MFConstants.paymentId] {
            NotificationCenter.default.post(name: .applePayCheck, object: paymentId)
        }
        return true
    }
    .
    }
@implementation AppDelegate
    . 
    .
        
     - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
            if (url[MFConstants.paymentId] != NULL) {
                [[NSNotificationCenter defaultCenter] postNotificationName:MFConstants.applePayNotificationName object:url[MFConstants.paymentId]];
            }
            return true;
        }
    .
    
    @end

🚧

SceneDelegate

Please note if your app has SceneDelegate so you should implement func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) instead of func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

@available(iOS 13.0, *)
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
     if let url = URLContexts.first?.url {
        if let paymentId = url[MFConstants.paymentId] {
             NotificationCenter.default.post(name: .applePayCheck, object: paymentId)
         }
     }
}

👍

Apple Pay Test

Use the Apple document that explains how to test Apple pays on your device.


Embedded Payment for iOS

Usage
1- Create a variable from MFCardPaymentView, you can add it:
In storyboard

  • Drag view to view
  • Select the dragged view.
  • In the right navigation select 'Identity Inspector'.
  • Set Class MFPaymentCardView and Module MFSDK

Or by code

let cardPaymentView = MFCardPaymentView()
view.addSubview(cardPaymentView)
cardPaymentView.translatesAutoresizingMaskIntoConstraints = false
cardPaymentView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
cardPaymentView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
cardPaymentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
cardPaymentView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
cardPaymentView.heightAnchor.constraint(equalToConstant: 220).isActive = true
MFPaymentCardView * paymentCardView = [[MFPaymentCardView alloc] init];
[self.view addSubview:paymentCardView];
[[paymentCardView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor] setActive:YES];
[[paymentCardView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor] setActive:YES];
[[paymentCardView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor] setActive:YES];
[[paymentCardView.heightAnchor constraintEqualToConstant:220] setActive:YES];

2- You can configure the card with labels, placeholders, colors, height, and border-radius also by code or storyboard

// get default configure
    var configure = MFCardConfigureBuilder.default
    // but you can create yours
    // set placeholders
    configure.setPlaceholder(MFCardPlaceholder(cardHolderNamePlaceholder: "Name", cardNumberPlaceholder: "Number", expiryDatePlaceholder: "MM / YY", cvvPlaceholder: "CVV"))
    // set labels
    configure.setLabel(MFCardLabel(cardHolderNameLabel: "Card holder name", cardNumberLabel: "Card number", expiryDateLabel: "MM / YY", cvvLabel: "CVV", showLabels: true, fontWeight: .normal))
    // set theme
    let theme = MFCardTheme(inputColor: .black, labelColor: .black, errorColor: .red, borderColor: .black)
    theme.language = .english // select .arabic for rtl vie
    configure.setTheme(theme)
    // set height and margin of card inputs
    configure.setCardInput(MFCardInput(inputHeight: 32, inputMargin: 15))

    // set labels and texts font size
    configure.setFontSize(15)
    // set border width
    configure.setBorderWidth(1)
    // set border radius for input fields
    configure.setBorderRadius(8)
    // set the display of card icons
    configure.setHideCardIcon(false)
    // set Font Family
    configure.setFontFamily(.timesNewRoman)
  	// set box shadow
    configure.setBoxShadow(MFBoxShadow(hOffset: 0, vOffset: 0, blur: 0, spread: 0, color: .gray))


    // create the new configure and assigned to payment card view
    paymentCardView.configure = configure.build()
// get default configure
    MFCardConfigureBuilder * configure = [MFCardConfigureBuilder default];
    // but you can create yours
    // set placeholders
    MFCardPlaceholder * placeholder = [[MFCardPlaceholder alloc] initWithCardHolderNamePlaceholder:@"Name on card" cardNumberPlaceholder:@"Card number" expiryDatePlaceholder:@"MM / YY" cvvPlaceholder:@"CVV"];
    [configure setPlaceholder:placeholder];

    // set labels
    MFCardLabel * label = [[MFCardLabel alloc] initWithCardHolderNameLabel:@"Card holder name" cardNumberLabel:@"Card Number" expiryDateLabel:@"Expiry Date" cvvLabel:@"CVV" showLabels:YES];
    [configure setLabel:label];

    // set theme
    MFCardTheme * theme = [[MFCardTheme alloc] initWithInputColor:UIColor.blackColor labelColor:UIColor.blackColor errorColor:UIColor.redColor];
    [configure setTheme:theme];


    // set labels and texts font size
    [configure setFontSize:14];

    // set border width
    [configure setBorderWidth:1];

    // set border radius
    [configure setBorderRadius:8];

    // create the new configure and assigned to payment card view
    paymentCardView.configure = [configure build];

3- Initiate session and get session id to setup MFCardPaymentView

MFPaymentRequest.shared.initiateSession(apiLanguage: .english) { response in
		switch response {
    case .success(let session):
      	self.paymentCardView.load(initiateSession: session)
    case .failure(let error):
    		self.showFailError(error)
    }
}
[[MFPaymentRequest shared] initiateSessionWithApiLanguage:MFAPILanguageEnglish completion:^(MFInitiateSessionResponse * response, MFFailResponse * error) {
            if (error == NULL) {
                [paymentCardView loadWithInitiateSession:response];
            } else {
                NSLog(error);
            }
    }];

(Alternative Option) You can call the function including onCardBinChanged closure to receive the card bin

MFPaymentRequest.shared.initiateSession(apiLanguage: .english) { [weak self] response in
		switch response {
    case .success(let session):
      	self?.paymentCardView.load(initiateSession: session) { bin in
        		print("bin", bin)
        }
    case .failure(let error):
    		self?.showFailError(error)
    }
}

4- Now your MFPaymentCardView is set up, so once the customer entered the card details you need to call pay

// create request, make sure you don't set paymentMethodId, because it override sessionId and this is wrong.
let request = MFExecutePaymentRequest(invoiceValue: 5)

// call pay method to make your order
cardPaymentView.pay(request, .english) { response, invoiceId in
    switch response {
    case .success(let paymentStatus):
        print(paymentStatus)
    case .failure(let error):
        print(error)
    }
}
// create request, make sure you don't set paymentMethodId, because it override sessionId and this is wrong.
    NSDecimalNumber * decimalNumber = [NSDecimalNumber decimalNumberWithString:self.amountTextField.text];
    NSDecimal invoiceValue = [decimalNumber decimalValue];
    MFExecutePaymentRequest * request = [[MFExecutePaymentRequest alloc] initWithInvoiceValue:invoiceValue];
    [_paymentCardView pay:request :MFAPILanguageEnglish completion:^(MFPaymentStatusResponse * response, MFFailResponse * error, NSString * invoiceId) {
        if (response != NULL) {
            if (response.invoiceStatus != NULL) {
                [self showSuccess:response.invoiceStatus];
            } else {
                [self showFailError:error];
            }
        }else {
            [self showFailError:error];
        }
    }];

(Alternative Option) You can validate the session first and complete the payment if the session is valid

// create request, make sure you don't set paymentMethodId, because it override sessionId and this is wrong.
let request = MFExecutePaymentRequest(invoiceValue: 5)

// call calidate method
paymentCardView.validate{ [weak self] result in
    switch result {
    case .success(let cardBrand):
        
        // call pay method to make your order
        cardPaymentView.pay(request, .english) { response, invoiceId in
            switch response {
            case .success(let paymentStatus):
                print(paymentStatus)
            case .failure(let error):
                print(error)
            }
        }
    case .failure(let failError):
    }
}

Payment Inquiry

We have explained the main usage for the Payment Inquiry function, which will enable your application to get the full details about a certain invoice/payment. You can use this function within your application on different platforms as well. Here we are explaining some samples of its usage through the SDK.

let paymentStatusRequest = MFPaymentStatusRequest(Key: "id", KeyType: .invoiceId)
MFPaymentRequest.shared.getPaymentStatus(paymentStatus: paymentStatusRequest, apiLanguage: .english) { [weak self] (response) in
    self?.stopRequestLoading()
        switch response {
            case .success(let paymentStatusResponse):
                print("\(paymentStatusResponse.invoiceStatus)")
            case .failure(let failError):
                print("\(failError)")
        }
}
MFPaymentStatusRequest* request = [[MFPaymentStatusRequest alloc]initWithKey:@"1234" KeyType:MFKeyTypeInvoiceId];
    
    [[MFPaymentRequest shared] getPaymentStatusWithPaymentStatus:request apiLanguage:MFAPILanguageEnglish completion:^(MFPaymentStatusResponse * paymentStatusResponse, MFFailResponse * failResponse) {
        if(paymentStatusResponse != NULL) {
            NSLog(@"%@",paymentStatusResponse.invoiceStatus);
        } else {
            NSLog(@"%@",failResponse);
        }
    }];

Send Payment

We have explained in the Send Payment section earlier, the different usage cases for it and how it works, here we are going to embed some sample code for calling it through the SDK on the different platforms.

let invoiceValue = 5.0
        var notificationOption : MFNotificationOption =  .all
        /*
         notificationOption = .sms
         notificationOption = .email
         notificationOption = .link
         */
        
        let invoice = MFSendPaymentRequest(invoiceValue: invoiceValue, notificationOption: notificationOption, customerName: "customerName")
        
        invoice.customerEmail = "[email protected]"// must be email Required if you choose notificationOption .all or  .email
        invoice.customerMobile = "mobile no"//Required if you choose notificationOption .all or .sms
        invoice.mobileCountryIsoCode = MFMobileCountryCodeISO.kuwait.rawValue
        
        MFPaymentRequest.shared.sendPayment(request: invoice, apiLanguage: .english) { [weak self] (result) in
            switch result {
            case .success(let sendPaymentResponse):
                if let invoiceURL = sendPaymentResponse.invoiceURL {
                    print("result: RedirectUrl is \(invoiceURL)")
                }
            case .failure(let failError):
                print("Error: \(failError)")
            }
        }
double invoiceValue = 5.0;
    MFSendPaymentRequest* request = [[MFSendPaymentRequest alloc] initWithInvoiceValue:invoiceValue notificationOption:MFNotificationOptionAll customerName:@"Test"];
    request.mobileCountryIsoCode = [MFEnumRawValue rawValueWithEnumValue:MFMobileCountryCodeISOKuwait];
    [[MFPaymentRequest shared] sendPaymentWithRequest:request apiLanguage:MFAPILanguageEnglish completion:^(MFSendPaymentResponse * sendPaymentResponse, MFFailResponse * failResponse) {
        
        if(sendPaymentResponse != NULL) {
            NSLog(@"%@",sendPaymentResponse.invoiceURL);
            
        } else {
            NSLog(@"%@",failResponse.errorDescription);
        }
        
    }];

Direct Payment/Tokenization

As we have explained earlier in the [Direct Payment] integration and how it works, it also has the same scenario for the SDK implementation, you have to know the following steps to understand how it works:

  • Get the payment method that allows Direct Payment by calling initiatePayment to get paymentMethodId
  • Collect card info from user MFCardInfo(cardNumber: "51234500000000081", cardExpiryMonth: "05", cardExpiryYear: "21", cardSecurityCode: "100", saveToken: false)
  • If you want to save your credit card info and get a token for your next payment you have to set saveToken: true and you will get the token in the response read more in Tokenization
  • If you want to execute payment through a saved token you have to use MFCardInfo(cardToken: "put your token here")
  • Now you are ready to execute the payment, please check the following sample code
let card = MFCardInfo(cardNumber: "51234500000000081", cardExpiryMonth: "05", cardExpiryYear: "21", HolderName: "John", cardSecurityCode: "100", saveToken: true) //MFCardInfo(cardToken: "token")
         // card.bypass = false // default is true
        let invoiceValue = 5.0
        
        let paymentMethod = 2 // if you don't Know this you have to call initiatePayment
        let request = MFExecutePaymentRequest(invoiceValue: invoiceValue, paymentMethod: 2)
        MFPaymentRequest.shared.executeDirectPayment(request: request, cardInfo: card, apiLanguage: .english) { [weak self] response, invoiceId in
            switch response {
            case .success(let directPaymentResponse):
                if let cardInfoResponse = directPaymentResponse.cardInfoResponse, let card = cardInfoResponse.cardInfo {
                    print("Status: with card number \(card.number)")
                }
                if let invoiceId = invoiceId {
                    print("Success with invoiceId \(invoiceId)")
                }
            case .failure(let failError):
                print("Error: \(failError.errorDescription)")
                if let invoiceId = invoiceId {
                    print("Fail: \(failError.statusCode) with invoiceId \(invoiceId)")
                }
            }
        }
MFExecutePaymentRequest* request = [self getExecutePaymentRequest:paymentMethodId];

    MFCardInfo* card = [self getCardInfo];

    [self startLoading];

    [[MFPaymentRequest shared] executeDirectPaymentWithRequest:request cardInfo:card apiLanguage:MFAPILanguageEnglish completion:^(MFDirectPaymentResponse * response, MFFailResponse * error, NSString * invoiceId) {


        if (response !=NULL) {

            if (response.cardInfoResponse != NULL) {

                NSLog(@"%@",[NSString stringWithFormat:@"Status: with card number: %@", response.cardInfoResponse.cardInfo.number]);

            }

            if (invoiceId != NULL) {
                NSLog(@"%@", [NSString stringWithFormat:@"Success with invoice id %@", invoiceId ]);

            }

        }

    }];