# Stored payment instrument for Payment Setup API
A stored payment instrument is an existing, previously saved payment source, such as a saved card or bank account, that Checkout.com already holds on file for your customer. Use the `instrument` payment method to submit the ID of a stored payment instrument, instead of collecting the customer's payment details again.
To accept payments using a stored payment instrument, you must:
1. Create a payment setup.
2. Update the payment setup with the stored instrument's ID.
3. Verify payment authorization.
4. Confirm the payment.
---
## Create a payment setup
Call the [Create a payment setup](https://api-reference.checkout.com/tag/Payment-Setups/#operation/createAPaymentSetup) endpoint.
> **Information**
>
> The Payment Setup API supports [idempotency](https://www.checkout.com/docs/developer-resources/api/idempotency.md). You can safely retry API requests without the risk of duplicate requests.
> **Information**
>
> Your base URL's `{prefix}` value is unique to your account and environment. To learn how to retrieve your base URLs for the sandbox and production environments, see [API endpoints](https://www.checkout.com/docs/developer-resources/api/api-endpoints.md).
**Production**
`POST` `https://{prefix}.api.checkout.com/payments/setups`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/setups`
### Request example
```json
{
"processing_channel_id": "pc_wzjki6hw5puepb5fnvqlizj2e4",
"currency": "USD",
"amount": 2000,
"reference": "ORDER_01234",
"description": "Stored payment instrument payment",
"payment_type": "regular",
"settings": {
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
}
```
In the request body, provide the following:
- `processing_channel_id` – The [processing channel's](https://www.checkout.com/docs/business-operations/use-the-dashboard/manage-processing-channels.md) unique identifier
- `amount` – The payment amount
- `currency` – The payment currency
### Response example
```json
{
"id": "set_rcmepwrchqab2wsergcafvijfy",
"processing_channel_id": "pc_wzjki6hw5puepb5fnvqlizj2e4",
"amount": 2000,
"currency": "USD",
"payment_type": "regular",
"reference": "ORDER_01234",
"description": "Stored payment instrument payment",
"payment_methods": {
"instrument": {
"id": "src_wmlfc3zttb4uzmk6snpwb43jbi",
"status": "action_required",
"flags": [],
"action": {
"type": "set_instrument"
}
}
},
"available_payment_methods": [
"instrument"
],
"settings": {
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
}
```
The response returns a `payment_methods` object, which contains the payment methods enabled on your account.
For a stored payment instrument, `payment_methods` contains the following fields:
- `status` – The [status of the payment method](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-using-the-payment-setup-api.md#Payment_method_status).
- `flags` – An array of error codes or indicators that highlight missing or invalid information.
- `action` – Present when `status` is `action_required`. `action.type` is set to `set_instrument`, which indicates you must update the payment setup with the ID of a stored payment instrument before you can proceed.
---
## Update the payment setup
When the customer selects a stored payment instrument as the payment method, call the [Update a payment setup](https://api-reference.checkout.com/tag/Payment-Setups/#operation/updateAPaymentSetup) endpoint and provide the ID of the stored instrument.
Additionally, provide the following fields:
| Field | Description |
| --- | --- |
| `payment_methods.instrument.id`
`string` | The ID of the stored payment instrument to use for this payment setup.
**Required** |
When you submit the instrument `id`, we validate it and check that it supports the requested `payment_type`:
- Pending – If the instrument requires asynchronous validation, we add `instrument_pending` to `payment_methods.instrument.flags` and set `status` to `pending`. This currently applies only to Bacs instruments, which take about five days to validate, so do not poll the payment setup. For the first Bacs payment, use the Bacs payment method instead of a stored instrument. If you do receive a `pending` status, wait for the [Payment method ready](https://www.checkout.com/docs/developer-resources/event-notifications/event-types/payment_method_ready.md) webhook.
- Invalid – If the instrument `id` doesn't correspond to a valid, existing instrument, we add `instrument_invalid` to `payment_methods.instrument.flags` and set `status` to `invalid`. Ask your customer for a different payment method.
- Payment type mismatch – If the stored instrument doesn't support the requested `payment_type`, for example, a recurring-only instrument used for a regular payment, we add `payment_type_mismatch` to `payment_methods.instrument.flags` and set `status` to `invalid`. Ask your customer for a different payment method, or update the payment setup with a supported `payment_type`.
### Request example
```json
{
"processing_channel_id": "pc_wzjki6hw5puepb5fnvqlizj2e4",
"currency": "USD",
"amount": 2000,
"reference": "ORDER_01234",
"description": "Stored payment instrument payment",
"payment_type": "regular",
"settings": {
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
},
"payment_methods": {
"instrument": {
"id": "src_wmlfc3zttb4uzmk6snpwb43jbi",
"account_holder": {
"type": "individual",
"first_name": "Toby",
"last_name": "Arden"
},
"preferred_scheme": "visa"
}
}
}
```
### Response example
```json
{
"id": "set_rcmepwrchqab2wsergcafvijfy",
"processing_channel_id": "pc_wzjki6hw5puepb5fnvqlizj2e4",
"amount": 2000,
"currency": "USD",
"payment_type": "regular",
"reference": "ORDER_01234",
"description": "Stored payment instrument payment",
"payment_methods": {
"instrument": {
"type": "card",
"status": "ready",
"flags": []
}
},
"available_payment_methods": [
"instrument"
],
"settings": {
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
}
```
The response returns a `ready` status when the instrument has been successfully validated. The payment is ready to confirm.
The response also returns `payment_methods.instrument.type`, the underlying instrument's actual type, for example `card` or `bacs`.
---
## Verify payment authorization
We validate stored payment instruments synchronously, so the update response already contains the final status and you do not need to poll before you confirm the payment. To retrieve the current state of a payment setup, for example after your customer reloads the page, call the [Get a payment setup](https://api-reference.checkout.com/tag/Payment-Setups/#operation/getAPaymentSetup) endpoint, setting the `id` of the payment setup as the `id` path parameter.
**Production**
`GET` `https://{prefix}.api.checkout.com/payments/setups/{id}`
**Sandbox**
`GET` `https://{prefix}.api.sandbox.checkout.com/payments/setups/{id}`
### Response example
```json
{
"id": "set_rcmepwrchqab2wsergcafvijfy",
"processing_channel_id": "pc_wzjki6hw5puepb5fnvqlizj2e4",
"amount": 2000,
"currency": "USD",
"payment_type": "regular",
"reference": "ORDER_01234",
"description": "Stored payment instrument payment",
"payment_methods": {
"instrument": {
"id": "src_wmlfc3zttb4uzmk6snpwb43jbi",
"type": "card",
"status": "ready",
"flags": []
}
},
"available_payment_methods": [
"instrument"
],
"settings": {
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
}
```
---
## Confirm the payment
When the payment method status changes to `ready`, confirm the payment by calling the [Confirm a payment setup](https://api-reference.checkout.com/tag/Payment-Setups/#operation/confirmAPaymentSetup) endpoint and provide:
- The payment setup `id` as the `{id}` path parameter.
- `instrument` as the payment method name.
**Production**
`POST` `https://{prefix}.api.checkout.com/payments/setups/{id}/confirm/instrument`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/setups/{id}/confirm/instrument`