# Charge a customer's saved payment method

In this tutorial you can learn how to save and charge your customer's payment methods using the Revolut Checkout Widget. To do that, you have to:

1. [Save a customer's payment details](#1-save-a-customers-payment-details)
1. [Charge the customer's saved payment method](#2-charge-the-saved-payment-method)

#### Customer and merchant initiated payments

Familiarizing yourself with this process can be helpful to take advantage of saved payment methods. There are two types of payments:

- **Customer initiated payments:** These are useful to improve your customer experience. Your customers can save their card details and choose from saved payment methods on their future checkouts without providing their card details again. For more information, see: [Save cards and speed up checkout](/docs/guides/merchant/optimise-checkout/save-payment-methods/checkout-with-saved-card).
- **Merchant initiated payments:** These payments are useful to manage subscriptions. Your customers can save their card details, and you can initiate recurring payments on that card. For more information, see: [Manage subscriptions](/docs/guides/merchant/optimise-checkout/save-payment-methods/subscription-management).

## 1. Save a customer's payment details

To save a customer's payment details using any of the available payment methods, you need to meet one of the following requirements:

- Have a customer object with `email` and assign it to the order by providing `customer.id`
- Create a new customer with, at least, `customer.email` during [order creation](/docs/api/merchant#create-order)

There are two approaches to save the payment details of a customer:

::::details [Create a customer first]

Use this approach when your customer already has an account on your site at checkout. The payment method is attached to the customer after the payment is made.

1. Create a [`customer`](/docs/api/merchant#create-customer) and save the `id` of the `customer` object in the response.

   :::warning
   To save a customer's payment details, at least the `email` is required during customer creation.
   :::

1. Create an [`order`](/docs/api/merchant#create-order) with the `amount`, `currency`, and `customer.id` parameters in the request body.
1. Initialise the Revolut Checkout Widget with the `savePaymentMethodFor` parameter set to either `customer` or `merchant`. If you want to use Revolut Pay, initialise the widget by passing the `savePaymentMethodForMerchant` parameter as `true`.

    - ![Card field]

      See an example with the [Card field](/docs/sdks/merchant-web-sdk/payment-methods/card-field):

      - ![Production]

        ```js {16}
        RevolutCheckout("<token>").then(function (instance) {
          var card = instance.createCardField({
            target: document.getElementById("card-field"),
            onSuccess() {
              window.alert("Payment was successful. Thank you!");
            },
            onError(message) {
              window.alert("Something went wrong.");
            },
          });

          document
            .getElementById("button-submit")
            .addEventListener("click", function () {
              card.submit({
                savePaymentMethodFor: "merchant"
              });
            });
        });
        ```

      - ![Sandbox]

        ```js {16}
        RevolutCheckout("<token>", "sandbox").then(function (instance) {
          var card = instance.createCardField({
            target: document.getElementById("card-field"),
            onSuccess() {
              window.alert("Payment was successful. Thank you!");
            },
            onError(message) {
              window.alert("Something went wrong.");
            },
          });

          document
            .getElementById("button-submit")
            .addEventListener("click", function () {
              card.submit({
                savePaymentMethodFor: "merchant"
              });
            });
        });
        ```

      :::info
      You can also use the [Card pop-up](/docs/sdks/merchant-web-sdk/payment-methods/pop-up) of the Revolut Checkout Widget to save a customer's payment method.
      :::

    - ![Revolut Pay - Web]

      See an example of the [Revolut Pay](/docs/sdks/merchant-web-sdk/payment-methods/revolut-pay):
      - ![Production]

        ```js {12}
        import RevolutCheckout from '@revolut/checkout'

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

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

          // Put other parameters here
        }

        revolutPay.mount(target, paymentOptions)
        ```

      - ![Sandbox]

        ```js {12}
        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
        })

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

          // Put other parameters here
        }

        revolutPay.mount(target, paymentOptions)
        ```

      :::warning
      The example above is not complete, it is intended to demonstrate the `savePaymentMethodForMerchant` parameter. To see the full implementation process, visit: [Accept payments via Revolut Pay - Web](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web).
      :::

      By initialising the Revolut Pay widget with the `savePaymentMethodForMerchant` option customers can grant permission to the merchant to initiate transactions without further action required from the customer. Customers are able to save both their Revolut account and card details via Revolut Pay.

      For more information about configuring and mounting the Revolut Pay widget, see: [Configure Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web#2-configure-revolut-pay-button) and [Mount Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web#3-mount-revolut-pay-button).

      :::info
      Only merchant initiated transactions are supported with Revolut Pay on the [Pay for an order](/docs/api/merchant#pay-order) endpoint.
      :::

    - ![Revolut Pay - iOS]

      See an example of the [`RevolutPayKit` for iOS](/docs/sdks/merchant-ios-sdk/revolut-pay-ios-sdk/methods-parameters):
      - ![Production]

        ```swift {15}
        import RevolutPayments

        RevolutPayKit.configure(
            with: .init(
                merchantPublicKey: "<yourPublicAPIKey>",
                environment: .production
            )
        )

        let revolutPayKit = RevolutPayKit()

        let button = revolutPayKit.button(
            style: .init(),
            returnURL: "myapp://revolut-pay",
            savePaymentMethodForMerchant: true,
            createOrder: { createOrderHandler in
                createOrderOnBackEnd { orderToken in
                    createOrderHandler.set(orderToken: orderToken)
                }
            },
            completion: { result in
                switch result {
                    case .success:
                        // Handle success
                    case .failure(let error):
                        // Handle failure
                }
            }
        )
        ```

      - ![Sandbox]

        ```swift {15}
        import RevolutPayments

        RevolutPayKit.configure(
            with: .init(
                merchantPublicKey: "<yourPublicAPIKey>",
                environment: .sandbox
            )
        )

        let revolutPayKit = RevolutPayKit()

        let button = revolutPayKit.button(
            style: .init(),
            returnURL: "myapp://revolut-pay",
            savePaymentMethodForMerchant: true,
            createOrder: { createOrderHandler in
                createOrderOnBackEnd { orderToken in
                    createOrderHandler.set(orderToken: orderToken)
                }
            },
            completion: { result in
                switch result {
                    case .success:
                        // Handle success
                    case .failure(let error):
                        // Handle failure
                }
            }
        )
        ```

      :::warning
      The example above is not complete, it is intended to demonstrate the `savePaymentMethodForMerchant` parameter. To see the full implementation process, visit: [Implement Revolut Pay - iOS](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios).
      :::

      By initialising the Revolut Pay widget with the `savePaymentMethodForMerchant` option customers can grant permission to the merchant to initiate transactions without further action required from the customer. Customers are able to save both their Revolut account and card details via Revolut Pay.

      For more information about configuring and displaying the Revolut Pay button, see: [Create Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios#4-create-revolut-pay-button) and [Display Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios#5-display-revolut-pay-button).

      :::info
      Only merchant initiated transactions are supported with Revolut Pay on the [Pay for an order](/docs/api/merchant#pay-order) endpoint.
      :::

1. Make the payment via the widget.
1. The payment method is created and attached to the customer. To check a customer's saved payment methods, use the: [Merchant API: Retrieve payment method list of a customer](/docs/api/merchant#retrieve-payment-method-list) endpoint.

::::

::::details [Create an order first]

Use this approach when your customer starts the checkout as a guest user on your site. The payment method is attached to the customer after the payment is made.

1. Create an [`order`](/docs/api/merchant#create-order) with the `amount`, `currency`, and at least one of the following:
   - `customer.email`, or
   - `customer.phone`, or
   - `customer.full_name` parameters.

   As a general best practice, it's recommended to additionally provide any further information you have (`email`, `phone`, `full_name`) when you wish to create a new `customer` object.

   Unless you provide `customer.id` at order creation, we always create a new customer, irrespective of another, existing customer having the same details (`email`, `phone`, `full_name`).

   :::warning
   To save a customer's payment details, either `customer.id` (with `email` present on customer object) or `customer.email` is required during order creation.
   :::

1. Initialise the widget with `savePaymentMethodFor` parameter set to either `customer` or `merchant`. If you want to use Revolut Pay, initialise the widget by passing the `savePaymentMethodForMerchant` parameter as `true`.

    - ![Card field]

      See an example with the [Card field](/docs/sdks/merchant-web-sdk/payment-methods/card-field):

      - ![Production]

        ```js {16}
        RevolutCheckout("<token>").then(function (instance) {
          var card = instance.createCardField({
            target: document.getElementById("card-field"),
            onSuccess() {
              window.alert("Payment was successful. Thank you!");
            },
            onError(message) {
              window.alert("Something went wrong.");
            },
          });

          document
            .getElementById("button-submit")
            .addEventListener("click", function () {
              card.submit({
                savePaymentMethodFor: "merchant"
              });
            });
        });
        ```

      - ![Sandbox]

        ```js {16}
        RevolutCheckout("<token>", "sandbox").then(function (instance) {
          var card = instance.createCardField({
            target: document.getElementById("card-field"),
            onSuccess() {
              window.alert("Payment was successful. Thank you!");
            },
            onError(message) {
              window.alert("Something went wrong.");
            },
          });

          document
            .getElementById("button-submit")
            .addEventListener("click", function () {
              card.submit({
                savePaymentMethodFor: "merchant"
              });
            });
        });
        ```

      :::info
      You can also use the [Card pop-up](/docs/sdks/merchant-web-sdk/payment-methods/pop-up) of the Revolut Checkout Widget to save a customer's payment method.
      :::

    - ![Revolut Pay - Web]

      See an example of the [Revolut Pay](/docs/sdks/merchant-web-sdk/payment-methods/revolut-pay):
      - ![Production]

        ```js {12}
        import RevolutCheckout from '@revolut/checkout'

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

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

          // Put other parameters here
        }

        revolutPay.mount(target, paymentOptions)
        ```

      - ![Sandbox]

        ```js {12}
        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
        })

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

          // Put other parameters here
        }

        revolutPay.mount(target, paymentOptions)
        ```

      :::warning
      The example above is not complete, it is intended to demonstrate the `savePaymentMethodForMerchant` parameter. To see the full implementation process, visit: [Accept payments via Revolut Pay - Web](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web).
      :::

      By initialising the Revolut Pay widget with the `savePaymentMethodForMerchant` option customers can grant permission to the merchant to initiate transactions without further action required from the customer. Customers are able to save both their Revolut account and card details via Revolut Pay.

      For more information about configuring and mounting the Revolut Pay widget, see: [Configure Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web#2-configure-revolut-pay-button) and [Mount Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/web#3-mount-revolut-pay-button).

      :::info
      Only merchant initiated transactions are supported with Revolut Pay on the [Pay for an order](/docs/api/merchant#pay-order) endpoint.
      :::

    - ![Revolut Pay - iOS]

      See an example of the [`RevolutPayKit` for iOS](/docs/sdks/merchant-ios-sdk/revolut-pay-ios-sdk/methods-parameters):
      - ![Production]

        ```swift {15}
        import RevolutPayments

        RevolutPayKit.configure(
            with: .init(
                merchantPublicKey: "<yourPublicAPIKey>",
                environment: .production
            )
        )

        let revolutPayKit = RevolutPayKit()

        let button = revolutPayKit.button(
            style: .init(),
            returnURL: "myapp://revolut-pay",
            savePaymentMethodForMerchant: true,
            createOrder: { createOrderHandler in
                createOrderOnBackEnd { orderToken in
                    createOrderHandler.set(orderToken: orderToken)
                }
            },
            completion: { result in
                switch result {
                    case .success:
                        // Handle success
                    case .failure(let error):
                        // Handle failure
                }
            }
        )
        ```

      - ![Sandbox]

        ```swift {15}
        import RevolutPayments

        RevolutPayKit.configure(
            with: .init(
                merchantPublicKey: "<yourPublicAPIKey>",
                environment: .sandbox
            )
        )

        let revolutPayKit = RevolutPayKit()

        let button = revolutPayKit.button(
            style: .init(),
            returnURL: "myapp://revolut-pay",
            savePaymentMethodForMerchant: true,
            createOrder: { createOrderHandler in
                createOrderOnBackEnd { orderToken in
                    createOrderHandler.set(orderToken: orderToken)
                }
            },
            completion: { result in
                switch result {
                    case .success:
                        // Handle success
                    case .failure(let error):
                        // Handle failure
                }
            }
        )
        ```

      :::warning
      The example above is not complete, it is intended to demonstrate the `savePaymentMethodForMerchant` parameter. To see the full implementation process, visit: [Implement Revolut Pay - iOS](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios).
      :::

      By initialising the Revolut Pay widget with the `savePaymentMethodForMerchant` option customers can grant permission to the merchant to initiate transactions without further action required from the customer. Customers are able to save both their Revolut account and card details via Revolut Pay.

      For more information about configuring and displaying the Revolut Pay button, see: [Create Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios#4-create-revolut-pay-button) and [Display Revolut Pay button](/docs/guides/merchant/accept-payments/online-payments/revolut-pay/mobile/ios#5-display-revolut-pay-button).

      :::info
      Only merchant initiated transactions are supported with Revolut Pay on the [Pay for an order](/docs/api/merchant#pay-order) endpoint.
      :::

1. Make the payment via the widget.
1. When the payment is successful, a [`customer`](/docs/api/merchant#create-customer) is created with the email.
1. The payment method is associated with the customer, and the `customer` object is attached to the order automatically. To check a customer's saved payment methods, use the: [Merchant API: Retrieve payment method list of a customer](/docs/api/merchant#retrieve-payment-method-list) endpoint.

::::

## 2. Charge the saved payment method

Once the customer is created and their payment method is saved, you can charge the payment method even when the customer is not on the checkout page. This can be useful for taking recurring payments.

You can also use this approach to provide a faster checkout experience for customers, for example, a 1-click buy flow.

To charge a customer's saved payment method, follow these steps:

1. [Create an order](/docs/api/merchant#create-order) with the `amount`, `currency` and `customer.id` parameters in the body of the request. Where the `customer.id` corresponds to a customer with a saved payment method.
1. Pay for the order using the [Merchant API: Pay for an order](/docs/api/merchant#pay-order) endpoint to initiate the payment using a customer's saved payment method.

Use the following JSON object as the payload of the request:

```json
{
  "saved_payment_method": {
    "type": "<type of the saved payment method>",
    "id": "<ID of the saved payment method>",
    "initiator": "<initiator of the payment>"
  }
}
```

To retrieve the required information, use the [Retrieve payment method list of a customer](/docs/api/merchant#retrieve-payment-method-list) endpoint or the customer object from [Step 1](#1-save-a-customers-card-details). Retrieve the payment method `id` and `type` from `customer.payment_methods[]`.

:::info
The customer-level `payment_methods[].type` field returns only two values: `card` and `revolut_pay`. Both the card-backed and account-to-account (A2A) variants of Revolut Pay are represented as `revolut_pay` at this level — sub-types are not differentiated. Use `revolut_pay` as the `type` when calling [Pay for an order](/docs/api/merchant#pay-order) with a saved Revolut Pay method.

For per-transaction sub-type details (`revolut_pay_card` / `revolut_pay_account`), refer to the order-level `payments[].payment_method.type` field instead — but do **not** use these granular types when referencing a saved payment method.
:::

The following table shows who can initiate payments on saved payment methods (`initiator` parameter in payment request), depending on if the payment method was saved for the customer or the merchant (`savedPaymentMethodFor` parameter in the widget configuration):

|                           | **`savePaymentMethodFor: customer`** | **`savePaymentMethodFor: merchant`** |
| ------------------------- | ------------------------------------ | ------------------------------------ |
| **`initiator: customer`** | Allowed                              | Allowed                              |
| **`initiator: merchant`** | Not allowed                          | Allowed                              |

:::info
Only merchant initiated transactions are supported with Revolut Pay on the [Pay for an order](/docs/api/merchant#pay-order) endpoint.
:::

1. If the payment is successfully captured, the following JSON is returned:

    - ![Successful payment via card]

      ```json
      {
        "id": "6407402d-cf34-ac35-9be4-f1448708811b",
        "order_id": "64073e7b-41af-a715-8a37-9d73cd01fa9f",
        "payment_method": {
          "type": "card",
          "id": "6513122e-877b-aa8d-9d26-4d1a805c7841",
          "brand": "mastercard_credit",
          "last_four": "1234"
        },
        "state": "captured"
      }
      ```

    - ![Successful payment via Revolut Pay]

      ```json
      {
        "id": "6487022d-b095-aeba-989c-196d8f0c6703",
        "order_id": "64870215-c3f1-adc2-9bec-6a4c63232fb9",
        "payment_method": {
          "type": "revolut_pay",
          "subtype": "revolut_account",
          "id": "649ab540-a509-aec0-a856-caca95e33ba2"
        },
        "state": "captured"
      }
      ```

1. You can handle captured payments as completed, it takes around 24 hours to settle payments on your Merchant Account.

:::tip
**Congratulations!** You've successfully charged one of your customer's saved payment methods.
:::

## What's next

- [Learn how to set up a 1-click checkout experience](/docs/guides/merchant/optimise-checkout/save-payment-methods/checkout-with-saved-card) using a customer's saved card
- [Learn how to manage subscriptions](/docs/guides/merchant/optimise-checkout/save-payment-methods/subscription-management) using a customer's saved card
- [Learn how to use webhooks](/docs/guides/merchant/monitor-and-observe/webhooks/using-webhooks) to track payment lifecycle
- [Learn more about the order and payment lifecycle](/docs/guides/merchant/reference/order-lifecycle)