The Revolut Merchant Card Form SDK for Android allows merchants to accept card payments within their mobile applications. This guide provides step-by-step instructions for integrating a prebuilt payment form using the SDK.
From an implementation perspective, the SDK works with the following components:
token
, using the Merchant API: Create an order endpoint.RevolutPaymentApi.buildCardPaymentIntent()
method. This returns an intent for launching a UI activity for gathering payment details and confirming the payment.onActivityResult()
method, providing the status of the payment.The order and payment flow is similar to all card payment solutions:
For more information about the order and payment lifecycle, see: Order and payment lifecycle.
Before you start this tutorial, ensure you have completed the following steps:
Since the SDK is hosted on mavenCentral
, to fetch the dependency add the following lines to your project-level build.gradle
file:
allprojects {
repositories {
mavenCentral()
}
}
To install the SDK, add the merchantcardform
to the dependencies
block of your module-level build.gradle
file:
dependencies {
// ...
// Revolut Card Payments SDK
implementation 'com.revolut.payments:merchantcardform:1.3'
}
Sync your project.
Before accepting payments, initalise the SDK by calling the following method:
RevolutPaymentApi.init(
Environment.PRODUCTION,
"<merchantPublicKey>" // Your Production API Public key
)
When a customer decides to make a purchase on your website, using the Merchant API: Create an order endpoint, you'll need to create an order based on your customer's checkout and obtain a token
.
This token represents the order and is used to invoke the buildCardPaymentIntent()
method. The process of creating an order and receiving a token will vary based on your backend setup.
See an example response of an order created with minimal required parameters:
{
"id": "6516e61c-d279-a454-a837-bc52ce55ed49",
"token": "0adc0e3c-ab44-4f33-bcc0-534ded7354ce",
"type": "payment",
"state": "pending",
"created_at": "2023-09-29T14:58:36.079398Z",
"updated_at": "2023-09-29T14:58:36.079398Z",
"amount": 5,
"currency": "GBP",
"outstanding_amount": 5,
"capture_mode": "automatic",
"checkout_url": "https://checkout.revolut.com/payment-link/0adc0e3c-ab44-4f33-bcc0-534ded7354ce",
"enforce_challenge": "automatic"
}
To accept a payment from your customer, you'll need to initiate the payment process by invoking the RevolutPaymentApi.buildCardPaymentIntent()
method. This will return an intent for launching an activity. The activity provides the necessary UI for collecting the user's card details and confirming the payment.
The method requires several parameters, including the application context, the unique order token
obtained from your server. Optionally, the customer's email, billing and shipping address. The intent created is then launched using the startActivityForResult()
method.
Here's an example of how you can start the payment process:
startActivityForResult(
RevolutPaymentApi.buildCardPaymentIntent(
context = context,
orderId = "<token>",
RevolutPaymentApi.Configuration.CardPayment(
email = "example.customer@example.com",
billingAddress = AddressParams(
streetLine1 = "1 Canada Square",
streetLine2 = "Sample street",
city = "London",
region = "Greater London",
country = "GB",
postcode = "12345"
),
shippingAddress = null,
savePaymentMethodFor = null
)
), 0
)
Code snippet | Explanation |
---|---|
startActivityForResult | This method is used to start a new activity and receive a result. The result will be handled in the onActivityResult method of the current activity. |
RevolutPaymentApi.buildCardPaymentIntent | This method creates an Intent for starting the payment activity provided by the SDK. |
context | The context in which the application is running, typically the current activity. |
orderId | The unique token of the order, obtained from your server after creating an order. |
RevolutPaymentApi.Configuration.CardPayment | Configuration object that includes optional payment details such as email, billing and shipping address. |
email | The customer's email address (optional). |
billingAddress | The customer's billing address (optional, but recommended to increase payment acceptance). |
shippingAddress | The customer's shipping address (optional). |
savePaymentMethodFor | Indicates whether the payment method should be saved for the customer or merchant (optional). For more information, see: Save payment methods. |
For more details about the available parameters see, Revolut Merchant Card Form SDK: Methods and parameters.
The savePaymentMethodFor
parameter allows you to save a customer's payment method used in the current payment session. You have the option to save a payment method either for the customer
or the merchant
. To learn more about customer and merchant initiated payments, see: Charge a customer's saved payment method.
If you wish to save a customer's payment details using the Revolut Merchant Card Form SDK, you need to meet one of the following requirements:
email
and assign it to the order by providing customer.id
customer.email
during order creationTo handle the payment result, you need to implement onActivityResult()
in your activity or fragment, which is invoked when the payment operation is completed. This method allows you to capture the payment result and perform various actions within your application.
onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val result = RevolutPaymentApi.mapIntentToResult(resultCode, data)
result?.let { handleResult(it) }
}
Code snippet | Explanation |
---|---|
onActivityResult() | This method is a callback in Android used to receive the result from a previous activity. The requestCode identifies which activity is returning a result, the resultCode indicates the success or failure of the operation, and data is the intent containing additional information or results. This method is critical for handling results in activities that are started for a result, such as payment operations. |
super.onActivityResult(requestCode, resultCode, data) | This line calls the parent class's implementation of onActivityResult() . It's important to include this to ensure that any default processing in the parent class is also executed. Neglecting this can lead to unexpected behaviour, especially if the superclass needs to handle certain results. |
val result = RevolutPaymentApi.mapIntentToResult(resultCode, data) | The mapIntentToResult() method is provided by the SDK to simplify the process of interpreting the result of the payment activity. It takes the resultCode and data intent and converts them into a Result object that is easier to work with. This encapsulation hides the complexity of parsing the intent and managing various possible result codes, allowing developers to focus on business logic. |
result?.let { handleResult(it) } | This line checks if the result is not null . If a result exists, the handleResult() function is invoked, passing the Result object as a parameter. This is where custom logic can be applied based on the outcome of the payment process, such as displaying messages to the user, updating the UI, or processing the transaction data further. This approach ensures that you only proceed with valid results, avoiding potential null pointer exceptions. |
handleResult(it) | You define this function, which processes the Result object returned by mapIntentToResult() . Depending on whether the payment was successful or not, you can perform actions such as displaying a success message, retrying the payment, logging errors, or initiating post-payment workflows like order fulfilment. This step is where you implement your application's response to the payment result, ensuring a smooth user experience. |
The mapIntentToResult()
method is critical because it abstracts the complexity of interpreting the result of the payment activity. This allows you to focus on the logic for handling the result, such as:
The result codes between 1000
and 1009
(included) are used by the SDK, avoid using them to prevent any collisions.
For more details about the possible payment results, see: Revolut Merchant Card Form SDK: Payment results.
In addition to handling payment results directly in your app, you can also set up webhooks to receive notifications about different events. Webhooks provide a reliable way to track the entire order and payment lifecycle, allowing your server to react to changes.
To implement webhooks, refer to the Use webhooks to track order and payment lifecycle tutorial for detailed instructions on setting up and managing webhooks with the Merchant API.
By utilizing both in-app payment result handling and webhooks, you can create a robust and responsive payment processing system that enhances the user experience and streamlines your business operations.
The SDK's public repository contains a fully functional example app designed to demonstrate how to integrate the Revolut Merchant Card Form SDK into your mobile application. This app serves as a practical reference for developers, showcasing a working implementation of the SDK's features.
Follow these steps to set up and run the example app:
Clone the repository:
git clone https://bitbucket.org/revolut/revolut-card-payments-android.git
Open the project in Android Studio, or your preferred IDE.
Update the following line in the demo/app/build.gradle
file:
implementation 'com.revolut:cardpayments:1.0.0' // Change this line
implementation 'com.revolut.payments:merchantcardform:1.3' // To this line
Now you can run the example app.
Before deploying your implementation to your production environment, complete the checklist below to see if everything works as expected, using Merchant API's Sandbox environment.
To test in Sandbox environment, set the base URL of your API calls to: sandbox-merchant.revolut.com/
and initialise the SDK in sandbox:
RevolutPaymentApi.init(
Environment.SANDBOX,
"<merchantPublicKey>" // Your Sandbox API Public key
)
token
. The order must be created in the same environment where the widget is loaded, in this case the Sandbox environment. If your implementation handles all these cases as you expect in Sandbox, it is advised you also test your implementation in production before going live. Once your implementation passes all the checks in both environments, you can safely go live with your implementation.
These checks only cover the implementation path described in this tutorial, if your application handles more features of the Merchant API, see the Merchant API: Implementation checklists.
Congratulations! You've successfully integrated the card form with the Merchant API in your app.