# Test payment flows

This page covers client-side **payment method checkout flows** - the customer experience at checkout - in the Sandbox environment. Some flows use Sandbox-specific UX that differs from production; each section explains what to expect.

:::info
This page covers test flows for Revolut Pay and Google Pay. Further test flows will be added as they become available.
:::

## Revolut Pay

Revolut Pay involves a more complex testing scenario due to its connection with our account-to-account (A2A) payment system. This section explains the process and details of the **mock sign-up** feature, which simulates a new Revolut Retail account creation in the checkout flow of Revolut Pay. This is required for testing A2A payment flows.

:::info
The UX in the Sandbox environment is different from the production flow. **There is no Sandbox version of the Revolut retail app**, which means that certain interactions are simulated differently. Ensure you account for these differences when testing.
:::

- **Mock sign-up feature:**  
  As the Revolut Retail app is not available in Sandbox, a simulated sign-up process needs to be completed. Once the mock account is created, you can use it to test account-to-account transactions and store our test cards for future use.
- **Revolut Pay A2A in Sandbox:**  
  The flow includes an initial card payment that triggers the mock sign-up, creating a new, simulated Revolut Retail account necessary for subsequent A2A transactions.

### Mock sign-up flow

:::info
This guide will use our [Hosted Checkout Page implementation](/docs/guides/merchant/accept-payments/online-payments/hosted-checkout-page/introduction), but will work with every Revolut Pay integration.
:::

