Accept payments via Revolut Checkout - Web
Welcome to the implementation guide for Revolut Checkout on web! In this tutorial, we'll walk you through the integration process of the Revolut Checkout widget.
Revolut Checkout is an embedded widget that aggregates all available payment methods (Card, Apple Pay, Google Pay, Pay by Bank, etc.) into a single, fully-managed UI. The ordering and availability of payment methods are configured through your Business Dashboard, not through code, giving you flexibility to update your checkout experience without deploying new code.

Saving payment methods is currently not supported.
When to use
Use embedded checkout when:
- You want a complete checkout solution with all payment methods in one widget
- You prefer configuration via Revolut Business dashboard over code
- You need automatic payment method ordering based on customer location and preferences
- You want to add new payment methods without deploying code changes
Use individual payment methods when:
- You need granular control over payment button placement
- You want to build custom UI around each payment method
- You need different payment methods on different pages
- You require specific payment method customisation beyond what the widget offers
How it works
From an implementation perspective, the Revolut Checkout widget works with the following components:
- Server-side: A server-side endpoint is required to securely communicate with the Merchant API to create orders.
- Client-side: The widget uses your public API key to initialise a
RevolutCheckoutinstance, which provides access to theembeddedCheckoutmethod. The widget is then configured and mounted using atokenfrom the created order to initiate the payment. The widget handles the payment flow, including actions like redirection or authentication. - 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 works as follows:
- The customer goes to the checkout page.
- Your frontend displays the Revolut Checkout widget showing all enabled payment methods.
- The customer selects their preferred payment method and proceeds with payment.
- Your frontend uses your server endpoint to create an order and obtains the order
tokenvia the Merchant API: Create an order. - The widget processes the payment and presents the payment result to the customer through callback functions.
- Your server receives webhook notifications about each event you're subscribed to. While this is optional, it's strongly recommended as the most reliable way to track the payment lifecycle. For more information, see: Use webhooks to keep track of the payment lifecycle.
For more information about the order and payment lifecycle in the Merchant API, see: Order and payment lifecycle.
Implementation overview
Check the following high-level overview on how to implement Revolut Checkout on your website:
- Set up an endpoint for creating orders
- Install Revolut Checkout package
- Initialise and mount the widget
- Handle payment results
The following sections describe each step in detail. To see working examples, you can skip ahead.
Before you begin
Ensure you have:
- Active Revolut Business account with Merchant capabilities
- API credentials for the Merchant API
- Registered your domain for Apple Pay (required for Apple Pay to render correctly in the
embeddedCheckoutwidget)
Implement Revolut Checkout
This section walks you through the server- and client-side implementation step by step.
The SDK supports both async/await syntax and the traditional Promise-based .then() syntax. You can see examples of both at each step of the guide.
1. Set up an endpoint for creating orders
Before implementing the client-side widget, you must first create a dedicated endpoint on your server. This is a critical security step, as your secret API key must never be exposed on the client side.
The role of this server-side endpoint is to act as a secure bridge between your frontend and the Merchant API. When a customer initiates a payment on your website, your frontend will call this endpoint. Your endpoint is then responsible for:
- Receiving the checkout details (e.g.,
amount,currency) from the frontend request. Ensure you pass theredirect_urlparameter, so customers are redirected to your shop after a Revolut Pay payment. - Securely calling the Merchant API: Create an order endpoint with the received details.
- Receiving the order details, including the public
token, back from the Merchant API. - Passing this
tokenback to your frontend in the response.
The redirect_url parameter must be set when creating an order so that Revolut Pay customers can be redirected to your shop after payment.
Later, in the client-side configuration, the createOrder callback function will call this endpoint to fetch the token, which is required to initialise the checkout widget.
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 frontend 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. Install Revolut Checkout package
Before you begin the client-side integration, add the Revolut Checkout package to your project using your preferred package manager. This package is necessary to interact with the Revolut Checkout widget.
Make sure you're on the latest version of the @revolut/checkout library.
npm install @revolut/checkout
After installation, import the SDK in your JavaScript file:
import RevolutCheckout from '@revolut/checkout'
Alternatively, you can add the widget to your code base by adding the embed script to your page directly. To learn more, see: Installation.
3. Initialise and mount the widget
Now you'll configure the checkout widget and mount it to your page.
3.1 Initialise the SDK
First, initialise the Revolut Checkout SDK with your API credentials. This creates the foundation for mounting the widget.
import RevolutCheckout from '@revolut/checkout'
const { destroy } = await RevolutCheckout.embeddedCheckout({
publicToken: '<yourPublicApiKey>',
mode: 'prod', // 'prod' for production, 'sandbox' for testing
locale: 'en' // Optional, defaults to 'auto'
// Configuration will be added in the next steps
})
// Call destroy() later if you need to remove the widget from the page
Required parameters:
publicToken- Your Merchant API Public keymode- Environment:'prod'for production or'sandbox'for testing
Optional parameters:
locale- Widget language (defaults to'auto'for automatic detection)
3.2 Add a DOM element
First, add an empty <div> container to your HTML file where you want the widget to appear.
<...>
<div id="checkout-container"></div>
<...>
3.3 Mount and configure
Now that you have the DOM element ready, add the target and createOrder configuration to mount the widget and enable order creation.
import RevolutCheckout from '@revolut/checkout'
const { destroy } = await RevolutCheckout.embeddedCheckout({
publicToken: '<yourPublicApiKey>',
mode: 'prod',
locale: 'en', // Optional, defaults to 'auto'
// Mount the widget to the DOM element
target: document.getElementById('checkout-container'),
// Create order on-demand when payment is initiated
createOrder: async () => {
// Call your backend to create an order
// For more information, see: https://developer.revolut.com/docs/merchant/create-order
const order = await yourServerSideCall()
return { publicId: order.token }
}
// Callback handlers will be added in step 4
})
// Call destroy() later if you need to remove the widget from the page
Parameters for mounting:
target(required) - The DOM element where the widget should be rendered (e.g.,document.getElementById('checkout-container'))createOrder(required) - An async function that calls your backend to create an order via the Merchant API and returns thetoken(aspublicId)- Your backend calls the Merchant API: Create an order endpoint
- The Merchant API responds with a
token - You return
{ publicId: order.token }to the widget so it can start the checkout session
Optional configuration:
email- Pre-fill the customer's email addressbillingAddress- Pre-fill the customer's billing address with the following fields:countryCode- Two-letter country code (ISO 3166-1 alpha-2)region- State, province, or regioncity- City namepostcode- Postal or ZIP codestreetLine1- First line of the street addressstreetLine2- Second line of the street address (optional)
When you provide email and billingAddress, the widget automatically pre-fills these fields in the payment form, reducing the number of fields the customer needs to fill in manually.
This improves the checkout experience and can increase conversion rates, especially when you already have customer information from registration or previous orders.
Example:
const { destroy } = await RevolutCheckout.embeddedCheckout({
// ... other configuration
email: 'customer@example.com',
billingAddress: {
countryCode: 'GB',
region: 'Greater London',
city: 'London',
postcode: 'EC1A 1BB',
streetLine1: '1 Example Street',
streetLine2: 'Flat 2B'
}
})
3.4 Destroy the widget (optional)
The embeddedCheckout() function returns an instance with a destroy() method. If you need to remove the widget from the page, you can call this method:
const { destroy } = await RevolutCheckout.embeddedCheckout({
// ... configuration
})
// Later, when you need to remove the widget:
destroy()
4. Handle payment results
Now let's complete the implementation by adding callback handlers to respond to payment events. These callbacks allow you to provide immediate feedback to customers and update your UI based on payment outcomes.
Add the onSuccess, onError, and onCancel callbacks to your configuration:
import RevolutCheckout from '@revolut/checkout'
const { destroy } = await RevolutCheckout.embeddedCheckout({
publicToken: '<yourPublicApiKey>',
mode: 'prod',
locale: 'en', // Optional, defaults to 'auto'
target: document.getElementById('checkout-container'),
createOrder: async () => {
const order = await yourServerSideCall()
return { publicId: order.token }
},
// Handle successful payments
onSuccess({ orderId }) {
console.log('Payment successful!', orderId)
window.location.href = `/confirmation?orderId=${orderId}`
},
// Handle payment errors
onError({ error, orderId }) {
console.error('Payment failed:', error.message, orderId)
alert(`Payment failed: ${error.message}`)
},
// Handle cancelled payments (optional)
onCancel({ orderId }) {
console.log('Payment cancelled', orderId)
alert('Payment was cancelled.')
}
})
After configuring the widget, you need to decide how to handle payment results. Revolut Checkout provides two complementary mechanisms for tracking payment outcomes.
Before choosing your implementation approach, it's crucial to understand the roles of client-side callbacks and server-side webhooks:
- Widget callbacks (
onSuccess,onError,onCancel): These are perfect for handling frontend logic, such as displaying a success message, updating the UI, or showing an error to the customer. However, their delivery is not guaranteed. Factors like the user's browser performance, network connectivity, or ad-blockers can prevent these events from firing. - Webhooks: These are server-to-server notifications that we guarantee to send for every payment status change. You must rely on webhooks for all critical backend logic, such as confirming the order, releasing digital goods, or starting the shipping process.
Never use widget callbacks as the sole trigger for critical backend logic.
4.1 Widget callbacks (for UI updates)
The widget callbacks (onSuccess, onError, and onCancel) allow you to respond immediately to payment events in your frontend. These are ideal for providing instant feedback to your customers.
When to use widget callbacks:
- Display success or error messages to the user
- Update the UI to reflect the payment status
- Redirect users to a confirmation/error page
- Re-enable the checkout form after cancellation
- Show loading indicators or success animations
Example use cases:
onSuccess() {
// Show a success message
showSuccessMessage('Payment successful! Thank you for your purchase.')
// Redirect to confirmation page
window.location.href = '/order-confirmation'
}
onError(error) {
// Show error to user
showErrorMessage(`Payment failed: ${error.message}`)
// Re-enable checkout button
enableCheckoutButton()
}
onCancel() {
// Inform user of cancellation
showInfoMessage('Payment was cancelled. You can try again.')
}
Important limitations:
- These callbacks are not reliable for backend operations
- Users may close their browser before callbacks fire
- Ad-blockers or network issues can prevent callbacks
- Never fulfil orders based solely on these callbacks
4.2 Webhooks (for reliable backend operations)
Webhooks are server-to-server HTTP notifications that Revolut sends to your backend whenever a payment status changes. Unlike widget callbacks, webhooks are guaranteed to be delivered, making them essential for critical business operations.
When to use webhooks:
- Confirming order completion before fulfilment
- Updating inventory or stock levels
- Initiating shipping or delivery processes
- Releasing digital goods or access rights
- Recording transactions in your database
- Sending confirmation emails
- Processing refunds or chargebacks
How webhooks work:
- An order status changes (e.g., from
pendingtocompleted) - Revolut sends an HTTP POST request to your webhook endpoint
- Your server processes the webhook and performs backend operations
- Your server responds with a
200 OKstatus code
Setting up webhooks:
To implement webhooks, you need to:
- Create a dedicated endpoint on your server to receive webhook events
- Register this endpoint URL in your Revolut Business dashboard
- Verify webhook signatures for security
- Process events based on their type (e.g.,
ORDER_COMPLETED,ORDER_PAYMENT_DECLINED)
For detailed implementation instructions, see: Use webhooks to keep track of the payment lifecycle.
Best practices:
- Always verify webhook signatures to ensure authenticity
- Implement idempotency to handle duplicate webhooks
- Respond with
200 OKquickly, then process asynchronously - Only fulfil orders after receiving
ORDER_COMPLETEDwebhook - Use both methods together: callbacks for UX, webhooks for backend operations
Customise Revolut Checkout
One of the key advantages of Revolut Checkout is that you can fully customise the checkout experience through your Revolut Business dashboard without any code changes. This allows you to:
- Enable or disable specific payment methods
- Reorder payment method priority
- Customise the visual appearance of the widget
- Add shipping address collection, trust signals, and reward banners
All customisation happens in your Revolut Business dashboard at: your profile > Settings → APIs → Merchant API tab > Revolut Checkout
The settings are organised across three tabs:
- Payment methods — enable, disable, and reorder payment methods
- Appearance — customise the visual style of the widget
- Additional modules — add shipping address collection, trust signals, and reward banners
Before saving, use the Desktop and Mobile preview panels to see how your customisation will appear to customers on different devices.
Use the Canvas colour dropdown in the preview panel to simulate how the widget looks against different page background colours — this is a preview-only tool and does not affect the live widget.
Payment methods
Manage and re-order payment methods for Revolut Checkout.

