Flutter SDK
Use our Flutter SDK to integrate Android and iOS online payments through a single library while ensuring secure processing of customer payment data.
Our native SDK helps you communicate with the Client API. It offers:
- Convenient wrappers for API responses.
- Handling of all the details concerning the encryption of payment details.
- User-friendly formatting of payment data, such as card numbers and expiry dates.
- Input validation.
- Checks to determine to which issuer a card number is associated.
We encourage you to always target the most up-to-date API base URL when sending requests to our platform. Have a look at our dedicated guide for a full overview.
Our example app simulates the user interface for the whole payment flow based on the interaction between the app and our platform. Find the source code of the SDK and the example app on GitHub, including installation instructions.
To understand how to use this SDK, look at the following documentation:
- Mobile/Client Integration – Familiarise yourself with various concepts.
- Client API Reference – The SDK wraps the Client API and (among other things) exposes the responses of the web service calls as objects. Understanding the Client API will help you understand these SDK objects as well.
- The SDK on GitHub – The SDK contains a working example application, which can help you understand how to best use it.
- This current document will help you understand the global flow when creating payment pages using the SDK.
Why use the Flutter SDK
Our Flutter SDK helps you integrate online payments into Android and iOS applications through a single library. It handles many technical details for you, so you do not have to work directly with the Client API for common tasks. The main advantages of using the SDK are:
- Less code to write and maintain – The SDK includes ready-made functionality, which reduces development time and ongoing maintenance.
- Simple and secure authentication – The SDK takes care of authentication and security-related logic, making setup faster and safer.
- More stable integration over time – Most platform changes are handled within the SDK, minimising the impact on your application code.
- Faster setup and easier support – Using the SDK creates more standardised integrations, making onboarding quicker and support more efficient.
SDK integration
To create payments, you first need to integrate the SDK with your project. You can find all the versions of the SDK in our repository. We have prepared the requirements and installation instructions for the SDK below.
Requirements
| Requirement | Minimum Version |
|---|---|
| Flutter SDK | 3.32.0 or higher |
| Dart SDK | 3.8.0 or higher (and <4.0.0) |
| iOS Deployment Target | iOS 15.6+ |
| Android minSdkVersion | API 23 (Android 6.0) |
Installation
Add a dependency to the SDK in your app's pubspec.yaml file, where x.y.z is the version number:
dependencies:
// other dependencies
online_payments_sdk: ^x.y.z
Then, run the following command: flutter pub get.
Android
When installing the SDK on Android, enable multidex support in your build.gradle file if minSdkVersion is set to 20 or lower.
defaultConfig {
...
multiDexEnabled true
...
}
dependencies {
...
implementation 'androidx.multidex:multidex:2.0.1'
...
}
Example apps
We have bundled an example app within the SDK inside the example folder. This example shows how to initialise a OnlinePaymentSdk and how to make a Payment Product call.
You can also find a more extensive example showing the complete flow of how to create a payment here.
After you successfully integrate the SDK with your project, you can proceed to integrate it with the entire payment system. The complete payment process consists of these steps:
- Initialisation of the SDK
- Fetching possible payment methods
- Fetching and displaying payment method details
- Validation of the provided data
- Encryption and transfer of payment data
- Finalising transaction
1. Initialise SDK
Firstly, you need to create a OnlinePaymentSdk enabling communication between the Server API and the client. Your app must have its own server, acting as an intermediary between our Client and Server API.
Since the customer initiates the payment in your app, your Client application asks your Server application to create a session. When a Server application receives a request, it can create a session via CreateSession from the Server SDK.
Try our API Explorer to send a CreateSession request.
After configuring and connecting your application to the Server API, you receive a response containing information about the created OnlinePaymentSdk. A typical response looks like this:
import 'package:online_payments_sdk/online_payments_sdk.dart';
final sdk = OnlinePaymentSdk(
SessionData(
clientSessionId: '47e9dc332ca24273818be2a46072e006',
customerId: '9991-0d93d6a0e18443bd871c89ec6d38a873',
clientApiUrl: 'https://clientapi.com',
assetUrl: 'https://assets.com',
),
configuration: SdkConfiguration(
appIdentifier: 'Flutter Example Application/v1.0.0',
),
);
Now pass clientSessionId, customerId, clientApiUrl and assetUrl to the Client application. Once the application receives a response from the Server application with the session information, create a local OnlinePaymentSdk object on the Client application side.
Each Session has a fixed 3-hour lifespan. If it expires, you need to create a new Session.
After creating an instance of OnlinePaymentSdk, you will also need to configure your PaymentContext object, as shown below. It contains information like currency, country, amount, etc.
AmountOfMoney amountOfMoney = AmountOfMoney(
1298, // in cents
"EUR" // three-letter currency code as defined in ISO 4217
);
PaymentContext paymentContext = PaymentContext(
amountOfMoney,
"NL", // two-letter country code as defined in ISO 3166-1 alpha-2
false // true, if it is a recurring payment
);
Different payment methods are available for different PaymentContext objects. If you change any variable, you must start the process again. Only the OnlinePaymentSdk can remain the same if the same customer made the payment.
2. Fetch possible payment methods
The next step is to get and display the possible payment options. Fetch and display the BasicPaymentProduct and AccountOnFile lists to let your customer select one.
Use our convenient example application as a basis for your own implementation.
try {
final basicPaymentProducts = await sdk.getBasicPaymentProducts(paymentContext);
// Display the contents of basicPaymentProducts.basicPaymentProducts & basicPaymentProducts.accountsOnFile to your customer
} on SdkError catch (e) {
// Inform the customer that something went wrong while retrieving the available Payment Products
}
3. Fetch and display payment method details
For certain payment products, customers can opt for our platform to store their credentials for recurring payments. We refer to the stored data as an account on file (Card On File) or a token. You can reuse this account on file/token for subsequent payments if your customers chose the same payment method.
The list of available payment products that the SDK receives from the Client API also contains the accounts on file for each payment product. Your application can present this list to the user.
Depending on the method the customer chooses, consider cases of different data flows:
If the customer chooses a native form of payment, you need to use the SDK of the payment provider. You will need to handle the response only in the last step to inform the customer of their payment status. Read more about native payments in this dedicated chapter.
For payments with a third-party payment provider, you receive data with the redirection address in the payment properties. Redirect your customers in their browser to the third-party payment portal to continue the payment process. After the successful payment, your app needs to handle the redirection to the Client app.
The standard payment process is a card payment. Once the customer selects the desired payment product, retrieve the enriched PaymentProduct detailing what information the customer needs to provide to authorise the payment. Then, display the required information fields to your customer.
try {
final paymentProduct = await sdk.getPaymentProduct(
1, // id of the payment product you want to retrieve
paymentContext,
);
// Display the fields to your customer
} on SdkError catch (e) {
// Inform the customer that something went wrong while retrieving the Payment Product
}
If your customer selects an account on file, the system will automatically fill in the saved information in the respective input fields. The prefilled data on behalf of the customer is in line with applicable regulations. Depending on the individual use case, your customer may still have to provide some card data (i.e. CVC).
Use our example app for inspiration to create your screen.
4. Validate provided data
After your customer enters their payment information, your application needs to validate the received data. But before validation, you will first need to save the customer's input for the required information fields in a PaymentRequest instance. This class has a tokenize property used to indicate whether the app should store the customer's credentials for recurring payments.
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct, // Product for which the request will be made
tokenize: false // Flag for tokenising the request
);
Alternatively, adapt the code sample by supplying both the account on file and the corresponding payment product:
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct,
tokenize: true, // Optional argument to tokenise the request - default is false
accountOnFile: accountOnFile // Optional argument to set the accountOnFile to be used for the paymentRequest
);
Once you configure a payment request, supply the values for the payment product fields. Use the identifiers of the fields, such as "cardNumber", "cvv", and "expiryDate", to set the field values for the payment request:
paymentRequest.setValue(
"cardNumber", // field id
"1245 1254 4575 45" // value
);
paymentRequest.setValue("cvv", "123");
paymentRequest.setValue("expiryDate", "12/25");
Now you need to validate the received data using the available list of validators. Do that by performing validation on the PaymentRequest and validating both the field values and the payment request.
// Validate all fields in a Payment Request
List errorMessages = await paymentRequest.validate();
// check if the payment request is valid
if (errorMessages.isEmpty) {
// payment request is valid
} else {
// payment request has errors
}
Remember that the data entry interface must be fully transparent and understandable for your customers. So, if there are validation errors, you should provide the customer with feedback about them. The errors are returned as a list of ValidationErrorMessage, which you can use to display appropriate error messages.
for (ValidationErrorMessage errorMessage in errorMessages) {
// do something with the errorMessage, like displaying it to the user
}
5. Encrypt and transfer payment data
After the PaymentRequest validation, you will have access to its encrypted version, EncryptedRequest. Send the encrypted customer data to your server as follows:
try {
final encryptedRequest = await sdk.encryptPaymentRequest(paymentRequest);
// Forward encryptedRequest.encryptedCustomerInput to your server
} on SdkError catch (e) {
// Encrypting the request failed
}
See a more detailed description of the encryption process in this dedicated chapter.
6. Finalise transaction
After encrypting the customer data, send the encrypted object to your server and use it to make a CreatePayment request with the Server SDK. Then, provide the encrypted data in the encryptedCustomerInput field to finalise the payment.
The response of the CreatePayment request may require additional actions from the Client, specified in the MerchantAction object. In most cases, this involves redirecting the customer to an external party (i.e. for a 3-D Secure check). Once your customers complete this check, our platform processes the actual transaction. Read the Server SDK documentation for more information.
Finally, you have to pass the information back to your Client application to display the transaction result to your customers.
Find a full overview of the payment flow in the Mobile/Client Integration guide.
SDK objects
The Flutter SDK includes several objects. Choose the object of your interest from the list below to read more about it:
- OnlinePaymentSdk
- PaymentContext
- BasicPaymentProducts
- BasicPaymentProduct
- AccountOnFile
- PaymentProduct
- PaymentProductField
- PaymentRequest
- Masking
OnlinePaymentSdk
An instance of OnlinePaymentSdk is required for all interactions with the SDK. The following code snippet shows how to initialise an OnlinePaymentSdk instance. You obtain session details by performing a Create Client Session call using the Server API.
import 'package:online_payments_sdk/online_payments_sdk.dart';
final sdk = OnlinePaymentSdk(
SessionData(
clientSessionId: '47e9dc332ca24273818be2a46072e006',
customerId: '9991-0d93d6a0e18443bd871c89ec6d38a873',
clientApiUrl: 'https://clientapi.com',
assetUrl: 'https://assets.com',
),
configuration: SdkConfiguration(
appIdentifier: 'Flutter Example Application/v1.0.0', // optional application identifier
),
);
All methods the OnlinePaymentSdk offers are wrappers around the Client API. They create the request and convert the response to Dart objects that may contain convenience functions. Every method is asynchronous and returns a Future. On error, an SdkError subclass is thrown.
Available methods:
getBasicPaymentProducts(PaymentContext context)
→ Future<basicpaymentproducts>
getPaymentProduct(int paymentProductId, PaymentContext context)
→ Future<paymentproduct>
getPaymentProductNetworks(int paymentProductId, PaymentContext context)
→ Future<paymentproductnetworksresponse>
getIinDetails(String partialCreditCardNumber, PaymentContext context)
→ Future<iindetailsresponse>
getSurchargeCalculation(AmountOfMoney amountOfMoney, CardSource cardSource)
→ Future<surchargecalculationresponse>
getCurrencyConversionQuote(AmountOfMoney amountOfMoney, CardSource cardSource)
→ Future<currencyconversionresponse>
getPublicKey()
→ Future<publickeyresponse>
encryptPaymentRequest(PaymentRequest request)
→ Future<encryptedrequest>
encryptTokenRequest(CreditCardTokenRequest request)
→ Future<encryptedrequest>
dispose()
→ void // releases HTTP client resources; call when the SDK is no longer needed
PaymentContext
PaymentContext is an object that contains the context/settings of the upcoming payment. Some methods of the OnlinePaymentSdk instance require it as an argument. This object can contain the following details:
class PaymentContext {
AmountOfMoney amountOfMoney; // contains the total amount and the ISO 4217 currency code
String countryCode; // ISO 3166-1 alpha-2 country code
bool isRecurring; // Set `true` when payment is recurring. Default false.
bool forceBasicFlow; // Set 'true' to force the basic flow. Default false.
PaymentContext(
this.amountOfMoney, this.countryCode, this.isRecurring, // Required unnamed constructor arguments
{ this.forceBasicFlow = false } // Named optional constructor argument
);
}
BasicPaymentProducts
This object contains the available payment products for the current payment. Use the session.getBasicPaymentProducts function to request the data.
The object you will receive is BasicPaymentProducts, which contains a list of all available BasicPaymentProducts and their associated AccountOnFiles.
The code snippet below shows how to get the BasicPaymentProducts instance.
try {
final basicPaymentProducts = await sdk.getBasicPaymentProducts(paymentContext);
// Display basicPaymentProducts.basicPaymentProducts & basicPaymentProducts.accountsOnFile to your customer
} on SdkError catch (e) {
// Inform the customer that something went wrong while retrieving the available Payment Products
}
BasicPaymentProduct
The SDK offers two types of objects to represent information about payment products:
- BasicPaymentProduct
- PaymentProduct
The instances of BasicPaymentProduct contain only the information required to display a simple list of payment products for the customer to choose from.
The object PaymentProduct contains additional information on each payment product. An example would be the specific form fields that the customer must fill out. You typically use this object when creating a form that asks for a customer's payment details. Read the PaymentProduct section for more info.
Below is an example of how to get display names and assets for the Visa product (id: 1).
BasicPaymentProduct? basicPaymentProduct = basicPaymentProducts.getBasicPaymentProductById(1);
int? id = basicPaymentProduct?.id;
String? label = basicPaymentProduct?.label;
String? logoUrl = basicPaymentProduct?.logo;
AccountOnFile
An instance of AccountOnFile represents information about a stored card product for the current customer. You must provide the available AccountOnFile IDs for the current payment in the request body of the Server API's CreateSession call if you want to let a customer use a previously tokenised payment method.
If the customer wants to use an existing AccountOnFile for a payment, you should add the selected AccountOnFile to the PaymentRequest. The code snippet below shows how to retrieve the display data for an account on file. You can show this label and the logo of the corresponding payment product to the customer.
// All available accounts on file across all payment products
List<AccountOnFile> allAccountsOnFile = basicPaymentProducts.accountsOnFile;
// All available accounts on file for a specific payment product
BasicPaymentProduct? basicPaymentProduct = basicPaymentProducts.getBasicPaymentProductById(1);
List<AccountOnFile> productAccountsOnFile = basicPaymentProduct?.accountsOnFile ?? [];
// Get the specific account on file for the payment product by its id
AccountOnFile? accountOnFile = basicPaymentProduct?.getAccountOnFile('identifier');
// Shows the masked value stored for a field, e.g. the obfuscated card number.
// If the stored value for "cardNumber" is **** **** **** 7412, that is returned directly.
String? maskedValue = accountOnFile?.getValue('cardNumber');
// Display label for the account on file, typically a masked card number
String? displayLabel = accountOnFile?.label;
PaymentProduct
BasicPaymentProduct only contains the basic payment product information that customers need to distinguish them. However, when they select a payment product or an account on file, they must provide additional information. The system needs mandatory info like the bank account number, credit card number, and expiry date to process the payment. The instances of BasicPaymentProduct do not contain any information about these fields.
So when you need detailed payment information, call the PaymentProduct object. This object contains a list of PaymentProductField instances. Each PaymentProductField carries a piece of information required to process the payment (e.g. bank account number, credit card number).
Use the OnlinePaymentSdk instance to retrieve the instance of PaymentProduct, as shown in the code snippet below.
try {
final paymentProduct = await sdk.getPaymentProduct(
1, // id of the payment product you want to retrieve
paymentContext,
);
// Display the fields to your customer
} on SdkError catch (e) {
// Inform the customer that something went wrong while retrieving the Payment Product
}
PaymentProductField
PaymentProductField instances represent individual payment product fields (e.g. bank account number, credit card number). Each field has the following:
- An identifier
- A type
- A definition of restrictions that apply to the field's value
- Built-in validation for input values
- Information on how the field should be displayed to the customer
In the code example below, the system retrieves the field with the identifier "cvv" from a payment product. The system then checks the data restrictions to identify if it is a required field or an optional field. Finally, the system inspects whether the values the customer provided should be visible or hidden in the user interface.
PaymentProductField ccvField = paymentProduct.getPaymentProductFieldById("cvv");
bool isRequired = ccvField.dataRestrictions.isRequired; // state if value is required for this field
bool shouldObfuscate = ccvField.displayHints?.obfuscate; // state if field value should be obfuscated
PaymentRequest
Once the customer selects a payment product and the system retrieves an instance of PaymentProduct, a payment request can be constructed. You must use the PaymentRequest class as a container for all the values the customer provides.
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct,
tokenize: true, // Optional argument to tokenise the request - default is false
accountOnFile: accountOnFile // Optional argument to set the accountOnFile to be used for the paymentRequest
);
Tokenise payment request
A PaymentRequest has a property tokenize. You can use it to indicate whether a payment request should be stored as an account on file for future payments. The code snippet below shows how to construct a payment request when you want to store it as an account on file.
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct,
);
// you can set the request's tokenize property after having initialised the paymentRequest
paymentRequest.tokenize = true;
By default, tokenize is set to false.
If the customer selects an account on file, you must supply both the account on file and the corresponding payment product when constructing the payment request. You can retrieve the instances of AccountOnFile from instances of BasicPaymentProduct and PaymentProduct.
// you can supply accountOnFile via the constructor
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct,
accountOnFile: accountOnFile
);
// or by accessing the request's accountOnFile property
paymentRequest.accountOnFile = accountOnFile;
Set field values for the payment request
Once you create a payment request, you can supply the values for the payment request fields as follows:
PaymentRequest paymentRequest = PaymentRequest(
paymentProduct: paymentProduct,
);
paymentRequest.setValue(
"cardNumber", // field id
"1245 1254 4575 45" // value
);
paymentRequest.setValue("cvv", "123");
paymentRequest.setValue("expiryDate", "12/25");
The identifiers of the fields, such as "cardNumber" and "cvv", are used to set the field values using the payment request. In general, you can retrieve all available fields from the PaymentProduct instance.
Calling setValue on a field that is marked as read-only in the associated AccountOnFile throws an InvalidArgumentError.
Validate payment request
Once the server receives all the values, it can validate the payment request. The validation uses the DataRestrictions defined in the fields added to the PaymentRequest. The server will also provide a list of errors that occurred during validation.
If there are no errors, you can encrypt the payment request and send it to our platform via your server. If there are validation errors, you should provide the customer with feedback on these errors.
// Validate all fields in a Payment Request
List<validationerrormessage> errorMessages = await paymentRequest.validate();
// check if the payment request is valid
if (errorMessages.isEmpty) {
// payment request is valid
} else {
// payment request has errors
}
The validations are the Validators linked to the PaymentProductField. The server returns them as a ValidationErrorMessage.
for (ValidationErrorMessage errorMessage in validationResult.errorMessages) {
// do something with the errorMessage, like displaying it to the user
// errorMessage.paymentProductFieldId — which field failed
// errorMessage.rule — which rule was violated
}
Encrypt payment request
The PaymentRequest is ready for encryption only after the following conditions have been met:
- The PaymentProduct is set
- The PaymentProductField values have been provided and validated
- The selected AccountOnFile or tokenize properties have been set (optional)
The encryption is done using sdk.encryptPaymentRequest. After successfully encrypting the PaymentRequest, you will get access to its encrypted version. The EncryptedRequest contains the encrypted customer input and encoded client meta info.
try {
final encryptedRequest = await sdk.encryptPaymentRequest(paymentRequest);
// Forward encryptedRequest.encryptedCustomerInput to your server
// encryptedRequest.encodedClientMetaInfo is also available if needed
} on SdkError catch (e) {
// Something went wrong while encrypting your payment request
}
Although you can use your own encryption algorithms to encrypt a payment request, we advise you to use the encryption functionality offered by the SDK.
Masking
The SDK offers a masking functionality on PaymentProductField and PaymentRequestField. It allows you to format field values for display and apply or remove masks on a string.
// apply mask to a raw value
String? maskedValue = paymentProduct.getField('cardNumber')?.applyMask('4242424242424242'); // "4242 4242 4242 4242"
// remove mask from a formatted value
String unmaskedValue = paymentProduct.getField('cardNumber')?.removeMask('4242 4242 4242 4242') ?? ''; // "4242424242424242"
// Get the masked value from a PaymentRequestField for display in your UI
String? displayValue = paymentRequest.getField('cardNumber').getMaskedValue();
Additional features
The SDK has a lot more to offer. Have a look at the following features, as they will help you build the perfect solution.
Encrypt sensitive data
One of the biggest assets of the SDK is its encryption tool. It offers great security when transferring sensitive data (i.e. card numbers, expiry date, CVC code). An entire encryption/transfer flow looks like this:
The SDK is here to simplify this process. Here is what you need to do:
- Use the sdk.encryptPaymentRequest to encrypt the payment information provided in the PaymentRequest.
- The Future returned by encryptPaymentRequest resolves to an EncryptedRequest containing the encrypted customer data.
- Retrieve the encrypted customer input from the EncryptedRequest.
- Send the encrypted customer input to your server.
- Send the encrypted data from your server using the CreatePayment request. Provide the encrypted data in the encryptedCustomerInput field.
- Send the transaction result to the client application.
Do not store the encrypted data. Transfer it via the Server API directly to our platform right after the encryption.
try {
final encryptedRequest = await sdk.encryptPaymentRequest(paymentRequest);
// Forward encryptedRequest.encryptedCustomerInput to your server
} on SdkError catch (e) {
// Something went wrong while encrypting your payment request
}
The SDK does all the heavy lifting, including:
- Requesting a public key from the Client API
- Performing the encryption
- BASE-64 encoding the result into one string
You only need to ensure that the PaymentRequest object contains all the information entered by the user.
Although the payment data is encrypted on your customers' devices, they are still out of scope for your PCI-DSS certification level, as you cannot be responsible for the security of a device you do not control.
To keep the risk to card data and level as low as possible, we strongly recommend complying with the following:
- Use our Client SDK's encryption mechanism (public and private keys), which is in line with the requirements in PCI DSS. Encrypting card data on your customers' devices using our platform's public key ensures your e-commerce server will not process plain card data. Consequently, your required PCI type for this integration method is SAQ A.
- Develop your mobile app according to the PCI Security Standards Council's requirements as described in this FAQ.
Validate data
Each PaymentProductField has appropriate DataRestrictions. The DataRestrictions object contains information about all mandatory fields and validates whether the values entered meet the correctness condition. Together with a list of abstract validators, it also has a property isRequired. This property informs whether given restrictions are required or not.
You can validate a particular input just as easily as through the PaymentRequest validation. In case of any errors, the errorMessages field of the ValidationResult will display a list of errors.
It contains the following validators:
- Expiration Date: Checks whether the entered card expiration date is not earlier than the current date and whether it is not beyond the range of twenty-five years ahead.
- Email Address: Checks the format of the email address the customer has provided.
- Fixed List: Checks whether the entered value is on the list of possibilities.
- IBAN: Validates the IBAN the customer has provided.
- Length: Checks if the entered value is longer than the minimum value and if it is not longer than the maximum value.
- Luhn: The checksum formula used to validate a variety of identification numbers, such as credit card numbers.
- Range: Checks if the value is greater than the minimum value and if it is not greater than the maximum value.
- Regex: Validates that the entered value matches the regular expression.
- TermsAndConditions: The boolean validator for the terms and conditions accept field.
Each validator returns an appropriate error, indicating a field that does not meet the conditions, and a message you can easily translate.
Apply IIN check
The first six digits of a payment card number are known as the Issuer Identification Number (IIN). You can check the payment product and network associated with the entered IIN as soon as the customer enters the first six digits of their card number. Use the sdk.getIinDetails call to retrieve that information and verify if you can accept that card type.
You can use an instance of OnlinePaymentSdk to check which payment product is associated with an IIN. You do that with the sdk.getIinDetails function. The result of this check is an instance of IinDetailsResponse. This class has the following:
- A property status indicating the result of the check
- Property paymentProductId indicating which payment product is associated with the IIN.
You can use the returned paymentProductId to fetch the PaymentProduct and show the appropriate logo to the customer.
The IinDetailsResponse has a status property represented through the IinStatus enum. The IinStatus enum values are:
- SUPPORTED indicates that the IIN is associated with a payment product supported by our platform.
- UNKNOWN indicates that the IIN is not recognised.
- UNSUPPORTED indicates that the IIN is not recognised by our platform.
- NOT_ENOUGH_DIGITS indicates that fewer than six digits were provided, and that it is impossible to perform the IIN check.
- EXISTING_BUT_NOT_ALLOWED indicates that the provided IIN is recognised, but that the corresponding product is not allowed for the current payment or merchant.
try {
final iinDetails = await sdk.getIinDetails('123456', paymentContext);
if (iinDetails.status == IinStatus.supported) {
// iinDetails.paymentProductId — use to load the matching PaymentProduct
}
} on SdkError catch (e) {
// Handle error while retrieving IIN details
}
Some cards are co-branded and can be processed as either a local card (with a local brand) or an international card (with an international brand). If you are not set up to process these local cards, the API call will not return that card type in its response.
if (iinDetails.coBrands.isNotEmpty) {
// Let the customer pick a brand from iinDetails.coBrands
Implement native payments
Our system supports native payments for mobile devices, including Google Pay for Android and Apple Pay for iOS.
If the customer receives a payment product responsible for the native payment, the SDK automatically verifies whether the device can handle the payment.
For Android devices, you first verify whether the system meets the minimum version (6.0 - Marshmallow) criterion. Then, you use the PaymentClient to perform an IsReadToPayRequest to return a value depending on the result. The SDK will do that automatically and filter out unsupported payment products.
For iOS devices, first verify whether the system meets the minimum version (15.6) criterion. Then, use the PKPaymentAuthorizationViewController to check whether it is possible to carry out the transaction. If the device does not meet the conditions, this payment is hidden.
Refer to our Google Pay and Apple Pay guides for more information.