Overview
The iOS Direct Native SDK integration is an SDK for native mobile apps to perform 3DS-Only validation using the Nuvei authenticate3d() method.
This topic steps you through the process of integrating Nuvei payment solutions into your native mobile apps on the iOS platform.
UI Implementation
To be able to customize the UI of 3DS 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" }
Create a Payment
Submit a NuveiSimplyConnect.createPayment() request.
NuveiSimplyConnect.createPayment(
/* NVUIOwner */ uiOwner: navigationController, // Pass an instance of root UIViewController or UIApplication (for Swift-UI projects)
/* NVInput */ input: input, // NVInput object with all the required transaction details
/* Bool */ forceWebChallenge: forceWebChallenge // Optional flag indicating whether 3DS challenge screen should be forced as Web challenge
) { (output) in
debugPrint("\(#function): output = \(output)")
}
Tokenization
Submit a NuveiSimplyConnect.tokenize() request.
NuveiSimplyConnect.tokenize(input: input) { token, error in
debugPrint("[Authorize3dViewController] \(#function): token = \(token), error = \(error?.localizedDescription)")
}
3DS 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(uiOwner: navigationController, input: input) { (output) in
debugPrint("Output = \(output)")
}
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 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 class containing the 3DS 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 3DS authentication failed; however, subject to risk considerations, you may still want to proceed with a non-3DS transaction payment, without liability shift, by simply submitting a payment, without the threeD class, as shown below in Example /payment API Request without Liability Shift. |
Perform the Server-Side Payment
Please press here to continue.