Revolut Pay
Fast checkout for Revolut users with saved payment methods and instant authentication. The revolutPay module provides methods to mount and manage the Revolut Pay button, which enables customers to pay with their Revolut account or saved cards.
Key features:
- 1-click checkout for Revolut users
- Support for both card and bank account payments
- Built-in customer data collection
- Event-based payment lifecycle tracking
- Customisable button styles
- Optional line items and shipping collection
For a complete implementation guide with examples, see: Accept payments via Revolut Pay - Web
Check out our live Revolut Pay demo and integration examples repository.
Prerequisites
This payment method requires Payments module initialisation.
Type signature
type PaymentsModuleRevolutPayInstance = {
mount: (
target: string | HTMLElement | null,
options: WidgetPaymentsRevolutPayOptions
) => void
on: <T extends RevolutPayEvents['type']>(
event: T,
callback: (payload: RevolutPayEventPayload<T>) => void
) => void
destroy: () => void
}
The revolutPay object, returned from the parent payments() instance, exposes the following methods:
| Method | Description | Signature |
|---|---|---|
mount() | Renders the Revolut Pay button into a target DOM element and configures it. | (target: string | HTMLElement | null, options: WidgetPaymentsRevolutPayOptions) => void |
on() | Attaches a listener to Revolut Pay events. | <T extends RevolutPayEvents['type']>(event: T, callback: (payload: RevolutPayEventPayload<T>) => void) => void |
destroy() | Removes the Revolut Pay button and cleans up all associated event listeners. | () => void |
Method details
mount(target, options)
This method renders the Revolut Pay button.
revolutPay.mount: (
target: string | HTMLElement | null,
options: WidgetPaymentsRevolutPayOptions
) => void
| Parameter | Description | Type | Required |
|---|---|---|---|
target | The DOM element or CSS selector where the button should be rendered (e.g., document.getElementById('container')). | string | HTMLElement | null | Yes |
options | An object to configure the button's behavior, appearance, and payment details. | WidgetPaymentsRevolutPayOptions | Yes |
WidgetPaymentsRevolutPayOptions
This object configures the payment session.
type WidgetPaymentsRevolutPayOptions = {
currency: string;
totalAmount: number;
createOrder: () => Promise<{ publicId: string }>;
customer?: CustomerDetails;
buttonStyle?: ButtonStyleOptions;
requestShipping?: boolean;
savePaymentMethodForMerchant?: boolean;
redirectUrls?: {
success: string;
failure: string;
cancel: string;
};
mobileRedirectUrls?: {
success: string;
failure: string;
cancel: string;
};
validate?: () => Promise<boolean> | boolean;
lineItems?: RevolutPayLineItem[];
};
| Parameter | Description | Type | Required |
|---|---|---|---|
currency | 3-letter ISO 4217 currency code for the payment. Info For more information about the supported currencies, see: Help Center. | string | Yes |
totalAmount | The total amount to be paid, in the currency's smallest denomination (e.g., cents). | number | Yes |
createOrder | Async function that calls your backend to create an order and returns the order token | () => Promise<{ publicId: string }> | Yes |
customer | Pre-fills customer details in the payment pop-up. | CustomerDetails | No |
buttonStyle | Customises the appearance of the Revolut Pay button. | ButtonStyleOptions | No |
requestShipping | If true, collects the shipping address and delivery method from the customer via the Revolut Pay flow. Default: false Note Your backend must support Fast checkout for this functionality to work, for more information see: Fast checkout guide | boolean | No |
savePaymentMethodForMerchant | If true, the customer's payment method is saved for future merchant-initiated payments (e.g., subscriptions). Default: false. | boolean | No |
redirectUrls | An object with URLs for redirecting the user after payment completion. Use this for a redirect-based flow. See the integration guide for details. | Object | No |
mobileRedirectUrls | Same as redirectUrls, but specifically for mobile devices. Can be used to combine event listening on desktop with redirects on mobile. | Object | No |
validate | An optional async function that runs before payment. Return true to proceed or throw an error to display a message and cancel. | () => Promise<boolean> | boolean | No |
lineItems | An array of objects detailing the items in the customer's cart. | RevolutPayLineItem[] | No |
CustomerDetails object
Use this object to pre-fill known customer information in the payment flow.
interface CustomerDetails {
name?: string;
email?: string;
phone?: string;
dateOfBirth?: {
day: number;
month: number;
year: number;
}
billingAddress?: Address;
shippingAddress?: Address;
}
| Parameter | Description | Type | Required |
|---|---|---|---|
name | The customer's full name. | string | No |
email | The customer's email address. | string | No |
phone | The customer's phone number, including country code (e.g., +44...). | string | No |
dateOfBirth | An object containing the customer's date of birth. | Object | No |
billingAddress | The customer's billing address. | Address | No |
shippingAddress | The customer's shipping address. | Address | No |
ButtonStyleOptions object
This object allows you to customise the appearance of the Revolut Pay button.
type ButtonStyleOptions = {
height?: string;
size?: 'large' | 'small';
radius?: 'none' | 'small' | 'large' | 'round';
variant?: 'dark' | 'light' | 'light-outlined';
action?: 'donate' | 'pay' | 'subscribe' | 'buy';
cashback?: boolean;
cashbackCurrency?: RevolutPayButtonCashbackCurrency;
};
| Property | Description | Type | Required |
|---|---|---|---|
height | The CSS height of the button (e.g., '48px'). | string | No |
size | large for a full-width button, small for an inline-sized button. | 'large' | 'small' | No |
radius | The border-radius of the button. | 'none' | 'small' | 'large' | 'round' | No |
variant | The color theme of the button. | 'dark' | 'light' | 'light-outlined' | No |
action | The call-to-action text displayed on the button. | 'donate' | 'pay' | 'subscribe' | 'buy' | No |
cashback | If true, may display rewards information on the button. | boolean | No |
cashbackCurrency | 3-letter currency code for the rewards text. | string | No |
RevolutPayButtonCashbackCurrency type
The available currencies for the rewards text:
type RevolutPayButtonCashbackCurrency =
| 'AED'
| 'AUD'
| 'BGN'
| 'CAD'
| 'CHF'
| 'CZK'
| 'DKK'
| 'EUR'
| 'GBP'
| 'HKD'
| 'HUF'
| 'ILS'
| 'JPY'
| 'MXN'
| 'NOK'
| 'NZD'
| 'PLN'
| 'QAR'
| 'RON'
| 'RUB'
| 'SAR'
| 'SEK'
| 'SGD'
| 'THB'
| 'TRY'
| 'USD'
| 'ZAR'
RevolutPayLineItem object
This object represents a single item in the customer's cart.
type RevolutPayLineItem = {
name: string;
totalAmount: string;
unitPriceAmount: string;
quantity?: {
value: number;
unit: 'PIECES';
};
type?:
| 'TAX'
| 'GIFT'
| 'MISC'
| 'REFUND'
| 'CHARGE'
| 'SERVICE'
| 'PHYSICAL'
| 'ADJUSTMENT';
productId?: string;
productUrl?: string;
description?: string;
taxes?: {
name: string;
amount: string;
type?: 'INCLUDED'
}[];
imageUrls?: string[];
totalTaxAmount?: string;
totalDiscountAmount?: string;
discounts?: {
name: string;
type?: 'FIXED';
totalAmount?: number;
appliedAmount?: number
}[];
metadata?: Record<string, string>;
};
| Property | Description | Type | Required |
|---|---|---|---|
name | The display name of the item. | string | Yes |
totalAmount | The total price for this line item (unit price * quantity). | string | Yes |
unitPriceAmount | The price of a single unit of this item. | string | Yes |
quantity | An object specifying the number of units. | Object | No |
type | The classification of the line item. | string | No |
productId | Your internal product identifier. | string | No |
productUrl | A URL pointing to the product page. | string | No |
description | A brief description of the item. | string | No |
taxes | An array of tax objects applied to this item. | Object[] | No |
imageUrls | An array of URLs for product images. | string[] | No |
totalTaxAmount | The total tax amount for this line item. | string | No |
totalDiscountAmount | The total discount amount for this line item. | string | No |
discounts | An array of discount objects applied to this item. | Object[] | No |
metadata | A key-value map for any additional data. | Object | No |
on(event, callback)
This method listens for events during the Revolut Pay lifecycle.
revolutPay.on: <T extends RevolutPayEvents['type']>(
event: T,
callback: (payload: RevolutPayEventPayload<T>) => void
) => void
| Parameter | Description | Type | Required |
|---|---|---|---|
event | The event type to listen for. | 'payment' | 'click' | Yes |
callback | Function executed when the event fires. Signature varies by event type (see below). | function | Yes |
In all callbacks, orderId refers to the order's public token (order.token from the API response), not the internal order.id. This is the public identifier used in your frontend code.
Supported events
The SDK uses TypeScript generics to provide type-safety. The callback function signature automatically adapts based on the event type.
type RevolutPayEvents =
| { type: 'click'; payload: null }
| {
type: 'payment';
payload:
| { type: 'success'; orderId: string }
| { type: 'error'; error: RevolutCheckoutError; orderId: string }
| {
type: 'cancel';
dropOffState: RevolutPayDropOffState;
orderId?: string;
};
};
click event
Fired immediately when the user clicks the Revolut Pay button, before order creation begins. The callback receives no parameters (payload: null). This is useful for tracking analytics or displaying loading states.
revolutPay.on('click', () => {
console.log('Revolut Pay button clicked')
})
payment event
Fired when the payment flow completes with one of three outcomes: success, error, or cancel. The callback receives an event object with the result details.
revolutPay.on('payment', (event) => {
switch (event.type) {
case 'success':
console.log('Payment successful!', event.orderId)
break
case 'error':
console.error('Payment failed:', event.error.message)
break
case 'cancel':
console.log('Payment cancelled at:', event.dropOffState)
break
}
})
When listening for the payment event, the payload object will have one of the following shapes:
payload.type | Description | Available fields |
|---|---|---|
'success' | Payment completed successfully. | orderId |
'error' | Payment failed. The error field is a RevolutCheckoutError object. | error, orderId |
'cancel' | User cancelled the payment. | dropOffState, orderId? |
RevolutPayDropOffState type
Indicates the step in the payment flow where the user cancelled:
type RevolutPayDropOffState =
| 'enter_otp'
| 'payment_summary'
| 'load_session_data'
| 'enter_card_details'
| 'verify_user_details'
| 'enter_personal_details'
| 'enter_shipping_details'
| 'revolut_app_push_challenge'
Handle redirects
You can handle the payment result in one of two ways:
- Event listening with mobile redirects: Use the
.on()method to handle payment outcomes in your client-side code. This is the standard approach for desktop. For mobile, you should also providemobileRedirectUrlsto handle cases where a redirect is required after the payment is completed. - Redirects only: Use the
redirectUrlsoption. This will disable the.on()event handler entirely and redirect the user to a new URL on both desktop and mobile.
When a user is redirected, Revolut Pay appends the order's public ID (token) as a query parameter named _rp_oid to the URL.
For a success URL of https://example.com/success, the final URL will be:
https://example.com/success?_rp_oid=fe34dbd3-3fa9-4d4c-8987-3f7735ba3cdf
You can fetch this ID from your redirect page using one of two methods:
-
Using
URLSearchParams:const searchParams = new URLSearchParams(window.location.search);
const revolutPublicOrderId = searchParams.get('_rp_oid'); -
Using the SDK's helper function (available from v1.1.3):
import { getRevolutPayOrderIdURLParam } from '@revolut/checkout';
const revolutPublicOrderId = getRevolutPayOrderIdURLParam();
Example usage
Here is a minimal example of how to mount the Revolut Pay button and listen for payment events.
<!-- Add a container for the button in your HTML -->
<div id="revolut-pay-container"></div>
import RevolutCheckout from '@revolut/checkout'
async function initializeRevolutPay() {
const { revolutPay } = await RevolutCheckout.payments({
publicToken: '<YOUR_PUBLIC_API_KEY>',
locale: 'en',
})
const paymentOptions = {
currency: 'GBP',
totalAmount: 2000, // £20.00
createOrder: async () => {
// Replace with your server-side call to create an order in the Merchant API
const response = await fetch('/api/create-revolut-order');
const order = await response.json()
return { publicId: order.token }
},
}
revolutPay.mount('#revolut-pay-container', paymentOptions)
revolutPay.on('payment', (event) => {
switch (event.type) {
case 'success':
console.log('Payment successful! Order ID:', event.orderId);
// e.g., redirect to a success page
break
case 'error':
console.error('Payment failed:', event.error);
// e.g., show an error message to the user
break
case 'cancel':
console.log('Payment cancelled by user at state:', event.dropOffState);
// e.g., re-enable the checkout button
break
}
})
}
initializeRevolutPay()