Welcome to the implementation guide for Revolut Pay on iOS! This page provides a comprehensive walkthrough for integrating Revolut Pay into your iOS application, allowing your customers to pay with their card or Revolut account for a streamlined checkout experience.
From an implementation perspective, the Revolut Pay iOS SDK works with the following components:
token
obtained from your server to initate and process the payment. The SDK handles the entire payment flow, including presenting native sheets, handling biometric authentication, and redirecting to the Revolut app if necessary.The payment flow differs slightly based on the SDK version you integrate and whether the customer has the Revolut app installed.
With the modern native SDK, the entire payment experience, including login and payment authorisation, occurs within a native interface inside your app. This provides the most seamless experience for the user, regardless of whether they have the Revolut app installed.
token
from your server and passes to the SDK for initialisation.The Revolut Pay iOS SDK is available in two versions:
Revolut Pay iOS SDK 3.x.x and newer (Recommended): This version provides a fully native payment flow, offering a superior user experience directly within your app.
Integrating this version will add approximately 45MB to your app's total size.
Revolut Pay iOS SDK 2.x.x: This version uses a flow that prioritises redirecting to the Revolut app, with a WebView-based experience as a fallback if the app is not installed.
Check the following high-level overview on how to implement Revolut Pay in your app:
Before you start this tutorial, ensure that you have completed the following steps:
This section walks you through the server- and client-side implementation step by step.
Before the Revolut Pay button can be displayed in your app, your client-side code needs to fetch a unique, single-use token
that represents an order. This token
can only be created on your server by making a secure call to the Revolut Merchant API.
This server-side endpoint is a mandatory security requirement. Your secret API key must never be exposed in your iOS application.
When a customer taps the Revolut Pay button in your app, your app will call this endpoint. Your endpoint is then responsible for:
amount
, currency
) from your client-side request.token
, in the API response.token
from the response to your app.Later, in the client-side configuration, the createOrder
callback function will call this endpoint to fetch the token
, which is required to initialise the SDK and display the Revolut Pay button.
Below is an example of the JSON response your endpoint will receive from the Merchant API after successfully creating an order. The crucial field to extract and return to your app is the token
.
{
"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": 1000,
"currency": "GBP",
"outstanding_amount": 1000,
"capture_mode": "automatic",
"checkout_url": "https://checkout.revolut.com/payment-link/0adc0e3c-ab44-4f33-bcc0-534ded7354ce",
"enforce_challenge": "automatic"
}
This section covers the one-time setup tasks required to prepare your Xcode project for the SDK.
The minimum supported iOS version is 13.0.
We recommend using CocoaPods to add the Revolut Pay iOS SDK to your Xcode project. Add the following line to your Podfile
:
# For the latest native SDK (recommended)
pod 'RevolutPayments/RevolutPay'
...
# Add the following code at the end of your `Podfile`
post_install do |installer|
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end
end
end
end
Then run pod install
from your terminal.
Check the following section to see which SDK version you should use.
To allow your app to open the Revolut retail app, you must declare the revolut
URL scheme in your Info.plist
file.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>revolut</string>
</array>
This step is only required when implementing the Native SDK (3.x.x).
To offer users a seamless and secure login experience with Face ID, Touch ID, and passkeys, you must associate your app with our web service.
Register your App ID with Revolut: Email your App ID (in the following format: <Team ID>.<Bundle ID>
) to merchant-integration@revolut.com.
If your Team ID is ABCD12345
and your Bundle ID is com.company.myshop
, your App ID is ABCD12345.com.company.myshop
.
Add Associated Domain: Once your app is registered with Revolut. In your Xcode project, go to Signing & Capabilities, add the Associated Domains capability, and enter webcredentials:sso.revolut.com
. This entry links your app with Revolut's single sign-on (SSO) service, enabling biometrics and passkeys for authentication.
When the user is redirected from the Revolut app back to yours, you must pass the incoming URL to the SDK.
Your implementation depends on your app's lifecycle management. Use the UISceneDelegate
method for modern, scene-based apps (the default since iOS 13), which support features like multiple windows on iPad. Use the AppDelegate
method for older apps or if you have explicitly opted out of the scene-based lifecycle.
If you are using UISceneDelegate
, add this to your SceneDelegate
:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
RevolutPayKit.handle(url: url)
}
}
First, import the RevolutPayments
module. Then, on app launch, typically in your AppDelegate
, configure the SDK with your public API key and the environment.
import RevolutPayments
// In your AppDelegate's didFinishLaunchingWithOptions method
RevolutPaymentsSDK.configure(with: .init(
merchantPublicKey: "<yourPublicApiKey>",
environment: .production // or .sandbox for testing
))
On your checkout screen, create and display the Revolut Pay button.
Instantiate RevolutPayKit
and call the button
method. This is where you connect your server-side endpoint and define what happens after the payment attempt.
let revolutPayKit = RevolutPayKit()
let button = revolutPayKit.button(
style: .init(size: .large),
returnURL: "myapp://revolut-pay", // Your app's custom URL scheme
createOrder: { createOrderHandler in
// 1. Call your server to create the order
createOrderOnBackEnd { orderToken in
// 2. Pass the token to the SDK
createOrderHandler.set(orderToken: orderToken)
}
},
completion: { result in
switch result {
case .success:
// Handle successful payment
case .failure(let error):
// Handle payment error
case .userAbandonedPayment:
// Handle abandoned payment
}
}
)
For more information about the parameters and button styling, see: Parameters: iOS and Revolut Pay button guidelines.
Add the created button to your view hierarchy.
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.bottomAnchor.constraint(equalTo: view.bottomAnchor),
button.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor),
button.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
You can enable additional features like saving payment methods or Fast Checkout within the button initaliser.
savePaymentMethodForMerchant: true
. See our guide on charging a saved payment method for details.shouldRequestShipping: ture
. This requires your backend to support the Fast checkout flow. See the Fast Checkout guide for details.Fast checkout and MIT are mutually exclusive. You can enable one or the other, but not both in the same transaction.
You can use the promotional banner widget to offer rewards to customers who create a new Revolut account after checkout.
We recommend implementing the promotional banner. Analysis has shown that having the upsell widget can increase conversion to payment by ~5%.
First, configure the banner by calling revolutPayKit.promotionalBanner
method:
let promotionalBanner = revolutPayKit.promotionalBanner(
transactionId: "transaction-id", // Unique ID of the payment corresponding to the promotional offer
amount: 10_00,
currency: .EUR,
customer: .init()
)
Then, add the banner to your view hierarchy, for example on your order confirmation screen:
view.addSubview(promotionalBanner)
promotionalBanner.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
promotionalBanner.topAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.topAnchor,
constant: 16
),
promotionalBanner.trailingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.trailingAnchor,
constant: -16
),
promotionalBanner.leadingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.leadingAnchor,
constant: 16
)
])
For more information about the possible parameters of the banner, see: Revolut Pay iOS SDK: RevolutPayKit.promotionalBanner
.
The client-side completion handler is for UI updates only. Its delivery is not guaranteed due to network conditions or other issues. You must rely on server-to-server webhooks to get the final, authoritative status of a payment before fulfilling the order.
The completion
block passed to the button
method provides a Result
type that tells you if the payment succeeded, failed, or was cancelled. Use this to show an appropriate message to the user.
If all the steps have been followed correctly, you have successfully implemented Revolut Pay! π
For a complete, working implementation, please refer to the example app included in our public SDK repository.
To run the example app:
ExampleApp
directory within the latest release.make project
to install dependencies.RevolutPayApp.xcworkspace
in Xcode and run the project.To comply with Apple's App Store requirements, you must include our privacy manifest in your app. This file, named PrivacyInfo.xcprivacy
, details the data collection practices of the Revolut Pay SDK.
Because the Revolut Pay SDK is distributed as a static library, you must manually merge our PrivacyInfo.xcprivacy
file with your app's primary privacy manifest.
These steps are required to prepare your iOS application for Apple's review policies and ensure that your Revolut Pay integration adheres to their privacy standards.
For merchants using the Native SDK (3.x.x
), privacy manifests are available from version 3.2.1
:
RevolutPayments.zip
archive under Frameworks/RevolutPay/RevolutPayNative.bundle/PrivacyInfo.xcprivacy
.The Sandbox environment is designed to replicate the production environment's behaviour, with the key difference being the absence of app redirection due to the lack of a sandbox version of the Revolut retail app.
For more information about Revolut Pay payment flows in Sandbox, see: Test flows.
Before going live, use this checklist to test your integration in both the .sandbox
and .production
environments.
Info.plist
contains the revolut
URL scheme.webcredentials:sso.revolut.com
is configured for passkeys.token
.ORDER_COMPLETED
, ORDER_AUTHORISED
for success; ORDER_PAYMENT_FAILED
, ORDER_CANCELLED
for failure or cancellation).