Guides β€’ Accept Payments
iOS
doc

Accept payments via Revolut Pay - iOS

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.

Revolut Pay - Mobile

How it works​

From an implementation perspective, the Revolut Pay iOS SDK works with the following components:

  1. Server-side: A server-side endpoint is required to securely communicate with the Merchant API to create orders.
  2. Client-side: The SDK is configured in your app with your public API key. When the customer taps the Revolut Pay button, the SDK uses the 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.
  3. Endpoint for webhooks: Your server should listen for webhook events to reliably track the payment lifecycle and handle critical backend processes like updating order status, managing inventory, or initiating shipping. For more information, see: Use webhooks to keep track of the payment lifecycle.

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.

  1. The customer taps the Revolut Pay button in your app.
  2. Your app obtains an order token from your server and passes to the SDK for initialisation.
  3. The SDK presents a native payment sheet where the customer reviews and authorises the payment, potentially using biometrics or passkeys.
  4. The SDK processes the payment and returns the result to your app via a completion handler. You should use this result to update your UI (e.g., show a success or failure message).
  5. Your server receives webhook notifications to confirm the payment's final state and securely fulfill the order.

Available versions and SDK support​

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.

    note

    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.

Implementation overview​

Check the following high-level overview on how to implement Revolut Pay in your app:

  1. Set up an endpoint for creating orders
  2. Configure your Xcode project
  3. Initialise the SDK
  4. Add the Revolut Pay button
  5. Handle payment result

Before you begin​

Before you start this tutorial, ensure that you have completed the following steps:

Implement Revolut Pay on iOS​

This section walks you through the server- and client-side implementation step by step.

1. Set up an endpoint for creating orders​

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:

  1. Receive the checkout details (e.g., amount, currency) from your client-side request.
  2. Securely call the Merchant API: Create an order endpoint with the checkout details.
  3. Receive the order object, including the public token, in the API response.
  4. Return the 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"
}

2. Configure your Xcode project​

This section covers the one-time setup tasks required to prepare your Xcode project for the SDK.

2.1 Install the SDK​

note

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.

note

Check the following section to see which SDK version you should use.

2.2 Configure project capabilities​

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>

2.3 Enable biometrics and passkeys support​

note

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.

  1. Register your App ID with Revolut: Email your App ID (in the following format: <Team ID>.<Bundle ID>) to merchant-integration@revolut.com.

    info
    • The Team ID is provided by Apple in your developer account
    • The Bundle ID is the unique identifier of your app

    If your Team ID is ABCD12345 and your Bundle ID is com.company.myshop, your App ID is ABCD12345.com.company.myshop.

  2. 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.

2.4 Add the URL handler​

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)
}
}

3. Initialise the SDK​

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
))

4. Add the Revolut Pay button​

On your checkout screen, create and display the Revolut Pay button.

4.1 Create the 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
}
}
)
info

For more information about the parameters and button styling, see: Parameters: iOS and Revolut Pay button guidelines.

4.2 Display the button​

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)
])

4.3 Advanced features​

You can enable additional features like saving payment methods or Fast Checkout within the button initaliser.

  • Merchant Initiated Transactions (MIT): To save a customer's payment method for future use (e.g., subscriptions), pass savePaymentMethodForMerchant: true. See our guide on charging a saved payment method for details.
  • Fast checkout: To collect shipping details via Revolut Pay, pass shouldRequestShipping: ture. This requires your backend to support the Fast checkout flow. See the Fast Checkout guide for details.
note

Fast checkout and MIT are mutually exclusive. You can enable one or the other, but not both in the same transaction.

Add a promotional banner​

You can use the promotional banner widget to offer rewards to customers who create a new Revolut account after checkout.

Boost Your Conversions!

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
)
])
info

For more information about the possible parameters of the banner, see: Revolut Pay iOS SDK: RevolutPayKit.promotionalBanner.

5. Handle payment result​

caution

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.

success

If all the steps have been followed correctly, you have successfully implemented Revolut Pay! πŸŽ‰

Example​

For a complete, working implementation, please refer to the example app included in our public SDK repository.

To run the example app:

  1. Clone the repository.
  2. Navigate to the ExampleApp directory within the latest release.
  3. Run make project to install dependencies.
  4. Open RevolutPayApp.xcworkspace in Xcode and run the project.

Preparing for App Store submission​

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.

caution

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:

  1. The privacy manifest file is located within the RevolutPayments.zip archive under Frameworks/RevolutPay/RevolutPayNative.bundle/PrivacyInfo.xcprivacy.
  2. Download the archive from the latest Release and extract the privacy manifest.
  3. Add the privacy manifest to your app's resources:
    • If your app does not currently use a privacy manifest, simply add the SDK's file to your app's resources.
    • If you already have an existing privacy manifest, merge the SDK's manifest with your app's existing privacy document to ensure compliance with Apple's new requirements. Address any conflicts by integrating data handling practices from both the SDK and your app into a unified document.

Implementation checklist​

note

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.

Project setup​

  • SDK is installed via CocoaPods.
  • Info.plist contains the revolut URL scheme.
  • Associated Domain webcredentials:sso.revolut.com is configured for passkeys.
  • The SDK is initialised with the correct public API key and environment.
  • The Privacy Manifest is correctly merged into the app's resources.

Payment flow​

  • The Revolut Pay button appears correctly on the checkout screen.
  • Tapping the button successfully calls your server to create an order and receives a token.
  • Test case 1 (Revolut app not installed): The payment flow completes successfully within the in-app native/WebView flow.
  • Test case 2 (Revolut app installed): The payment flow correctly redirects to the Revolut app and back.
  • Test case 3 (Biometrics): Passkey/Face ID/Touch ID login works as expected (requires a real device).
  • A successful payment shows a success message in the UI.
  • A failed payment shows an appropriate error message in the UI.
  • The user cancelling the payment flow is handled gracefully.

Backend verification​

  • Your server correctly receives and processes webhook events for different payment states (e.g., ORDER_COMPLETED, ORDER_AUTHORISED for success; ORDER_PAYMENT_FAILED, ORDER_CANCELLED for failure or cancellation).
  • Order fulfillment logic is only triggered after receiving a successful webhook, not from the client-side callback.

What's next​

Was this page helpful?