1. Initiate a payment via **Revolut Pay** on your checkout page.
1. Select **`Checkout as a guest`**.
1. Enter the details of one of our [test cards for successful payments](/docs/guides/merchant/test-and-go-live/testing/test-cards#test-for-successful-payments) (with any CVV and future expiry date).
1. Provide any random user details (first name, last name, email).
1. Enable saving card information and click **`Save card and pay ...`**.
1. In the pop-up, provide a random phone number that hasn't been used in the Sandbox before, then click **`Send verification code`**. Save this phone number for testing the account-to-account (A2A) payment flow.

   :::info
   If you enter a phone number that's already registered with a mock retail account, you can either use it for testing the account-to-account flow or try again with a new number to simulate the mock sign-up process.
   :::

1. Click **Fill with ...** in the top-right corner to autofill the mock OTP (one-time password).
1. Upon successful payment, you are redirected to the confirmation page.

![Mock sign up](/img/accept-payments/get-started/revolut-pay-mock-sign-up.mov)

### Account-to-account payment flow

Your mock account is created with the credentials provided once your initial payment is successful. To test account-to-account (A2A) transactions using the same simulated credentials, follow these steps:

1. Initiate a new payment via **Revolut Pay** on your checkout page.
1. Complete the sign-in steps:
   1. Enter the phone number used during the mock sign-up and click **`Continue`**.
   1. When prompted, enter passcode: `124455`.
   1. Click **Autofill code ...** in the top-right corner to pass the OTP challenge.

1. On the payment verification screen, confirm that the **Revolut account** is selected by default in the **Pay with** section.
   - _(Optional)_ If you need to change the payment method, you can select a different option in the **Pay with** section.
1. Click **`Pay ...`** to proceed.
1. If additional verification is needed, click **Approve** in the top-right corner to pass the verification.

   :::info
   In production, customers complete the challenge through the Revolut retail app (if installed) or via a webview. In the Sandbox environment, this step is simulated by the **Approve**/**Decline** buttons on the verification screen.
   :::

Following these steps will complete the A2A payment flow, allowing you to fully test the account-to-account transaction process using your previously created mock account.

![a2a flow](/img/accept-payments/get-started/revolut-pay-a2a-flow.mov)

### Test for A2A error cases

When [creating an order](/docs/api/merchant#create-order) to test A2A payment error handling, use the following specific order **amounts** in minor currency units for `GBP` (for example, to test `10.01 GBP`, use `amount: 1001`). Pass the exact amount when you create the order so that the Sandbox environment simulates the corresponding error scenario.

| Order amount         | Case                                                                                                                                                                                                                                                               | Decline reason                                  | Payment state |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | ------------- |
| `1001` (`10.01 GBP`) | Payment declined without a reason.                                                                                                                                                                                                                                 | No `decline_reason` returned on payment details | `declined`    |
| `1002` (`10.02 GBP`) | Payment declined due to insufficient funds.                                                                                                                                                                                                                        | `insufficient_funds`                            | `declined`    |
| `1003` (`10.03 GBP`) | Payment declined due to suspected fraud.                                                                                                                                                                                                                           | `suspected_fraud`                               | `declined`    |
| `1004` (`10.04 GBP`) | Payment declined due to exceeded withdrawal limit.                                                                                                                                                                                                                 | `withdrawal_limit_exceeded`                     | `declined`    |
| `1005` (`10.05 GBP`) | Payment declined due to Do Not Honour. <br/><br/> This error happens when your customer's bank declines the transaction due to internal reasons. For example, their fraud rules might have been triggered, or a temporary hold may have been applied to this card. | `do_not_honour`                                 | `declined`    |

You can verify the returned `payment.state` and `decline_reason` by [retrieving the order details](/docs/api/merchant#retrieve-order).

:::tip
When testing A2A payment errors using [our plugins](/docs/guides/merchant/accept-payments/no-code/plugins/introduction), ensure you've created products (or set product prices) that exactly match the order amounts listed in this section. This allows the plugin to send the correct amount to trigger each error scenario.
:::

## Google Pay

Google Pay payments can be tested in the Sandbox environment using the [Merchant API](/docs/api/merchant). Unlike production, where real Google Pay tokens are used, the Sandbox environment allows you to simulate different payment outcomes by using specific order amounts.

When testing Google Pay, use one of our [test cards for successful payments](/docs/guides/merchant/test-and-go-live/testing/test-cards#test-for-successful-payments) as the underlying card in Google Pay. The test outcomes in this section are controlled by the **order amount**, so using a successful test card helps avoid unrelated card declines.

:::info
Google Pay testing applies to all integration methods, including:

- [Apple Pay and Google Pay via Web SDK](/docs/guides/merchant/accept-payments/online-payments/apple-pay-google-pay/web)
- [Revolut Checkout with Google Pay](/docs/sdks/merchant-web-sdk/introduction)
- [Direct Google Pay integration for Android](/docs/guides/merchant/accept-payments/online-payments/apple-pay-google-pay/introduction)

:::

### Test for different payment outcomes

When [creating an order](/docs/api/merchant#create-order) to test Google Pay payment scenarios, use the following specific order **amounts** in minor currency units (for example, to test `35.00`, use `amount: 3500`). Pass the exact amount when you create the order so that the Sandbox environment simulates the corresponding payment outcome.

| Order amount                                         | Case                                                    | Decline reason            | Payment state                                    |
| ---------------------------------------------------- | ------------------------------------------------------- | ------------------------- | ------------------------------------------------ |
| `3500` (`35.00`), or `20000-22999` (`200.00-229.99`) | Payment declined due to insufficient funds              | `insufficient_funds`      | `declined`                                       |
| `4000` (`40.00`), or `23000-24999` (`230.00-249.99`) | Payment declined because the transaction is not allowed | `transaction_not_allowed` | `declined`                                       |
| `25000-26999` (`250.00-269.99`)                      | Payment declined due to suspected fraud                 | `suspected_fraud`         | `declined`                                       |
| Other amounts                                        | Payment successful                                      | N/A                       | `completed` (or `authorised` for manual capture) |

You can verify the returned `payment.state` and `decline_reason` by [retrieving the order details](/docs/api/merchant#retrieve-order) or [retrieving the payment details](/docs/api/merchant#retrieve-payment-details).

:::tip
When testing Google Pay with [our plugins](/docs/guides/merchant/accept-payments/no-code/plugins/introduction), ensure you've created products (or set product prices) that exactly match the order amounts listed in this section. This allows the plugin to send the correct amount to trigger each scenario.
:::