Guides • Accept Payments
Web
doc

Accept payments via Revolut Pay - Web

Welcome to the implementation guide for Revolut Pay on web! This page provides a comprehensive walkthrough for integrating Revolut Pay into your websites.

Integration paths

Merchants have multiple options to integrate Revolut Pay, either using the event listening function of the widget, using event listening with mobile redirect URLs, or using redirect URLs. The main difference between the options is how the widget handles different results of the payment flow (success, failure, cancel):

The following sections list some aspects of each option merchants should take into consideration.

When to implement Revolut Pay with event listening

  • You work with a modern tech stack
  • Your implementation requires more flexibility
  • You have a single-page application, so redirects are not required

When to implement Revolut Pay with event listening and mobile redirect URLs

  • You maintain a stateful checkout page and users see it in a different state when they are redirected after payment
  • Your checkout page does not initialise Revolut Pay immediately when opened
  • You have multiple payment methods available on your checkout page, and initialising Revolut Pay is not guaranteed when a user is redirected after a payment event

When to implement Revolut Pay with redirect URLs

  • You have limited technical resources
  • You use an older tech stack
  • You have a multi-page application
  • You need to redirect customers to a new page upon payment

Implement Revolut Pay

Check the following high-level procedure to implement Revolut Pay on your website:

  1. Initialize Revolut Pay client SDK
  2. Configure Revolut Pay button
  3. Mount Revolut Pay button
  4. Listen to relevant events (skip if implementing with redirect URLs)

The following sections describe each step in detail, to see working examples you can skip ahead.

0. Before you start

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

1. Initialize Revolut Pay client SDK

caution

Make sure you're on the latest version of the @revolut/checkout library: v1.1.4+

import RevolutCheckout from '@revolut/checkout'

const { revolutPay } = await RevolutCheckout.payments({
locale: 'en' ,// Optional, defaults to 'auto'
mode: 'sandbox', // Optional, defaults to 'prod'
publicToken: '<yourPublicApiKey>', // Merchant public API key
})

2. Configure Revolut Pay button

Before mounting the Revolut Pay button, configure the Revolut Pay object's parameters.

For a more detailed reference of the Revolut Pay options and button styling, see: Payments.revolutPay reference and Revolut Pay button guidelines.

const paymentOptions = {
currency: 'USD', // 3-letter currency code
totalAmount: number, // in lowest denomination e.g., cents

// If you wish to implement Revolut Pay with event listening and mobile redirect URLs (skip this option if you only listen to events or only use redirect URLs):
mobileRedirectUrls: {
success: 'https://www.example.com/success',
failure: 'https://www.example.com/failure',
cancel: 'https://www.example.com/cancel'
},

// If you wish to implement Revolut Pay with redirect URLs (skip this option if you listen to events):
redirectUrls: {
success: 'https://www.example.com/success',
failure: 'https://www.example.com/failure',
cancel: 'https://www.example.com/cancel'
},

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

// You can put other optional parameters here
}

On your frontend, replace yourServerSideCall() from the example with a function you defined to call your backend/server. The role of this function is to pass the order details (e.g., amount, currency, billing_address, etc.) from the frontend to your backend.

When your backend received the order details, it needs to send them as the payload of a request to the Merchant API: Create an order endpoint. The backend will receive the token in the response.

You need to send the token back to your frontend and pass it to our widget. The token is required for initialising a new checkout session on the Revolut Pay widget.

caution

The Create an order endpoint was updated to a new version and now returns token as the public identifier for the order. Previous integrations might still use the deprecated endpoint returning public_id.

We strongly advise upgrading to the new Create an order endpoint.

Merchant initiated transactions

Pass the savePaymentMethodForMerchant parameter as true in order to save your customer's payment details during checkout. Customers are able to save both their Revolut account and card details via Revolut Pay.

This way, your customers can grant permission for you to initiate payments on their saved payment method stored by Revolut Pay, without any further action required from the customer. Use this feature to initiate recurring payments, e.g., to take payments for a subscription or to charge a customer later for a specific order.

By default, merchant initiated transactions are disabled.

To learn more about how to save and charge a customer's payment method, see: Charge a customer's saved payment method.

Fast checkout

If you want the shipping address and delivery method to be quickly collected from the user through Revolut Pay, pass the requestShipping parameter as true.

This way, your app can skip the shipping flow during checkout and the user can use existing shipping details stored by Revolut Pay.

By default, Fast checkout is not enabled.

caution

Your backend must support Fast checkout for this functionality to work. For more information, see: Implement Revolut Pay with Fast checkout.

3. Mount Revolut Pay button

Mount the Revolut Pay button with the following line:

revolutPay.mount(target, paymentOptions)
ParameterDescription
targetCan be either a DOM node e.g., document.getElementById("kiwi") or a CSS selector e.g., "#kiwi".
paymentOptionsRefers to the payment options describing the payment being initiated. For more information, see: Payments.revolutPay: Mount options.

4. Listen to relevant events

note

Completing this step is only needed, when implementing Revolut Pay with event listening.

To listen to relevant events during the payment flow, use the following code:

revolutPay.on('payment', (event) => {
// ... do something e.g., perform redirect
})

For more information about listening to payment events, see: Payments.revolutPay: Listen to events.

For more information about the createOrder operation, see: Merchant API reference: Create an order.

The order must be created on the server side. The client SDK will only receive the publicId of the created order.

In the following section, you can find a working example of the Revolut Pay button.

Examples

Example with minimal required values (with event listening)

Insert the Revolut Pay button using the code snippet below that contains an example with minimum required parameters, where:

  • RevolutCheckout is the widget instance.
  • <yourPublicApiKey> is your Merchant Public API Key.
  • order.token is returned when the createOrder operation runs. For more information, see the following section of the Merchant API reference: Create an order.
  • event.type is returned after a payment is triggered, defines the state of the payment. For more information, see: Payments.revolutPay: Listen to events.

