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
- Download the following three frameworks from this GitHub location – NuveiMobileSDK-iOS-Release:
- NuveiMobileSDK.xcframework
- JOSESwift.xcframework
- CryptoSwift.xcframework
- Locate these frameworks inside your Xcode project folder.
- Then drag the frameworks to Xcode, in target settings:
“General” tab > “Frameworks, Libraries and Embedded Content” section. - 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.
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:
Result | Notes | Next action |
---|---|---|
APPROVED | This result can be due to either of these cases:
| 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.
| The transaction should not proceed to payment. |
ERROR | The authentication failed.
| 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:
|
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.
|
The transaction should not proceed to payment. |
ERROR | The authentication failed.
|
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 |