# Payout Payment API

Accept payments through a hosted payment form, refund them, and send money from your Payout balance to bank accounts.

- [Checkouts](#create_checkout) – create a payment, send the customer to the payment form and follow the payment status
- [Pre-authorization](#capture_checkout) – authorize a card amount and capture or cancel it later
- [Refunds](#refund_payment) – return a paid checkout to the customer, in full or in part
- [M2M withdrawals](#create_withdrawal) – pay out from your balance to an IBAN over mTLS, signed with your QSEAL key
- [Payment methods](#list_payment_methods) and [balance](#balance_of_current_account) of your account
- [Certificates](#import_mtls_certificate) – import the QWAC and QSEAL certificates that M2M withdrawals need

To get access to the API, contact us at tech@payout.one.

## Environments

- Sandbox (for test purposes only): `https://sandbox.payout.one`
- Production: `https://app.payout.one`

## Authentication

### Bearer token

Send a Bearer token in the `Authorization` header of every request except [Get API token](#authorize_receive_api_token):

```http
Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU
```

Get the token from [Get API token](#authorize_receive_api_token) with the `client_id` and `client_secret` of an API key generated in the Admin section of your account. The token is valid for `valid_for` seconds (6000); then request a new one.

### mTLS and QSEAL (M2M withdrawals)

M2M withdrawals run on separate mTLS hosts:

- Sandbox – `https://api-mtls-sandbox.payout.one`
- Production – `https://api-mtls.payout.one`

Besides the bearer token, every withdrawal request needs an approved QWAC presented in the TLS handshake. Requests that create or cancel a withdrawal are also signed with your QSEAL key in the `Digest` and `X-JWS-Signature` headers. See [M2M Withdrawals](https://developers.payout.tech/guides/m2m.html) and [Certificates](https://developers.payout.tech/guides/certificates.html).


## Errors

Errors are returned as JSON with an `errors` key. Its value is a message, or an object (or a list of objects) with messages per field. Send `Accept: application/json` with every request.

```json
{
  "errors": "Unauthorized access. Check your token."
}
```

Each endpoint lists its own errors. These authentication errors can occur on any endpoint:

| Status | Message | When |
| ------ | ------- | ---- |
| 401 | `Bad credentials. Check your credentials or contact support.` | Wrong or missing `client_id` or `client_secret` at [Get API token](#authorize_receive_api_token) |
| 401 | `Unauthorized access. Check your token.` | The token is missing or invalid |
| 401 | `Unauthorized access. Token is expired.` | The token has expired |
| 429 | `Too many failed authentication attempts for this client. Try again in a few minutes.` | 5 failed token requests for the same `client_id` within 5 minutes. Retry after the number of seconds in the `Retry-After` header |


## Get API token

`POST https://sandbox.payout.one/api/v1/authorize`

Exchanges the `client_id` and `client_secret` of your API key for a Bearer token. Send the
token in the `Authorization` header of all other requests. The token is valid for `valid_for`
seconds; then request a new one.

After 5 failed attempts for the same `client_id` within 5 minutes, the endpoint responds with
`429`. Retry after the number of seconds in the `Retry-After` header.

### Request body

- `client_id` — string (required) · API key (client ID) · e.g. `8b0f3c52-6d1e-4a7b-9c2d-5e4f3a2b1c0d`
- `client_secret` — string (required) · API key secret · e.g. `example-client-secret-not-real`

### Response 200

- `token` — string · Bearer token for the `Authorization` header · e.g. `SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU`
- `valid_for` — integer · Token validity in seconds · e.g. `6000`

### Responses

- `200` — Success
- `401` — Wrong `client_id` or `client_secret`, or one of them is missing.
- `429` — 5 failed attempts for this `client_id` within 5 minutes. Retry after `Retry-After` seconds.

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/v1/authorize' \
  -H "Content-Type: application/json" \
  -d '{
       "client_id": "8b0f3c52-6d1e-4a7b-9c2d-5e4f3a2b1c0d",
       "client_secret": "example-client-secret-not-real"
     }'
```


## Create checkout

`POST https://sandbox.payout.one/api/v1/checkouts`

Creates a checkout for a payment. Redirect your customer to the returned `checkout_url` to pay; afterwards they are sent to your `redirect_url`.

The response `status` shows the state of the checkout. To follow it later, call [Retrieve checkout](#retrieve_checkout).

### Idempotent requests

Send an `Idempotency-Key` header with a unique value, for example a v4 UUID. If a checkout with the same key already exists for your account, it is returned with status `200` instead of creating a new one. If that checkout has a different `amount`, the response is `409`.

### How to create the `signature`

1. Join these values with `|`, in this order:
   1. `amount`, exactly as sent in the request
   2. `currency`
   3. `external_id`
   4. `nonce`
   5. `client_secret` of your API key
2. Hash the string (`amount|currency|external_id|nonce|client_secret`) with SHA-256.
3. Encode the hash as lowercase hex (Base16) and send it as `signature`.

### Parameters

- `Idempotency-Key` (header) — Unique key of the request, for example a v4 UUID. A retry with the same key returns the object the first request created.

### Request body

- `amount` — integer (required) · Amount in cents, for example `1050` for 10.50. A numeric string is also accepted. · e.g. `1050`
- `currency` — string (required) · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217). Currencies not supported by Payout are rejected. · e.g. `EUR`
- `customer` — object (required) · Customer details. Send `name`, or `first_name` and `last_name`.
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `external_id` — string (required) · Your order ID or another reference for the payment · e.g. `f0ac316a-9ea6-7998-01a7-720437afb34c`
- `idempotency_key` — string · Stored with the checkout and returned in responses. Repeated requests are detected only by the `Idempotency-Key` header; when the header is sent, its value replaces this field. · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `metadata` — object · Your own data, returned with the checkout. For example the source of the payment if you have several systems. · e.g. `{"source": "eshop"}`
- `nonce` — string (required) · Random string that is part of the `signature` · e.g. `ZUc0Mk9sVXZDOXNsdklzMQ`
- `redirect_url` — string (required) · URL where the customer is sent after the payment form. Must be an absolute URL with a scheme and a host. · e.g. `https://eshop.example.com/payment/redirect`
- `signature` — string (required) · Request signature, see [How to create the `signature`](#create_checkout) · e.g. `1bd312c9ee898c2a7d2c149c2f5557bad1b02bd7ccc00aa0248ca6b660940e04`
- `mode` — string · Checkout mode. Modes other than `standard` must be enabled for your account.
  - `standard` — Regular payment
  - `pre_authorization` — Only authorizes the amount on the card; [capture](#capture_checkout) or [cancel](#cancel_checkout) it later
  - `store_card` — Stores the card and sends its token in the `payu_token.created` webhook
  - `card_on_file` — Pays with a stored card; requires `card_token`
  - `recurrent` — Recurrent payment with a stored card; requires `recurrent_token`
- `recurring` — boolean · Only with `mode: store_card`. Send `true` when you will charge the stored card regularly (recurring payments); this requires recurrent payments to be enabled for your account.
- `recurrent_token` — string · Token from the `payu_token.created` webhook. Required when `mode` is `recurrent`.
- `card_token` — string · Token of a stored card from the `payu_token.created` webhook. Required when `mode` is `card_on_file`.
- `payment_method` — string · e.g. `card`

  Payment method to open for the customer, for example `card`, `apple_pay`, `pisp` or `bank_transfer`. If the method is not available for your account, the customer sees all available methods.

  [List payment methods](#list_payment_methods) returns the methods enabled for your account. [Checkout payment methods](https://developers.payout.tech/guides/payment-gateway-use-cases-checkout-payment-methods.html) lists all identifiers, including the ones that open a single bank.

- `iban` — string · Customer's IBAN. Must be a valid IBAN. · e.g. `SK3112000000198742637541`
- `billing_address` — object · Billing address
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `shipping_address` — object · Shipping address
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `products` — object[] · Ordered products
  - `name` — string (required) · e.g. `Product 1`
  - `unit_price` — integer (required) · Unit price in cents · e.g. `350`
  - `quantity` — integer (required) · e.g. `3`
  - `date` — string<date> · Date of the product or service · e.g. `2026-10-20`
  - `offer_id` — string · Offer ID used for transaction splitting · e.g. `PREMIUM`
- `should_split` — boolean · Split the payment into one transaction per product `offer_id` (transaction splitting must be enabled for your account). The sum of `unit_price * quantity` of all products must equal `amount`.

### Response 201

- `object` — string · Object type · e.g. `checkout`
- `id` — integer · Checkout ID · e.g. `141447`
- `external_id` — string · Your order ID or another reference for the payment · e.g. `f0ac316a-9ea6-7998-01a7-720437afb34c`
- `amount` — integer · Amount in cents · e.g. `1050`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `redirect_url` — string · URL where the customer is sent after the payment form · e.g. `https://eshop.example.com/payment/redirect`
- `idempotency_key` — string | null · `Idempotency-Key` header (or `idempotency_key` field) of the request that created the checkout · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `customer` — object · Customer details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `checkout_url` — string · URL of the payment form. Redirect your customer to it. · e.g. `https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA`
- `metadata` — object | null · Your own data sent with the checkout · e.g. `{"source": "eshop"}`
- `status` — string · Checkout status · e.g. `processing`
  - `processing` — Created, waiting for the customer to pay
  - `requires_authorization` — Card payment soft-declined by the issuer; the next attempt requires 3-D Secure verification
  - `requires_3ds` — Waiting for the customer to complete 3-D Secure verification of the card
  - `pisp_processing` — Bank payment (PISP) accepted by the bank, waiting for it to complete
  - `awaiting_confirmation` — Card payment completed at the gateway, waiting for the gateway's notification
  - `succeeded` — Paid; with `mode: pre_authorization`, the amount is authorized and can be captured
  - `expired` — Not paid within the checkout expiration time of your account (10 days by default)
  - `failed` — The last payment attempt failed and the customer can try again. Also set when a pre-authorization is cancelled.
  - `requires_payment_method` — Reserved – not currently set
  - `requires_action` — Reserved – not currently set
  - `requires_capture` — Reserved – not currently set
  - `cancelled` — Reserved – not currently set; cancelling a pre-authorization sets `failed`. Withdrawals and refunds spell their status `canceled`.
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `aEs3VG1QcVh6TjJ3Ylk4ZA`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_checkout) · e.g. `cfbe2f29934d0cb90a37b2b54bdb73d32de99790a8414dc9e16624173776bf97`
- `payment` — object | null · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `all_payments` — object[] · All payments and bank transfers of the checkout. Currently it stays empty unless the checkout has a bank transfer, so read `payment` for card and other payments.
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `billing_address` — object | null · Billing address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `shipping_address` — object | null · Shipping address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `products` — object[] | null · Ordered products, `null` if none were sent
  - `name` — string · e.g. `Product 1`
  - `quantity` — integer · e.g. `3`
  - `unit_price` — integer · Unit price in cents · e.g. `350`
- `payment_token` — string · Token used to complete the payment with Payout JS (for example Apple Pay) · e.g. `U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl`
- `is_status_final` — boolean · Whether the checkout has reached a final state and will no longer change. Always `true` for `succeeded` checkouts. · e.g. `false`

### Responses

- `201` — Checkout created
- `200` — A checkout with the same `Idempotency-Key` already exists and is returned. It is returned without its payments (`payment` is `null`, `all_payments` is empty); call [Retrieve checkout](#retrieve_checkout) for its current state.
- `400` — Validation failed: `errors` lists one object per problem, or is a message for an unsupported `mode`
- `401` — Missing, invalid or expired bearer token.
- `403` — Invalid `recurrent_token` or `card_token`
- `409` — A checkout with the same `Idempotency-Key` but a different amount already exists

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/v1/checkouts' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "amount": 1050,
       "currency": "EUR",
       "customer": {
         "first_name": "John",
         "last_name": "Doe",
         "email": "john.doe@example.com"
       },
       "external_id": "f0ac316a-9ea6-7998-01a7-720437afb34c",
       "nonce": "ZUc0Mk9sVXZDOXNsdklzMQ",
       "metadata": {
         "source": "eshop"
       },
       "redirect_url": "https://eshop.example.com/payment/redirect",
       "signature": "1bd312c9ee898c2a7d2c149c2f5557bad1b02bd7ccc00aa0248ca6b660940e04"
     }'
```


## List checkouts

`GET https://sandbox.payout.one/api/v1/checkouts`

Lists the checkouts of your account, newest first. Page through them with `limit` and `offset`.

### Parameters

- `limit` (query) — Maximum number of checkouts to return. There is no upper limit (default `10`)
- `offset` (query) — Number of checkouts to skip (default `0`)

### Response 200

- `object` — string · Object type · e.g. `checkout`
- `id` — integer · Checkout ID · e.g. `141447`
- `external_id` — string · Your order ID or another reference for the payment · e.g. `f0ac316a-9ea6-7998-01a7-720437afb34c`
- `amount` — integer · Amount in cents · e.g. `1050`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `redirect_url` — string · URL where the customer is sent after the payment form · e.g. `https://eshop.example.com/payment/redirect`
- `idempotency_key` — string | null · `Idempotency-Key` header (or `idempotency_key` field) of the request that created the checkout · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `customer` — object · Customer details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `checkout_url` — string · URL of the payment form. Redirect your customer to it. · e.g. `https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA`
- `metadata` — object | null · Your own data sent with the checkout · e.g. `{"source": "eshop"}`
- `status` — string · Checkout status · e.g. `processing`
  - `processing` — Created, waiting for the customer to pay
  - `requires_authorization` — Card payment soft-declined by the issuer; the next attempt requires 3-D Secure verification
  - `requires_3ds` — Waiting for the customer to complete 3-D Secure verification of the card
  - `pisp_processing` — Bank payment (PISP) accepted by the bank, waiting for it to complete
  - `awaiting_confirmation` — Card payment completed at the gateway, waiting for the gateway's notification
  - `succeeded` — Paid; with `mode: pre_authorization`, the amount is authorized and can be captured
  - `expired` — Not paid within the checkout expiration time of your account (10 days by default)
  - `failed` — The last payment attempt failed and the customer can try again. Also set when a pre-authorization is cancelled.
  - `requires_payment_method` — Reserved – not currently set
  - `requires_action` — Reserved – not currently set
  - `requires_capture` — Reserved – not currently set
  - `cancelled` — Reserved – not currently set; cancelling a pre-authorization sets `failed`. Withdrawals and refunds spell their status `canceled`.
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `aEs3VG1QcVh6TjJ3Ylk4ZA`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_checkout) · e.g. `cfbe2f29934d0cb90a37b2b54bdb73d32de99790a8414dc9e16624173776bf97`
- `payment` — object | null · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `all_payments` — object[] · All payments and bank transfers of the checkout. Currently it stays empty unless the checkout has a bank transfer, so read `payment` for card and other payments.
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `billing_address` — object | null · Billing address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `shipping_address` — object | null · Shipping address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `products` — object[] | null · Ordered products, `null` if none were sent
  - `name` — string · e.g. `Product 1`
  - `quantity` — integer · e.g. `3`
  - `unit_price` — integer · Unit price in cents · e.g. `350`
- `payment_token` — string · Token used to complete the payment with Payout JS (for example Apple Pay) · e.g. `U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl`
- `is_status_final` — boolean · Whether the checkout has reached a final state and will no longer change. Always `true` for `succeeded` checkouts. · e.g. `false`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/checkouts?limit=2' \
  -H "Authorization: Bearer $TOKEN"
```


## Retrieve checkout

`GET https://sandbox.payout.one/api/v1/checkouts/{checkout_id}`

Returns a checkout of your account with its payments and bank transfers.

### How to verify the `signature`

1. Join these values from the response with `|`, in this order:
   1. `amount`
   2. `currency`
   3. `external_id`
   4. `nonce`
   5. `client_secret` of your API key
2. Hash the string (`amount|currency|external_id|nonce|client_secret`) with SHA-256 and encode the hash as lowercase hex (Base16).
3. Compare the result with `signature` from the response.

### Encrypted payer details

Decrypt `account_details.name` and `customer.iban` of bank payments as described in [Checkout verification webhook](https://developers.payout.tech/guides/payment-gateway-use-cases-checkout-verification-webhook.html#decrypting-account-details).

### Parameters

- `checkout_id` (path, required) — Checkout ID

### Response 200

- `object` — string · Object type · e.g. `checkout`
- `id` — integer · Checkout ID · e.g. `141447`
- `external_id` — string · Your order ID or another reference for the payment · e.g. `f0ac316a-9ea6-7998-01a7-720437afb34c`
- `amount` — integer · Amount in cents · e.g. `1050`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `redirect_url` — string · URL where the customer is sent after the payment form · e.g. `https://eshop.example.com/payment/redirect`
- `idempotency_key` — string | null · `Idempotency-Key` header (or `idempotency_key` field) of the request that created the checkout · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `customer` — object · Customer details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `checkout_url` — string · URL of the payment form. Redirect your customer to it. · e.g. `https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA`
- `metadata` — object | null · Your own data sent with the checkout · e.g. `{"source": "eshop"}`
- `status` — string · Checkout status · e.g. `processing`
  - `processing` — Created, waiting for the customer to pay
  - `requires_authorization` — Card payment soft-declined by the issuer; the next attempt requires 3-D Secure verification
  - `requires_3ds` — Waiting for the customer to complete 3-D Secure verification of the card
  - `pisp_processing` — Bank payment (PISP) accepted by the bank, waiting for it to complete
  - `awaiting_confirmation` — Card payment completed at the gateway, waiting for the gateway's notification
  - `succeeded` — Paid; with `mode: pre_authorization`, the amount is authorized and can be captured
  - `expired` — Not paid within the checkout expiration time of your account (10 days by default)
  - `failed` — The last payment attempt failed and the customer can try again. Also set when a pre-authorization is cancelled.
  - `requires_payment_method` — Reserved – not currently set
  - `requires_action` — Reserved – not currently set
  - `requires_capture` — Reserved – not currently set
  - `cancelled` — Reserved – not currently set; cancelling a pre-authorization sets `failed`. Withdrawals and refunds spell their status `canceled`.
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `aEs3VG1QcVh6TjJ3Ylk4ZA`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_checkout) · e.g. `cfbe2f29934d0cb90a37b2b54bdb73d32de99790a8414dc9e16624173776bf97`
- `payment` — object | null · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `all_payments` — object[] · All payments and bank transfers of the checkout. Currently it stays empty unless the checkout has a bank transfer, so read `payment` for card and other payments.
  - `object` — string · Object type · e.g. `payment`
    - `payment` — Payment with a payment method such as a card
    - `bank_transfer` — Manual bank transfer, matched to the checkout from Payout's bank statement
  - `status` — string · Status of the payment or bank transfer · e.g. `successful`
    - `pending` — Created, not confirmed by the acquirer yet (`payment` only)
    - `in_transit` — Matched to the checkout, not reconciled yet (`bank_transfer` only)
    - `successful` — Confirmed by the acquirer, or the bank transfer is reconciled
    - `failed` — Failed at the acquirer or bank
    - `expired` — Bank transfer expired (`bank_transfer` only)
    - `refunded` — Fully refunded
    - `partialy_refunded` — Partially refunded
  - `payment_method` — string · Payment method identifier. `card` for all card payments and `bank_transfer` for bank transfers; other methods use their identifier from [List payment methods](#list_payment_methods), for example `pisp`. · e.g. `card`
  - `failure_reason` — string · Payment failure reason (currently always an empty string) · e.g. ``
  - `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
  - `funds` — string · How the net amount counts in your [balance](#balance_of_current_account) · e.g. `available`
    - `pending` — Counted in your pending balance
    - `available` — Counted in your available balance
    - `onhold` — On hold, not counted in your balance
    - `canceled` — Not counted in your balance, for example because the payment failed
  - `fee` — integer · Fee in cents · e.g. `36`
  - `net` — integer · Amount after fees, in cents · e.g. `1014`
  - `iban` — string | null · Payer IBAN from the bank statement. Only in `bank_transfer` objects. · e.g. `CZ6508000000192000145399`
  - `account_details` — object · Only for bank payments when payer name encryption is enabled for your account. `name` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `name` — string · Encrypted payer name · e.g. `<encrypted>`
  - `customer` — object · Only for bank payments when payer IBAN encryption is enabled for your account. `iban` is encrypted with your API key, see *Encrypted payer details* in [Retrieve checkout](#retrieve_checkout).
    - `iban` — string · Encrypted payer IBAN · e.g. `<encrypted>`
- `billing_address` — object | null · Billing address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `shipping_address` — object | null · Shipping address, `null` if not sent
  - `name` — string (required) · e.g. `John Doe`
  - `address_line_1` — string (required) · e.g. `Main Street 1`
  - `address_line_2` — string · e.g. `Flat 2`
  - `postal_code` — string (required) · e.g. `81101`
  - `city` — string (required) · e.g. `Bratislava`
  - `country_code` — string (required) · Country code by ISO 3166-1 alpha-2 · e.g. `SK`
- `products` — object[] | null · Ordered products, `null` if none were sent
  - `name` — string · e.g. `Product 1`
  - `quantity` — integer · e.g. `3`
  - `unit_price` — integer · Unit price in cents · e.g. `350`
- `payment_token` — string · Token used to complete the payment with Payout JS (for example Apple Pay) · e.g. `U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl`
- `is_status_final` — boolean · Whether the checkout has reached a final state and will no longer change. Always `true` for `succeeded` checkouts. · e.g. `false`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `403` — The checkout belongs to another account
- `404` — Checkout not found

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/checkouts/141447' \
  -H "Authorization: Bearer $TOKEN"
```


## Cancel pre-authorized checkout

`DELETE https://sandbox.payout.one/api/v1/checkouts/{checkout_id}`

Cancels a checkout created with `mode` `pre_authorization`, for example when a product or service is not delivered. Only checkouts for which the `checkout.captured` webhook was not sent can be cancelled.

On success the checkout `status` changes to `failed` and the `checkout.canceled` webhook is sent. See also [Capture and cancel](https://developers.payout.tech/guides/payment-gateway-use-cases-capture.html#cancel).

### Parameters

- `checkout_id` (path, required) — Checkout ID

### Responses

- `200` — Pre-authorization cancelled
- `400` — The checkout was not created with `mode` `pre_authorization`
- `401` — Missing, invalid or expired bearer token.
- `403` — The checkout belongs to another account
- `404` — Checkout not found
- `422` — The acquirer refused the cancellation

### Example

```bash
curl -X DELETE 'https://sandbox.payout.one/api/v1/checkouts/141447' \
  -H "Authorization: Bearer $TOKEN"
```


## Capture pre-authorized checkout

`POST https://sandbox.payout.one/api/v1/checkouts/{checkout_id}/capture`

Captures the card amount authorized by a checkout created with `mode` `pre_authorization`. Pre-authorization must be enabled for your account.

Send an empty body to capture the whole authorized amount, or `amount` for a partial capture. After a successful capture the `checkout.captured` webhook is sent. See also [Capture and cancel](https://developers.payout.tech/guides/payment-gateway-use-cases-capture.html#capture).

### Parameters

- `checkout_id` (path, required) — Checkout ID

### Request body

- `amount` — integer · Amount to capture in cents. It must not be larger than the checkout amount. A numeric string is also accepted. Omit it to capture the whole amount. · e.g. `150`

### Responses

- `200` — Captured
- `400` — `amount` is larger than the checkout amount
- `401` — Missing, invalid or expired bearer token.
- `403` — The checkout belongs to another account
- `404` — Checkout not found
- `422` — The acquirer refused the capture

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/v1/checkouts/141447/capture' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "amount": 150
     }'
```


## Retrieve payment instructions

`GET https://sandbox.payout.one/api/v1/checkouts/{checkout_id}/payment_instructions`

Returns the bank details and QR code your customer needs to pay a checkout by manual bank transfer. No email is sent; use it to show the instructions in your own UI. See [Payment instructions](https://developers.payout.tech/guides/payment-gateway-use-cases-payment-instructions.html).

Bank transfer must be enabled for your account in the checkout currency. The QR code is cached, so repeated calls for the same checkout return the same image and are safe to retry.

### Parameters

- `checkout_id` (path, required) — Checkout ID

### Response 200

- `recipient_name` — string · Name of the beneficiary the customer should send the money to · e.g. `Payout a.s.`
- `iban` — string · Beneficiary IBAN in international format · e.g. `SK3112000000198742637541`
- `account_number` — string | null · Beneficiary account in local format (`prefix-account/bank_code`). Filled for Czech (CZ) and Slovak (SK) IBANs, otherwise `null`. · e.g. `000019-8742637541/1200`
- `variable_symbol` — string · Variable symbol the customer must include in the transfer. It binds the incoming payment to the checkout. · e.g. `1000123411`
- `amount` — string · Total amount to transfer, decimal string (not in cents) · e.g. `10.5000`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `qr_code` — string · Base64-encoded PNG of the payment QR code · e.g. `iVBORw0KGgoAAAANSUhEUgAAAX8AAAHBCAYAAACBh...`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `403` — The checkout belongs to another account
- `404` — Checkout not found
- `409` — Bank transfer is not enabled for your account in the checkout currency
- `410` — The checkout has expired
- `422` — No beneficiary bank account is available for the checkout currency
- `500` — The QR code could not be generated; the request is safe to repeat

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/checkouts/141447/payment_instructions' \
  -H "Authorization: Bearer $TOKEN"
```


## Refund payment

`POST https://sandbox.payout.one/api/v1/refunds`

Refunds a paid checkout to the original customer.

Send `amount` for a partial refund; without it, the whole amount that has not been refunded yet is refunded. Depending on the payment method, only a full refund may be possible. For checkouts created with `should_split: true`, `offer_id` is required and selects the split transaction to refund, see [Transaction Splitting](https://developers.payout.tech/guides/transaction-splitting.html#refund-handling).

The refunded amount and the refund fees are deducted from your available balance.

### How to create the `signature`

1. Join these values with `|`, in this order:
   1. `amount` exactly as sent in the request. If you omit `amount`, use the checkout `amount` in cents, even when part of it was already refunded.
   2. `currency` of the checkout
   3. `external_id` of the checkout
   4. `iban` as sent in the request, or empty if you omit it
   5. `nonce`
   6. `client_secret` of your API key
2. Hash the string (`amount|currency|external_id|iban|nonce|client_secret`) with SHA-256.
3. Encode the hash as lowercase hex (Base16) and send it as `signature`.

### How to verify the response `signature`

1. Join these values from the response with `|`, in this order:
   1. `amount`
   2. `currency`
   3. `external_id`
   4. an empty value (the response has no IBAN)
   5. `nonce`
   6. `client_secret` of your API key
2. Hash the string (`amount|currency|external_id||nonce|client_secret`) with SHA-256 and encode the hash as lowercase hex (Base16).
3. Compare the result with `signature` from the response.

### Request body

- `checkout_id` — integer (required) · ID of the paid checkout to refund · e.g. `141447`
- `amount` — integer · Amount to refund in cents, for example `500` for 5.00. A numeric string is also accepted. Without it, the whole amount that has not been refunded yet is refunded. · e.g. `500`
- `iban` — string · Customer's IBAN. It is only used in the `signature`; the refund goes to the original customer. · e.g. `SK3112000000198742637541`
- `statement_descriptor` — string · Text for the recipient's bank statement. Only letters without accents, digits, spaces and the characters `/-?:().,'+` are allowed. · e.g. `Refund for order 1001`
- `offer_id` — string · Offer ID of the split transaction to refund. Required for checkouts created with `should_split: true`. · e.g. `PREMIUM`
- `nonce` — string (required) · Random string that is part of the `signature` · e.g. `cnd0aXJ0cnVuZXg`
- `signature` — string (required) · Request signature, see [How to create the `signature`](#refund_payment) · e.g. `1197e50f076dec439cf1b47e6905aa95aacc7d593954a224496a7c350faeaa27`

### Response 200

- `id` — integer · Refund ID · e.g. `52332`
- `object` — string · Object type · e.g. `refund`
- `amount` — integer · Amount in cents · e.g. `500`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `external_id` — string · `external_id` of the refunded checkout · e.g. `f0ac316a-9ea6-7998-01a7-720437afb34c`
- `idempotency_key` — null · Always `null`; refunds have no idempotency key · e.g. `null`
- `customer` — object · Customer details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `status` — string · Refund status · e.g. `pending`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.
- `metadata` — object · Always an empty object · e.g. `{}`
- `statement_descriptor` — string | null · Text for the recipient's bank statement · e.g. `Refund for order 1001`
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759831200`
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `TGs5SmhHM2ZEczVBcVo3eA`
- `signature` — string · Response signature, see [How to verify the response `signature`](#refund_payment) · e.g. `addd0a0ef36320a8d8f041a092c7600f54678521b18fa738f6bc0cf664c61598`

### Responses

- `200` — Refund created
- `400` — The payment cannot be refunded, for example it is not paid yet, was already refunded, or your available balance is too low; `errors` names the reason
- `401` — Missing, invalid or expired bearer token.
- `403` — Invalid `signature`, see [How to create the `signature`](#refund_payment)
- `404` — Checkout not found
- `422` — The refund could not be created (for example, no split transaction for the given `offer_id`)

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/v1/refunds' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "checkout_id": 141447,
       "amount": 500,
       "statement_descriptor": "Refund for order 1001",
       "nonce": "cnd0aXJ0cnVuZXg",
       "signature": "1197e50f076dec439cf1b47e6905aa95aacc7d593954a224496a7c350faeaa27"
     }'
```


## Create withdrawal

`POST https://api-mtls-sandbox.payout.one/api/v2/withdrawals`

Hosts: `https://api-mtls-sandbox.payout.one`, `https://api-mtls.payout.one`

Sends money from your Payout balance to the given IBAN. A new withdrawal has `status` `pending`; its amount and fees are deducted from your available balance right away.

Call it on the mTLS host with an approved QWAC and sign it with your QSEAL key in the `Digest` and `X-JWS-Signature` headers. How to build the signature is described in [M2M Withdrawals](https://developers.payout.tech/guides/m2m.html#signing-payment-instructions-with-qseal); how to get and import the certificates in [Certificates](https://developers.payout.tech/guides/certificates.html#setup).

### Idempotent requests

Send an `Idempotency-Key` header with a unique value. If a withdrawal with the same key already exists for your account, it is returned with status `200` instead of creating a new one.

### Parameters

- `Idempotency-Key` (header) — Unique key of the request, for example a v4 UUID. A retry with the same key returns the object the first request created.
- `Digest` (header, required) — `SHA-256=` followed by the Base64 SHA-256 of the exact request body (of an empty body when there is none)
- `X-JWS-Signature` (header, required) — Detached JWS (`<protected header>..<signature>`) over the `Digest` value, made with your QSEAL key. The protected header carries `x5t#S256` (QSEAL thumbprint) and `sigT` (signing time, at most 5 minutes off).

### Request body

- `amount` — integer (required) · Amount in cents, for example `1050` for 10.50. A numeric string is also accepted. · e.g. `1050`
- `currency` — string (required) · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217). Currencies not supported by Payout are rejected. · e.g. `EUR`
- `iban` — string (required) · IBAN of the bank account the amount is sent to · e.g. `SK3112000000198742637541`
- `customer` — object (required) · Recipient details. Send `name`, or `first_name` and `last_name`.
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `external_id` — string · Your reference for the withdrawal, returned with it · e.g. `PAYOUT-2026-0001`
- `statement_descriptor` — string · Text for the recipient's bank statement. Only letters without accents, digits, spaces and the characters `/-?:().,'+` are allowed. · e.g. `Payout for order 1001`

### Response 201

- `id` — integer · Withdrawal ID · e.g. `52331`
- `object` — string · Object type · e.g. `withdrawal`
- `amount` — integer · Amount in cents · e.g. `1050`
- `api_key_id` — integer | null · ID of the API key that created the withdrawal, `null` if it was not created through the API · e.g. `42`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `external_id` — string | null · Your reference for the withdrawal · e.g. `PAYOUT-2026-0001`
- `iban` — string · IBAN of the recipient · e.g. `SK3112000000198742637541`
- `idempotency_key` — string | null · `Idempotency-Key` header of the request that created the withdrawal · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `status` — string · Withdrawal status · e.g. `pending`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.
- `metadata` — object · Additional data Payout stores with the withdrawal. Empty for withdrawals created through the API. · e.g. `{}`
- `statement_descriptor` — string | null · Text for the recipient's bank statement · e.g. `Payout for order 1001`
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `VGc1SGpLMm1OYjdWY1gzeg`
- `customer` — object · Recipient details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_withdrawal) · e.g. `46d36aad1153a6195e6a1db51d0d49d2008acc5c264562b5da30c40e355ce71c`

### Responses

- `201` — Withdrawal created
- `200` — A withdrawal with the same `Idempotency-Key` already exists and is returned
- `400` — Missing `iban`, not enough balance, or the currency is invalid or not allowed
- `401` — Missing, invalid or expired bearer token.
- `403` — The QWAC or the QSEAL signature was not accepted, for example the certificate is not approved or belongs to another account, `Digest` does not match the body, or `sigT` is more than 5 minutes off
- `404` — Not the mTLS host (empty response)
- `422` — Validation failed (`errors` per field, for example a blocked IBAN, or the amount plus fees would exceed your available balance), or the risk check refused the withdrawal

### Example

```bash
BODY='{
  "amount": 1050,
  "currency": "EUR",
  "external_id": "PAYOUT-2026-0001",
  "iban": "SK3112000000198742637541",
  "customer": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com"
  },
  "statement_descriptor": "Payout for order 1001"
}'
DIGEST="SHA-256=$(printf %s "$BODY" | openssl dgst -sha256 -binary | base64)"
# QSEAL key, see M2M Withdrawals: Signing payment instructions with QSEAL
JWS_SIGNATURE="<detached JWS over $DIGEST>"

curl -X POST 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals' \
  --cert qwac.pem --key qwac.key \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Digest: $DIGEST" \
  -H "X-JWS-Signature: $JWS_SIGNATURE" \
  -d "$BODY"
```


## List withdrawals

`GET https://api-mtls-sandbox.payout.one/api/v2/withdrawals`

Hosts: `https://api-mtls-sandbox.payout.one`, `https://api-mtls.payout.one`

Lists the withdrawals of your account, newest first by default. Read-only requests need the bearer token and the QWAC, no QSEAL signature.

### Parameters

- `limit` (query) — Maximum number of withdrawals to return. Without it, all withdrawals are returned.
- `offset` (query) — Number of withdrawals to skip (default `0`)
- `order` (query) — Sort order by withdrawal ID, case-insensitive. Any other value sorts `DESC` (default `DESC`)
  - `ASC`
  - `DESC`

### Response 200

- `id` — integer · Withdrawal ID · e.g. `52331`
- `object` — string · Object type · e.g. `withdrawal`
- `amount` — integer · Amount in cents · e.g. `1050`
- `api_key_id` — integer | null · ID of the API key that created the withdrawal, `null` if it was not created through the API · e.g. `42`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `external_id` — string | null · Your reference for the withdrawal · e.g. `PAYOUT-2026-0001`
- `iban` — string · IBAN of the recipient · e.g. `SK3112000000198742637541`
- `idempotency_key` — string | null · `Idempotency-Key` header of the request that created the withdrawal · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `status` — string · Withdrawal status · e.g. `pending`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.
- `metadata` — object · Additional data Payout stores with the withdrawal. Empty for withdrawals created through the API. · e.g. `{}`
- `statement_descriptor` — string | null · Text for the recipient's bank statement · e.g. `Payout for order 1001`
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `VGc1SGpLMm1OYjdWY1gzeg`
- `customer` — object · Recipient details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_withdrawal) · e.g. `46d36aad1153a6195e6a1db51d0d49d2008acc5c264562b5da30c40e355ce71c`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `403` — No approved QWAC presented in the TLS handshake, or the certificate belongs to another account
- `404` — Not the mTLS host (empty response)

### Example

```bash
curl -X GET 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals?limit=10' \
  --cert qwac.pem --key qwac.key \
  -H "Authorization: Bearer $TOKEN"
```


## Retrieve withdrawal

`GET https://api-mtls-sandbox.payout.one/api/v2/withdrawals/{withdrawal_id}`

Hosts: `https://api-mtls-sandbox.payout.one`, `https://api-mtls.payout.one`

Returns one withdrawal of your account. Read-only requests need the bearer token and the QWAC, no QSEAL signature.

### How to verify the `signature`

1. Join these values from the response with `|`, in this order:
   1. `amount`
   2. `currency`
   3. `external_id` (empty when `null`)
   4. `iban`
   5. `nonce`
   6. `client_secret` of your API key
2. Hash the string (`amount|currency|external_id|iban|nonce|client_secret`) with SHA-256 and encode the hash as lowercase hex (Base16).
3. Compare the result with `signature` from the response.

### Parameters

- `withdrawal_id` (path, required) — Withdrawal ID

### Response 200

- `id` — integer · Withdrawal ID · e.g. `52331`
- `object` — string · Object type · e.g. `withdrawal`
- `amount` — integer · Amount in cents · e.g. `1050`
- `api_key_id` — integer | null · ID of the API key that created the withdrawal, `null` if it was not created through the API · e.g. `42`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `external_id` — string | null · Your reference for the withdrawal · e.g. `PAYOUT-2026-0001`
- `iban` — string · IBAN of the recipient · e.g. `SK3112000000198742637541`
- `idempotency_key` — string | null · `Idempotency-Key` header of the request that created the withdrawal · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `status` — string · Withdrawal status · e.g. `pending`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.
- `metadata` — object · Additional data Payout stores with the withdrawal. Empty for withdrawals created through the API. · e.g. `{}`
- `statement_descriptor` — string | null · Text for the recipient's bank statement · e.g. `Payout for order 1001`
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `VGc1SGpLMm1OYjdWY1gzeg`
- `customer` — object · Recipient details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_withdrawal) · e.g. `46d36aad1153a6195e6a1db51d0d49d2008acc5c264562b5da30c40e355ce71c`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `403` — No approved QWAC presented in the TLS handshake, or the certificate belongs to another account; or the withdrawal belongs to another account
- `404` — Withdrawal not found, or not the mTLS host

### Example

```bash
curl -X GET 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals/52331' \
  --cert qwac.pem --key qwac.key \
  -H "Authorization: Bearer $TOKEN"
```


## Cancel withdrawal

`POST https://api-mtls-sandbox.payout.one/api/v2/withdrawals/{withdrawal_id}/cancel`

Hosts: `https://api-mtls-sandbox.payout.one`, `https://api-mtls.payout.one`

Cancels a withdrawal that is still `pending` and has not been passed to the bank yet. Its amount and fees are returned to your available balance. Sign the request with QSEAL like [Create withdrawal](#create_withdrawal); it has no body, so `Digest` is the SHA-256 of an empty body.

Both outcomes return `200`: the cancelled withdrawal, or `allowed: false` with the current `status` when the withdrawal can no longer be cancelled. To check in advance, call [Check if cancellable](#withdrawal_cancel_allowed).

### Parameters

- `withdrawal_id` (path, required) — Withdrawal ID
- `Digest` (header, required) — `SHA-256=` followed by the Base64 SHA-256 of the exact request body (of an empty body when there is none)
- `X-JWS-Signature` (header, required) — Detached JWS (`<protected header>..<signature>`) over the `Digest` value, made with your QSEAL key. The protected header carries `x5t#S256` (QSEAL thumbprint) and `sigT` (signing time, at most 5 minutes off).

### Response 200

One of:

**Option 1**

- `id` — integer · Withdrawal ID · e.g. `52331`
- `object` — string · Object type · e.g. `withdrawal`
- `amount` — integer · Amount in cents · e.g. `1050`
- `api_key_id` — integer | null · ID of the API key that created the withdrawal, `null` if it was not created through the API · e.g. `42`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`
- `external_id` — string | null · Your reference for the withdrawal · e.g. `PAYOUT-2026-0001`
- `iban` — string · IBAN of the recipient · e.g. `SK3112000000198742637541`
- `idempotency_key` — string | null · `Idempotency-Key` header of the request that created the withdrawal · e.g. `7c9e6679-7425-40de-944b-e07fc1f90ae7`
- `status` — string · Withdrawal status · e.g. `pending`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.
- `metadata` — object · Additional data Payout stores with the withdrawal. Empty for withdrawals created through the API. · e.g. `{}`
- `statement_descriptor` — string | null · Text for the recipient's bank statement · e.g. `Payout for order 1001`
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. `1759744800`
- `nonce` — string · Random string Payout generates for the response `signature` · e.g. `VGc1SGpLMm1OYjdWY1gzeg`
- `customer` — object · Recipient details
  - `first_name` — string · Customer first name · e.g. `John`
  - `last_name` — string · Customer surname · e.g. `Doe`
  - `name` — string · Customer full name. Can be sent instead of `first_name` and `last_name`; responses always contain it. · e.g. `John Doe`
  - `email` — string (required) · Customer email · e.g. `john.doe@example.com`
  - `phone` — string | null · Customer phone number. Characters other than digits and `+` are removed. · e.g. `+421900000000`
  - `note` — string | null · Note about the customer · e.g. `null`
- `signature` — string · Response signature, see [How to verify the `signature`](#retrieve_withdrawal) · e.g. `46d36aad1153a6195e6a1db51d0d49d2008acc5c264562b5da30c40e355ce71c`

**Option 2**

- `allowed` — boolean (required) · Always `false` · e.g. `false`
- `status` — string (required) · Current status of the withdrawal · e.g. `in_transit`
  - `pending` — Created, not sent to the bank (or, for a card refund, to the acquirer) yet. Withdrawals held because they exceed your account's withdrawal limits are also `pending`. Only `pending` withdrawals can be [cancelled](#cancel_withdrawal).
  - `in_transit` — Sent to the bank, waiting for the bank to execute it
  - `paid` — Executed by the bank (confirmed by the bank or found on Payout's bank statement); for a card refund, confirmed by the acquirer
  - `canceled` — Cancelled before it was executed, by you or by Payout. The amount and fees are returned to your available balance. Spelled `canceled`; checkouts use `cancelled`.
  - `failed` — Rejected by the bank or could not be executed. The amount and fees are returned to your available balance.

### Responses

- `200` — The cancelled withdrawal, or `allowed` false with the current `status`
- `401` — Missing, invalid or expired bearer token.
- `403` — The QWAC or the QSEAL signature was not accepted, for example the certificate is not approved or belongs to another account, `Digest` does not match the body, or `sigT` is more than 5 minutes off
- `404` — Withdrawal not found, or not the mTLS host

### Example

```bash
BODY=''
DIGEST="SHA-256=$(printf %s "$BODY" | openssl dgst -sha256 -binary | base64)"
# QSEAL key, see M2M Withdrawals: Signing payment instructions with QSEAL
JWS_SIGNATURE="<detached JWS over $DIGEST>"

curl -X POST 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals/52331/cancel' \
  --cert qwac.pem --key qwac.key \
  -H "Authorization: Bearer $TOKEN" \
  -H "Digest: $DIGEST" \
  -H "X-JWS-Signature: $JWS_SIGNATURE"
```


## Check if cancellable

`POST https://api-mtls-sandbox.payout.one/api/v2/withdrawals/{withdrawal_id}/cancel_allowed`

Hosts: `https://api-mtls-sandbox.payout.one`, `https://api-mtls.payout.one`

Tells whether [Cancel withdrawal](#cancel_withdrawal) would succeed now. Like the read-only requests, it needs the bearer token and the QWAC, no QSEAL signature.

### Parameters

- `withdrawal_id` (path, required) — Withdrawal ID

### Response 200

- `allowed` — boolean (required) · Whether [Cancel withdrawal](#cancel_withdrawal) would succeed now · e.g. `true`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `403` — No approved QWAC presented in the TLS handshake, the certificate belongs to another account, or the withdrawal belongs to another account
- `404` — Withdrawal not found, or not the mTLS host

### Example

```bash
curl -X POST 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals/52331/cancel_allowed' \
  --cert qwac.pem --key qwac.key \
  -H "Authorization: Bearer $TOKEN"
```


## List payment methods

`GET https://sandbox.payout.one/api/v1/payment_methods`

Lists the payment methods enabled for your account, with their fees. Send an `identificator` as `payment_method` in [Create checkout](#create_checkout) to open that method for the customer.

### Response 200

- `name` — string · Payment method name · e.g. `Card Payment`
- `identificator` — string · Payment method identifier. All card payment methods share the identifier `card`; other methods have their own, for example `pisp` or `bank_transfer`. · e.g. `card`
- `fixed_fee` — integer · Fixed fee per payment in cents · e.g. `20`
- `percentual_fee` — number · Percentage fee (1.5 = 1.5 %) of the payment amount · e.g. `1.5`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/payment_methods' \
  -H "Authorization: Bearer $TOKEN"
```


## Retrieve balance

`GET https://sandbox.payout.one/api/v1/balance`

Returns the balance of the account your API key belongs to, one entry per currency.

### Response 200

- `available` — integer · Money you can withdraw or refund from, in cents. Released incoming payments minus withdrawals, refunds, chargebacks and fees. · e.g. `1567243`
- `pending` — integer · Incoming payments in cents (after fees) that are not released to `available` yet. They are not part of `available`. · e.g. `14768`
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. `EUR`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/balance' \
  -H "Authorization: Bearer $TOKEN"
```


## Import certificate

`POST https://sandbox.payout.one/api/v1/mtls/certificates`

Imports a QWAC or QSEAL certificate for the server-to-server APIs, such as M2M withdrawals. Upload the PEM-encoded certificate only, never the private key. The certificate must be issued by a QTSP in Payout's trust store.

The certificate starts in `status` `pending` until Payout verifies it manually. See [mTLS client certificates](https://developers.payout.tech/guides/certificates.html#setup).

### Request body

- `type` — string (required) · Certificate profile · e.g. `qwac`
  - `qwac` — Client certificate presented in the TLS handshake on the mTLS host
  - `qseal` — Seal certificate whose key signs the `X-JWS-Signature` header
- `pem` — string (required) · PEM-encoded certificate · e.g. `-----BEGIN CERTIFICATE----- …`

### Response 201

- `thumbprint` — string · SHA-256 fingerprint of the certificate (lowercase hex) · e.g. `103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57`
- `type` — string · Certificate profile · e.g. `qwac`
  - `qwac` — Client certificate presented in the TLS handshake on the mTLS host
  - `qseal` — Seal certificate whose key signs the `X-JWS-Signature` header
- `status` — string · Approval status of the certificate · e.g. `pending`
  - `pending` — Imported, waiting for manual verification by Payout
  - `approved` — Verified by Payout and accepted until `valid_until`
  - `rejected` — Rejected or revoked by Payout, see `rejection_reason`
- `issuer_dn` — string · Issuer distinguished name · e.g. `C=SK,O=Example QTSP,CN=Example Qualified CA`
- `subject_dn` — string · Subject distinguished name · e.g. `C=SK,O=Example s.r.o.,organizationIdentifier=NTRSK-12345678,CN=Example s.r.o.`
- `subject_org_id` — string | null · Value of the `organizationIdentifier` subject attribute · e.g. `NTRSK-12345678`
- `valid_from` — string<date-time> · Start of the certificate's validity (`notBefore`) · e.g. `2026-06-09T06:23:06Z`
- `valid_until` — string<date-time> · End of the certificate's validity (`notAfter`). After it, the certificate is no longer accepted. · e.g. `2027-06-09T06:23:06Z`
- `rejection_reason` — string | null · Reason of rejection, if the certificate was rejected · e.g. `null`
- `validated_at` — string<date-time> | null · When Payout approved or rejected the certificate · e.g. `null`

### Responses

- `201` — Certificate imported
- `401` — Missing, invalid or expired bearer token.
- `409` — A certificate with the same thumbprint is already imported
- `422` — Malformed PEM, untrusted issuer, or missing or invalid `type` / `pem`

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/v1/mtls/certificates' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "type": "qwac",
       "pem": "-----BEGIN CERTIFICATE-----\nMIIF...\n-----END CERTIFICATE-----\n"
     }'
```


## List certificates

`GET https://sandbox.payout.one/api/v1/mtls/certificates`

Lists the certificates imported for your account, newest first.

### Response 200

- `data` — object[] · Your certificates, newest first
  - `thumbprint` — string · SHA-256 fingerprint of the certificate (lowercase hex) · e.g. `103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57`
  - `type` — string · Certificate profile · e.g. `qwac`
    - `qwac` — Client certificate presented in the TLS handshake on the mTLS host
    - `qseal` — Seal certificate whose key signs the `X-JWS-Signature` header
  - `status` — string · Approval status of the certificate · e.g. `approved`
    - `pending` — Imported, waiting for manual verification by Payout
    - `approved` — Verified by Payout and accepted until `valid_until`
    - `rejected` — Rejected or revoked by Payout, see `rejection_reason`
  - `subject_dn` — string · Subject distinguished name · e.g. `C=SK,O=Example s.r.o.,organizationIdentifier=NTRSK-12345678,CN=Example s.r.o.`
  - `valid_until` — string<date-time> · End of the certificate's validity (`notAfter`). After it, the certificate is no longer accepted. · e.g. `2027-06-09T06:23:06Z`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/mtls/certificates' \
  -H "Authorization: Bearer $TOKEN"
```


## Retrieve certificate status

`GET https://sandbox.payout.one/api/v1/mtls/certificates/{thumbprint}/status`

Returns the approval status of one of your certificates. The certificate can be used once its status is `approved`.

### Parameters

- `thumbprint` (path, required) — SHA-256 fingerprint of the certificate (lowercase hex), as returned on import

### Response 200

- `thumbprint` — string · SHA-256 fingerprint of the certificate (lowercase hex) · e.g. `103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57`
- `status` — string · Approval status of the certificate · e.g. `pending`
  - `pending` — Imported, waiting for manual verification by Payout
  - `approved` — Verified by Payout and accepted until `valid_until`
  - `rejected` — Rejected or revoked by Payout, see `rejection_reason`
- `rejection_reason` — string | null · Reason of rejection, if the certificate was rejected · e.g. `null`

### Responses

- `200` — Success
- `401` — Missing, invalid or expired bearer token.
- `404` — Certificate not found (or not owned by your account)

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/mtls/certificates/103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57/status' \
  -H "Authorization: Bearer $TOKEN"
```


## Delete certificate

`DELETE https://sandbox.payout.one/api/v1/mtls/certificates/{thumbprint}`

Deletes one of your certificates. It can no longer be used for M2M withdrawals.

### Parameters

- `thumbprint` (path, required) — SHA-256 fingerprint of the certificate (lowercase hex), as returned on import

### Responses

- `204` — Certificate deleted
- `401` — Missing, invalid or expired bearer token.
- `404` — Certificate not found (or not owned by your account)

### Example

```bash
curl -X DELETE 'https://sandbox.payout.one/api/v1/mtls/certificates/103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57' \
  -H "Authorization: Bearer $TOKEN"
```