Express checkout
Express checkout groups the payment methods that let customers skip providing shipping details manually and instead use the contact and shipping information already saved in their digital wallet. Enable or disable individual methods using their toggles:
| Payment method | Description |
|---|---|
| Revolut Pay | Always enabled. Customers authenticate with their Revolut account to pay using their balance, savings, or linked cards. |
| Google Pay | Customers pay using cards saved in Google Wallet with a single tap, without entering card details. Available on Android and in Chrome. |
| Apple Pay | Customers pay using cards saved in Apple Wallet with Touch ID or Face ID, without entering card details. Available on Apple devices and in Safari. |
For backend and client-side setup instructions for Express checkout, see: Enable Express checkout.
Payment methods
Control which payment methods appear in the main payment method list below the Express checkout buttons:
| Payment method | Description |
|---|---|
| Revolut Pay | Always enabled. Customers can also pay via Revolut Pay without a Revolut account by entering their card details through the Revolut Pay flow. |
| Apple Pay | Same as the Express checkout option, shown as a selectable method in the payment list. |
| Google Pay | Same as the Express checkout option, shown as a selectable method in the payment list. |
| Pay By Bank | Customers pay directly from their bank account via open banking, without entering card details. Available in supported markets. |
| Card | Customers enter their card details directly at checkout. When enabled, expand the Card section to toggle which card schemes to accept: Visa, Mastercard, Maestro, American Express. |
Click Save to finalise your changes.
Reorder payment methods
Control the order in which payment methods appear in the widget.

