• Documentation
  • API Reference
  • Documentation
  • API Reference
Expand All Collapse All
  • Payment Overview
    • Introduction
    • Choosing an Integration Method
  • Accept Payment
    • Payment Page
      • Quick Start
      • Input Parameters
      • Output Parameters
    • Web SDK
      • Quick Start
      • Nuvei Fields
        • Styling
      • Additional Functions
      • APM Payments
      • Tokenization-Only Flow
      • Scenarios
      • Using ReactJS
        • Full Samples
        • Sandbox Examples
      • FAQs
    • Checkout
      • Quick Start
        • UI Customization
        • Payment Customization
        • Advanced Controls
        • Checkout Examples
      • Server-to-Server
      • Payment Scenarios
      • Mobile SDKs (Beta Release)
        • Android Mobile SDK (Beta Release)
        • iOS Mobile SDK (Beta Release)
      • Flow Diagrams
      • Plugins
        • Magento
          • Rebilling with Magento
        • WooCommerce
          • Rebilling with WooCommerce
        • PrestaShop
          • PrestaShop with Web SDK
          • PrestaShop with Checkout
        • OpenCart
        • Shopify (via AsiaBill)
        • Mirakl
        • Salesforce
        • SAP
        • WIX
      • Marketplaces
    • Features
      • Authentication
      • Financial Operations
        • Refund
        • Void
        • Auth and Settle
        • Partial Approval
        • Currency Conversion (DCC and MCP)
        • Payout
      • Card Operations
        • Card-on-File
        • PCI and Tokenization
        • Zero-Authorization
        • Merchant-Initiated Transactions (MIT)
        • Blocking Cards
      • Subscription (Rebilling)
      • 3D-Secure
        • 3D-Secure Explained
        • 3DS Implementations
          • 3DS MPI-Only Web SDK
          • 3DS MPI-Only REST
          • 3DS External MPI
          • 3DS Responses
        • 3DS Functions
          • 3D-Secure Fingerprinting
          • 3D-Secure Authentication Challenge
      • Webhooks (DMNs)
        • Payment Transaction Requests
        • Control Panel Events API
    • Guides
      • Testing Cards, APIs and APMs
        • Testing Cards
        • Testing APIs with Postman
        • Testing APMs
      • Response Handling
      • Alternative Payment Guides (APMs)
      • Airline Ticket Guides
        • Airline Addendum
        • External Authorization Addendum
      • Payment Facilitators (PayFac)
      • Cashier
        • Cashier Events Guide
        • Cashier Features
      • Withdrawal Guide
      • Risk Guide
        • Nuvei Services
        • Transaction Types
        • Credits and Payouts
        • Fraud to Sale Programs
        • Compliance Programs
        • Chargebacks
      • eKYC Guide
      • Server SDKs
        • Java SDK
        • .NET SDK
        • PHP SDK
        • Node.JS SDK
      • Fast Track Onboarding Developer Guide
      • Currency Conversion Guides
        • Multiple Currency Pricing (MCP)
        • Dynamic Currency Conversion (DCC)
          • DCC in Cashier or Payment Page
          • DCC in REST API Workflows
          • DCC in Web SDK Workflows
      • Website Compliance Guides
    • Additional Links
      • FAQs
      • API Reference
      • Release Notes
      • Country and Currency Codes

    iOS Mobile SDK (Beta Release)

    On this page:
    • Overview
    • Install the iOS Mobile SDK
      • Install the SDK
      • Customize the UI
    • Submit a Payment Request
      • Initiate a Session
      • 3D-Secure Authentication
      • Perform the Server-Side Payment

    Overview

    The iOS Mobile SDK integration is an SDK for native mobile apps to perform 3D-Secure-Only validation (for 3D-Secure v1 or v2) using the Nuvei authenticate3d() method.

    This topic is a step-by-step guide to integrate Nuvei payment solutions into native mobile apps on the iOS platform.

    Install the iOS Mobile SDK

    Install the SDK

    1. Download the following three frameworks from this GitHub location – NuveiMobileSDK-iOS-Release:
      • NuveiMobileSDK.xcframework
      • JOSESwift.xcframework
      • CryptoSwift.xcframework
    2. Locate these frameworks inside your Xcode project folder.
    3. Then drag the frameworks to Xcode, in target settings:
      “General” tab > “Frameworks, Libraries and Embedded Content” section.
    4. Mark all three frameworks as “Embed & Sign“.

    Customize the UI

    To be able to customize the UI of 3D challenge screens, you can provide a set of customization definition objects. This customization definition is optional and can be skipped; the default customization is used in this case.

     let customization = NuveiUICustomization(
        toolbarCustomization: NuveiToolbarCustomization(
            headerText: "SECURE CHECKOUT",
            textFont: UIFont.boldSystemFont(ofSize: 22),
            textColor: .white,
            backgroundColor: .nuveiDefaultColor
        ),
        labelCustomization: NuveiLabelCustomization(
            textFont: UIFont.systemFont(ofSize: 14),
            textColor: .black,
            headingTextFont: UIFont.systemFont(ofSize: 14),
            headingTextColor: .white
        ),
        textBoxCustomization: NuveiTextBoxCustomization(
            textFont: UIFont.systemFont(ofSize: 14),
            textColor: .black,
            borderColor: .black,
            cornerRadius: 0,
            borderWidth: 1
        )
    )
    let nextButtonCustomization = NuveiButtonCustomization(
        textFont: UIFont.boldSystemFont(ofSize: 17),
        textColor: .white,
        backgroundColor: .nuveiDefaultColor,
        cornerRadius: 5
    )
    let cancelButtonCustomization = NuveiButtonCustomization(
        textFont: UIFont.boldSystemFont(ofSize: 17),
        textColor: .nuveiDefaultColor,
        backgroundColor: .white,
        cornerRadius: 5
    )
    customization.setButtonCustomization(nextButtonCustomization, for: .next)
    customization.setButtonCustomization(nextButtonCustomization, for: .continue)
    customization.setButtonCustomization(nextButtonCustomization, for: .resend)
    customization.setButtonCustomization(nextButtonCustomization, for: .submit)
    customization.setButtonCustomization(cancelButtonCustomization, for: .cancel)
    
    NuveiMobileSDK.customization = customization

    Submit a Payment Request

    Initiate a Session

    Send the /openOrder API call, which does the following:

    • Authenticates you as our merchant, using your given credentials.
    • Sets up an order on our system that contains your transaction details, which are referenced later in the payment flow.

      Before using the Server SDK, make sure to initialize the SDK before any request, by including the relevant SDK initialization.

    • This call must be performed on your backend server, never on the front-end. The /openOrder call described here requires your password, which should NOT be exposed on the client-side.

      It is also important to set the order from the server-side to prevent front-end user manipulation.

      You can simulate the Open Order functionality using a Postman script, follow our guide on using this here. Then use this Postman script to run and test the /openOrder method.

      For the /openOrder authentication, you must create the checksum field. This is a SHA-256 encryption, of the concatenation of the following fields, in this order:
      merchantId, merchantSiteId, clientRequestId, amount, currency, timeStamp and your secret key in the end.
    Example /openOrder Request
    • {  
         "merchantId":"<your merchantId goes here>",
         "merchantSiteId":"<your merchantSiteId goes here>",
         "clientUniqueId":"<unique transaction ID in merchant system>",
         "clientRequestId":"<unique request ID in merchant system>",
         "currency":"USD",
         "amount":"200",
         "timeStamp":"<YYYYMMDDHHmmss>",
         "checksum":"<calculated checksum>"
      }
      <?php
      $safecharge = new \SafeCharge\Api\RestClient([
      'environment' => \SafeCharge\Api\Environment::INT,
      'merchantId' => '<your merchantId>',
      'merchantSiteId' => '<your merchantSiteId>',
      'merchantSecretKey' => '<your merchantSecretKey>',
      ]);
      
      $openOrderRequest = $SafeCharge->getPaymentService()->openOrder([
          'clientUniqueId'    => '<unique transaction ID in merchant system>',
          'clientRequestId'    => '<unique request ID in merchant system>',
          'currency'          => 'USD',
          'amount'            => '200'
      ]);
      ?>
      public static void main(String[] args) {
      // for initialization 
      String merchantId = "<your merchantId>";
      String merchantSiteId = "<your merchantSiteId>";
      String merchantKey = "<your merchantKey>";
      safecharge.initialize(merchantId, merchantSiteId, merchantKey, 
      APIConstants.Environment.INTEGRATION_HOST.getUrl(), Constants.HashAlgorithm.SHA256);
      
      //for openOrder
      String clientUniqueId = "<unique transaction ID in merchant system>";
      String clientRequestId = "<unique request ID in merchant system>";
      String currency = "USD";
      String amount = "200";
      SafechargeResponse response = safecharge.openOrder(userTokenId, clientRequestId,
      clientUniqueId, null, null, null, null, currency, amount, null, null, null, null, 
      null, null, null, null, null, null, null, null, null, null, null, null, 
      null, null, null, null, null, null);
      }
      var safecharge = new Safecharge(
      "<your merchantKey>",
      "<your merchantId>",
      "<your merchantSiteId>",
      "<your server host value",
      HashAlgorithmType.SHA256
      );
      var response = safecharge.OpenOrder(
       "USD",
       "200",
       clientUniqueId: "<unique transaction ID in merchant system>",
       clientRequestId: "<unique request ID in merchant system>"
      );
      const safecharge = require('safecharge');
      safecharge.initiate(<merchantId>, <merchantSiteId>, <merchantSecretKey>, <env>);
      safecharge.paymentService.openOrder({
          'clientUniqueId'   : '<unique transaction ID in merchant system>',
          'clientRequestId'   : '<unique request ID in merchant system>',
          'currency'         : 'USD',
          'amount'           : '200'
      }, function (err, result) {
          console.log(err, result)
      });
    Example /openOrder Response
    • {
          "sessionToken": "64fe6953-69d1-440f-8e21-878c85701f09",
          "orderId": "39272",
          "merchantId": "427583496191624621",
          "merchantSiteId": "142033",
          "clientUniqueId": "12345",
          "clientRequestId": "1484759782197",
          "internalRequestId": "866",
          "status": "SUCCESS",
          "errCode": "0",
          "reason": "",
          "version": "1.0"
      }

    3D-Secure Authentication

    Once you have all the required transaction details, use the data to create an instance of the Authenticate3dInput class, and call the NuveiMobileSDK.authenticate3d(...) method as follows:

    Example Input
    // Using card details
    let paymentOption = try! PaymentOption(
        card: CardDetails(
            cardNumber: cardNumberField.text,
            cardHolderName: cardHolderNameField.text,
            cvv: cvvField.text,
            expirationMonth: monthField.text,
            expirationYear: yearField.text
        )
    )
    // Using card User Payment Option ID
    let paymentOption = try! PaymentOption(
        userPaymentOptionId: userPaymentOptionId
    )
    // Using card User Payment Option ID with updated expiration date
    let paymentOption = try! PaymentOption(
        userPaymentOptionId: userPaymentOptionId,
        card: CardDetails(
            expirationMonth: monthField.text,
            expirationYear: yearField.text
        )
    )
    let input = Authenticate3dInput(
        sessionToken: sessionToken,// required
        merchantId: merchantId,// required
        merchantSiteId: merchantSiteId,// required
        currency: currencyField.text!,// required
        amount: amountField.text!,// required
        paymentOption: paymentOption,// required
        clientUniqueId: clientUniqueId,// optional
        clientRequestId: clientRequestId,// optional
        customData: customData,// optional
        billingAddress: billingAddress,// optional
        shippingAddress: shippingAddress,// optional
        userDetails: userDetails,// optional
        merchantDetails: merchantDetails,// optional
        timeout: 10,// in minutes, optional
        requestTimeout: 30// in seconds, optional
    )
    
    // The viewController is used to present the challenge view controller(s) from 
    NuveiMobile.authenticate3d(viewController: navigationController, input: input) { (output) in
        debugPrint("Output = \(output)")
    }

    In the completion block, use the output. The following is the output class:

    Example Output
    public class Authenticate3dOutput {
        public enum Result: String {
            case approved, declined, redirect, error, other
        }    
        public let cavv: String?
        public let eci: String?
        public let xid: String?
        public let dsTransID: String?
        public let rawResult: [String: Any]?
        public let result: Result
        public let errorCode: Int?
        public let errorDescription: String?
    }
    Handling the authenticate3d() Response

    The response from the authenticate3d() call includes the result parameter which can have one of these values:

    ResultNotesNext action
    APPROVEDThis result can be due to either of these cases:
    • A cavv value is returned, and the eci value is either 5 (Visa) or 2 (Mastercard), and the issuer accepts liability (liability-shift).
    • For 3D-Secure v2 – If you requested a 3D-Secure Exemption, the issuer has approved a non-3D payment (the issuer does not accept liability (no liability-shift).
    Perform a server-side liability shift payment by sending a /payment API call, and include an externalMpi block containing the 3D-Secure authentication values received from the authenticate3d() call, as shown below.
    DECLINEDThe authentication failed.
    • eci is a negative value, and no cavv is returned.
    • An errCode and errorDescription are returned.
    The transaction should not proceed to payment.
    ERRORThe authentication failed.
    • eci is a negative value, and no cavv is returned.
    • An errCode and errorDescription are returned.
    The 3D-Secure authentication failed; however, subject to risk considerations, you may still want to proceed with a Non-3D-Secure transaction payment, without liability shift, by simply submitting a payment, without the threeD block, as shown below in Example /payment API Request without Liability Shift.

    Perform the Server-Side Payment

    Please press here to continue.

     
    Result Notes Next action
    APPROVED This result can be due to either of these cases:
    • A cavv value is returned, and the eci value is either 5 (Visa) or 2 (Mastercard), and the issuer accepts liability (liability-shift).
    • For 3D-Secure v2 – If you requested a 3D-Secure Exemption, the issuer has approved a non-3D payment (the issuer does not accept liability (no liability-shift).
    Perform a server-side liability shift payment by sending a /payment API call, and include an externalMpi block containing the 3D-Secure authentication values received from the authenticate3d() call, as shown below.
    DECLINED The authentication failed.
    • eci is a negative value, and no cavv is returned.
    • An errCode and errorDescription are returned.
    The transaction should not proceed to payment.
    ERROR The authentication failed.
    • eci is a negative value, and no cavv is returned.
    • An errCode and errorDescription are returned.
    The 3D-Secure authentication failed, however, subject to risk considerations, you may still want to proceed with a Non-3D-Secure transaction payment, without liability shift, by simply submitting a payment, without the threeD block, as shown below in Example /payment API Request without Liability Shift.

     

     

     
    Parameter Description Mandatory
    eci The Electronic Commerce Indicator as received from the MPI. (An Electronic Commerce Indicator (ECI) value is the result of a 3DS authentication request, returned by a Directory Server (“issuer ACS”) (namely Visa, MasterCard, JCB, and American Express).) Required
    cavv The card authentication verification value as received from the MPI. Required
    xid The transaction ID received from the MPI.
    (Optional for 3D-Secure v1.)(Do not send it at all for 3D-Secure v2.)
    Conditional
    dsTransID The transaction ID received from the MPI.
    (Mandatory for 3D-Secure v2.)(Do not send it for 3D-Secure v1.)
    Conditional
    challengePreference (The use of this parameter is only for “advanced” situations to force 3DS exemptions or challenges.)
    This indicates if an exemption has already been requested in the authentication. (This information can be used to synchronize the exemption flag according to EMVCO and schemes guidelines.)
    Possible values:ExemptionRequest or NoPreference
    Optional
    exemptionRequestReason (The use of this parameter is only for “advanced” situations to force 3DS exemptions.)
    If the merchant submitted an exemption requested using a challengePreference field, then this parameter displays the reason for the request. Possible values: AddCard, AccountVerification, LowValuePayment, or TransactionRiskAnalysis.
    Conditional
    2022 Nuvei. All rights reserved.