Insert the following DOM element into your webpage where you want to render the Revolut Pay button, and pass the id of this element as the first argument of the .mount statement:

your-page.html
...
<div id='revolut-pay'></div>
...
your-page.js
import RevolutCheckout from '@revolut/checkout'

const { revolutPay } = await RevolutCheckout.payments({
publicToken: '<yourPublicApiKey>' // Merchant public API key
})

const paymentOptions = {
currency: 'USD',
totalAmount: 1000,

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

// You can put other optional parameters here
}

revolutPay.mount(document.getElementById('revolut-pay'), paymentOptions)

revolutPay.on('payment', (event) => {
switch (event.type) {
case 'cancel': {
if (event.dropOffState === 'payment_summary') {
log('what a shame, please complete your payment')
}
break
}

case 'success':
onSuccess()
break

case 'error':
onError(event.error)
break
}
})

Example with minimal required values (with event listening and mobile redirect URLs)

your-page.js
import RevolutCheckout from '@revolut/checkout'

const { revolutPay } = await RevolutCheckout.payments({
publicToken: '<yourPublicAPIKey>' // Merchant public API key
})

const paymentOptions = {
currency: 'USD', // 3-letter currency code
totalAmount: 1000, // In lowest denomination e.g., cents
mobileRedirectUrls: {
success: 'https://www.example.com/success',
failure: 'https://www.example.com/failure',
cancel: 'https://www.example.com/cancel'
},

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

// You can put other optional parameters here
}

revolutPay.mount(document.getElementById('revolut-pay'), paymentOptions)

revolutPay.on('payment', (event) => {
switch (event.type) {
case 'cancel': {
if (event.dropOffState === 'payment_summary') {
log('what a shame, please complete your payment')
}
break
}

case 'success':
onSuccess()
break

case 'error':
onError(event.error)
break
}
})

Example with minimal required values (with redirect URLs)

your-page.js

import RevolutCheckout from '@revolut/checkout'

const { revolutPay } = await RevolutCheckout.payments({
publicToken: '<yourPublicApiKey>' // merchant public API key
})

const paymentOptions = {
currency: 'USD',
totalAmount: 1000,
redirectUrls: {
success: 'https://www.example.com/success',
failure: 'https://www.example.com/failure',
cancel: 'https://www.example.com/cancel'
},

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

// You can put other optional parameters here
}

revolutPay.mount(document.getElementById('revolut-pay'), paymentOptions)

This is what the button looks like:

Revolut Pay button

Implementation checklist

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

As Revolut Pay has more complex user flows compared to other payment methods, the following user journey paths needs to be tested (besides general tests):

To see if your implementation is able to manage all flows, check each flow against the checks below.

Desktop flow

This is the least complex of user flows. Steps are the following:

  1. User clicks Revolut Pay button on merchant's site.
  2. User journey is completed in a popup.
  3. Payment completed or failed, respective message is shown to customer.

Mobile flow (without Revolut app installed)

This user flow represents the case where the Revolut app is not installed on the customer's phone:

  1. User clicks Revolut Pay button on merchant's site using their mobile browser.
  2. Client SDK attempts to open the Revolut app.
  3. If it is not installed, user is redirected to a standalone page where the payment flow continues.
  4. Payment completed or failed, the customer should be redirected to the merchant site and respective message is shown to customer.
tip

You can test this flow with your browser's built-in mobile browser simulator. Available via the browser's developer tools.

Mobile flow (with Revolut app installed)

This user flow represent the case, where the Revolut app is installed on the customer's phone:

  1. User clicks Revolut Pay button on merchant's site, on his mobile browser.
  2. Client SDK attempts to open the Revolut app.
  3. If it is installed, Revolut app is opened where the payment flow continues.
  4. Payment completed or failed, Revolut app attempts to redirect user to the same browser where the flow started.
    caution

    Only Google Chrome, Safari, Samsung Internet Browser, Firefox, and Opera are supported. If the user begins on any other browser, successful redirection to the same browser is not guaranteed. The user will be redirected to their default mobile browser.

  5. A self-closing page is opened, user arrives at the tab where the flow started.

General checks

  • Revolut Pay button is rendered at the intended DOM element.
  • Your backend creates the order successfully when clicking the button.
  • Order token is successfully fetched.
  • Checkout is successful with test cards for successful payment.
  • Checkout errors are handled as expected by your application.

New customer

  • Customer is created in the Merchant API upon completing checkout.
  • Customer details (email, payment methods, shipping details) saved in the Merchant API.
  • On next checkout customer is already logged in.

Existing customer

  • After first login, customer is already logged in on next checkout.
  • Existing customer has their details returned.
  • New payment method is saved to customer successfully.
  • Shipping details are returned/saved to the customer successfully.

Event listening

If you implemented Revolut Pay with event listening:

  • All payment events are listened to.
  • Payment events trigger expected behavior on your backend.

Event listening with mobile redirect URLs

If you implemented Revolut Pay with event listening and mobile redirect URLs:

  • All payment events are listened to, when payment was made on desktop.
  • Payment events trigger expected behavior on your backend.
  • Redirect pages are always opened on mobile.
  • Success or failure messaging work on your redirect pages on mobile.

Redirect URLs

If you implemented Revolut Pay with redirect URLs:

  • Redirect pages are always opened, both on desktop and mobile.
  • Success or failure messaging work on your redirect pages, both on desktop and mobile.

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.

success

Congratulations! You've successfully implemented Revolut Pay and are ready to accept the first payment.

What's next

Was this page helpful?