- Click the icon to enter reorder mode.
- Use the drag handle next to each payment method.
- Drag and drop payment methods to your preferred order.
- The order you set determines the sequence customers see in the widget.
- Click Done to exit reorder mode.
- Click
Saveto finalise your changes.
Automatic payment method ordering
Enable Automatic payment method ordering to let Revolut dynamically optimise the payment method sequence based on:
- Customer location
- User habits and preferences
- Payment method availability
- Conversion data
When enabled, Revolut automatically shows the most relevant payment methods first for each customer, potentially improving conversion rates.
Appearance
Customise the appearance of your checkout widget to match the branding of your website.

Payment method layout
Choose how payment methods are displayed in the widget:
| Layout | Description |
|---|---|
| Vertical (default) | Payment methods are stacked vertically, one below the other |
| Horizontal | Payment methods are displayed as horizontal tiles that customers can scroll through |

Component style
Select a preset component style for the widget's form elements:
| Style | Description |
|---|---|
| Filled | Form fields with a filled background |
| Simple | Minimal style with less visual weight |
| Outlined | Form fields with an outline border |
| Simple 2 | An alternative minimal style |
| Custom | Set all style properties manually |
When a preset is selected, the following sub-settings are pre-configured and can be individually overridden:
| Setting | Description |
|---|---|
| Sections in containers | Group form sections within visible containers |
| Section container style | Style of the section containers: Filled or Outlined |
| Input field style | Style of the input fields: Filled or Outlined |
| Corner radius | Rounded corner radius of UI elements (px) |
| Border weight | Width of borders on form elements (pt) |
Colours
Customise the colour scheme of the widget:
| Setting | Description |
|---|---|
| Darkmode | Switch the widget to a dark colour theme |
| Brand colour | Primary brand colour used for highlights and accents |
| Component colour | Colour applied to widget components |
| Container fill colour | Background fill colour of containers |
Buttons
Choose a preset button style, or customise individual properties:
| Style | Description |
|---|---|
| Default | Standard button style |
| Soft | Softer, less prominent button appearance |
| Rounded | Fully rounded button edges |
| Sharp | Sharp-cornered button style |
| Custom | Set all button properties manually |
Customisable button properties:
| Property | Description |
|---|---|
| Button style | Visual style of the button: Filled or Outlined |
| Button size | Size of the button: Large or Small |
| Corner radius | Rounded corner radius of the button (px) |
| Button copy | Text displayed on the checkout button. Select from available types:
|
| Text colour | Colour of the button text |
Additional modules
Manage the additional modules displayed on Revolut Checkout.

Other modules
Shipping address
Enable the Shipping address module to collect customer shipping addresses during standard checkout. When enabled, customers are prompted to enter their shipping address as part of the payment flow.
This module applies to standard checkout flows only. Express checkout payment methods (Revolut Pay, Apple Pay, Google Pay) handle shipping using the customer's saved address from their Revolut account or digital wallet — no manual entry is needed.
Revolut footer
Enable the Revolut footer to:
- Display terms and conditions links
- Show "Powered by Revolut" branding
- Build customer trust by showcasing secure payment processing
This module appears at the bottom of the checkout widget and communicates to customers that their payment is processed securely through Revolut's trusted infrastructure.
When to use:
- Building customer confidence in your payment process
- Meeting legal requirements for terms display
- Leveraging Revolut's brand recognition
Reward modules
Reward your customers
Enable Reward your customers to display a promotional checkbox offering rewards to new Revolut users:
- Customers who don't have a Revolut account see an offer to join
- Displays an incentive (up to 5% conversion boost via Revolut Rewards)
- Encourages customer registration after purchase
This module can increase customer conversion rates by providing additional value for completing the purchase.
When to use:
- You want to increase conversion rates
- You're targeting customers who may not be Revolut users yet
- You want to provide extra incentives during checkout
Earn Rewards with the Revolut Merchant Affiliate Program
Enrol in the Revolut Merchant Affiliate Program to earn rewards for every new eligible Revolut customer who signs up using your rewards banner. Once enrolled, a sign-up prompt is displayed to eligible customers in the checkout widget.
Click Sign up now to enrol in the affiliate programme.
Changes to payment methods, appearance, and modules take effect immediately after you save them. The widget will reflect your customisation the next time it loads, without requiring any code changes.
Enable Express checkout
After enabling Express checkout payment methods in your dashboard, complete the backend and client-side setup for each method:
- Revolut Pay — requires a server-side address validation webhook.
- Apple Pay and Google Pay — require client-side shipping callbacks.
Revolut Pay
Your backend must handle shipping address validation requests from Revolut Pay. Follow steps 1 and 2 of the Fast checkout guide:
Step 3 of the Fast checkout guide (initialising the standalone Revolut Pay widget with requestShipping) does not apply here — the Revolut Checkout widget manages Revolut Pay internally.
Apple Pay and Google Pay
Add the following parameters to your embeddedCheckout() configuration:
| Parameter | Description | Required |
|---|---|---|
shippingOptions | Initial array of available shipping options to display when the widget loads | Yes |
onShippingAddressChange | Callback triggered when the customer changes their shipping address. Validate the address and return updated shipping options and order total | Yes |
onShippingOptionChange | Callback triggered when the customer selects a shipping option. Return the updated order total | Yes |
Example:
import RevolutCheckout from '@revolut/checkout'
const shippingOptions = [
{
id: 'standard',
label: 'Standard shipping',
amount: 500,
description: '3-5 business days'
},
{
id: 'express',
label: 'Express shipping',
amount: 1500,
description: '1-2 business days'
}
]
const { destroy } = await RevolutCheckout.embeddedCheckout({
publicToken: '<yourPublicApiKey>',
mode: 'prod',
target: document.getElementById('checkout-container'),
createOrder: async () => {
const order = await yourServerSideCall()
return { publicId: order.token }
},
shippingOptions,
onShippingAddressChange: async (address) => {
// Validate the address against your backend or shipping partner
const isValidAddress = await validateAddress(address)
if (!isValidAddress) {
return { status: 'fail', total: { amount: 5000 } }
}
return {
status: 'success',
shippingOptions,
total: { amount: 5000 + shippingOptions[0].amount }
}
},
onShippingOptionChange: async (selectedOption) => {
return {
status: 'success',
total: { amount: 5000 + selectedOption.amount }
}
},
onSuccess({ orderId }) {
window.location.href = `/confirmation?orderId=${orderId}`
}
})
For the full parameter reference, see: SDK reference: Embedded checkout.
Examples
The examples below assume you added the DOM container to your webpage where you want to render the checkout widget:
<...>
<div id='checkout-container'></div>
<...>
Example with and without async/await
import RevolutCheckout from '@revolut/checkout'
// Initialise and mount the embedded checkout
const { destroy } = await RevolutCheckout.embeddedCheckout({
publicToken: '<yourPublicApiKey>',
mode: 'prod',
locale: 'en', // Optional, defaults to 'auto'
target: document.getElementById('checkout-container'),
createOrder: async () => {
// Call your backend here to create an order
// For more information, see: https://developer.revolut.com/docs/merchant/create-order
const order = await yourServerSideCall()
return { publicId: order.token }
},
onSuccess() {
// Handle successful payments
console.log('Payment successful!')
// Redirect to success page or show success message
},
onError(error) {
// Handle payment errors
console.error('Payment failed:', error)
// Show error message to user
},
onCancel() {
// Handle cancelled payments
console.log('Payment was cancelled by user')
// Re-enable checkout or show cancellation message
}
})
Implementation checklist
Before deploying your implementation to your production environment, complete the checklist below to ensure everything works as expected, using the Merchant API's Sandbox environment.
To test in the Sandbox environment:
- Set the base URL of your API calls to
https://sandbox-merchant.revolut.com - Set the
modeparameter to'sandbox'when callingRevolutCheckout.embeddedCheckout()
Apple Pay and Pay by Bank are not available in the Sandbox environment. These payment methods can only be tested in the production environment.
General checks
- Checkout widget renders correctly in the intended DOM element.
- Your backend creates the order successfully when the checkout loads.
- The
redirect_urlparameter is configured when creating orders. - Order
tokenis successfully fetched and passed to the widget. - If Apple Pay is enabled, register your domain for Apple Pay.
- All enabled payment methods appear in the widget (based on your Business Dashboard configuration).
- Customisations are displayed correctly (payment method order, additional modules like Revolut footer or reward banners).
- Checkout completes successfully with test cards for successful payment.
- Payment success callback (
onSuccess) is triggered as expected. - Payment error callback (
onError) is triggered for failed payments. - Payment cancellation callback (
onCancel) is triggered when user cancels. - Checkout handles errors gracefully:
- Failed payments with test cards for error cases.
- Network errors are handled appropriately.
- (If Revolut Pay Express checkout is enabled) Address validation webhook is registered and responds within SLA (1s connection timeout, 5s socket timeout).
- (If Apple Pay or Google Pay Express checkout is enabled) Shipping callbacks (
onShippingAddressChange,onShippingOptionChange) are configured and tested end-to-end.
Webhook verification
- Webhook endpoint is set up to receive order and payment updates.
- Your backend only fulfils orders after receiving the appropriate webhook confirmation (e.g.,
ORDER_COMPLETED). - Webhook signature verification is implemented for security.
Browser compatibility
- Checkout works correctly on major browsers (Chrome, Firefox, Safari, Edge).
- Checkout is responsive and works on different screen sizes.
- Mobile experience is tested on iOS and Android devices.
If your implementation handles all these cases as expected in Sandbox, test your implementation in production before going live. Once your implementation passes all the checks in both environments, you can safely deploy to production.
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 implemented Revolut Checkout and are ready to accept payments.