# Payout Payment API

## Authentication

**Bearer**

For accessing the API a valid token must be passed in all the queries in the 'Authorization' header. A valid token is obtained from `POST /api/v1/authorize` with the `client_id` and `client_secret` of an API key generated in Admin section of your account. The token is valid for the number of seconds returned in `valid_for` (6000); after that, request a new one.

The following syntax must be used in the 'Authorization' header :

    Bearer <<token>>

So Authorization header can be like:

    Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU

**mTLS + QSEAL (M2M Withdrawals)**

Withdrawals run on the mTLS hosts `api-mtls-sandbox.payout.one` and `api-mtls.payout.one`. Besides the bearer token, they need an approved QWAC for the TLS connection and, for requests that create or cancel, a QSEAL signature in `Digest` and `X-JWS-Signature`. See [M2M Withdrawals](m2m.md) and [Certificates](certificates.md).


## Errors

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

401
```
{
    "errors": "Bad credentials. Check your credentials or contact support."
}
```

401 - missing, invalid or expired token
```
{
    "errors": "Unauthorized access. Check your token."
}
```

429 - after 5 failed `POST /api/v1/authorize` attempts for the same `client_id` within 5 minutes; retry after the number of seconds in the `Retry-After` header
```
{
    "errors": "Too many failed authentication attempts for this client. Try again in a few minutes."
}
```


## Authorize (receive 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: Bearer <token>` header of all other requests. The token is valid for `valid_for` seconds.

After 5 failed attempts for the same `client_id` within 5 minutes, the endpoint responds with `429` and a `Retry-After: 300` 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

### 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`

This request create checkout for payment where customer will authorize payment method for transaction.

To perform an idempotent request, provide an additional `Idempotency-Key: <key>` header to the request. An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using v4 UUIDs, or another random string with enough entropy to avoid collisions. If a checkout with the same key already exists for your account, it is returned with status `200`; if its amount differs, the request fails with `409`.

Use `mode` for pre-authorization with later capture (`pre_authorization`), storing a card (`store_card`), payments with a stored card (`card_on_file`) and recurrent payments (`recurrent`). These modes must be enabled for your account.

### How to create the `signature`

Signature is created by few steps. First step is to create string concatenated with character `|` by joining arguments in following order:

1. `amount` (exactly as sent in the request)
2. `currency`
3. `external_id`
4. `nonce`
5. `client_secret` (obtained from merchant's API key)

After this step we should have string that looks like this: `amount|currency|external_id|nonce|client_secret`

Now, we use SHA256 hashing algorithm to hash this string and encode it using Base16 in lowercase. The signature is now complete and you can send it with the request.

### Checkout statuses:
* `processing` - created payment form
* `requires_capture` - additional authorization requested (if some gateway has additional authorization)
* `succeeded` - from checkout created transaction
* `expired` - no transaction has been created. Expires after the checkout expiration time of your account (by default 10 days after creation)

Other statuses the API can return: `requires_payment_method`, `requires_action`, `requires_authorization`, `requires_3ds`, `pisp_processing`, `awaiting_confirmation`, `cancelled`, `failed`.

### Parameters

- `Idempotency-Key` (header) — Unique key of the request, used to recognize retries of the same request

### Request body

- `amount` — integer (required) · Amount in cents (integer). 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) · Required nested JSON structure with details about customer. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `external_id` — string (required) · Client order's ID or another ID for reference to reason of 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. 31f0ac6a-9ea6-01a7-7998-720437afb34c
- `metadata` — object · Can be used for payment notation or also for internal use, for example set origin of payment if merchant has more systems. · e.g. {'source': 'eshop'}
- `nonce` — string (required) · Required random data so signature cant be reused · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `redirect_url` — string (required) · URL where user will be redirected after payment form is filled. Must be an absolute URL with a scheme and a host. · e.g. https://eshop.example.com/payment/redirect
- `signature` — string (required) · Request signature · e.g. 5a940ff7f1698f5d334527951519c84fa104c77ecf6691936093835bcac14d52
- `mode` — string · Checkout mode. `pre_authorization` only authorizes the amount on the card, capture it later with the capture endpoint. `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` makes a recurrent payment (requires `recurrent_token`). · one of standard, pre_authorization, store_card, card_on_file, recurrent
- `recurring` — boolean · Used with `mode` `store_card`. `true` 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 · Identificator of the payment method the customer is sent to directly (for example `card`, `apple_pay`, `pisp`, `bank_transfer`). If the value is not available for your account, the customer sees all available methods. · e.g. card
- `iban` — string · Customer's IBAN (optional). Must be a valid IBAN. · e.g. SK3112000000198742637541
- `billing_address` — object · Billing address (optional)
  - `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 (optional)
  - `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 (optional)
  - `name` — string (required) · e.g. Product 1
  - `unit_price` — integer (required) · Unit price in cents (integer) · e.g. 350
  - `quantity` — integer (required) · e.g. 3
  - `date` — string<date> · Date of the product or service (optional) · e.g. 2026-10-20
  - `offer_id` — string · Offer ID used for transaction splitting (optional) · 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 · Client order's ID or another ID for reference to reason of 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 user will be redirected after payment form is filled · e.g. https://eshop.example.com/payment/redirect
- `idempotency_key` — string | null · Idempotency key of the request that created the checkout · e.g. 31f0ac6a-9ea6-01a7-7998-720437afb34c
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `checkout_url` — string · URL of payment form for users order. You should redirect user to this URL. · e.g. https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA
- `metadata` — object | null · Can be used for payment notation or also for internal use, for example set origin of payment if merchant has more systems. · e.g. {'source': 'eshop'}
- `status` — string · State of checkout, for more information check Checkout statuses · one of processing, requires_payment_method, requires_action, requires_authorization, requires_capture, requires_3ds, pisp_processing, awaiting_confirmation, succeeded, expired, cancelled, failed · e.g. processing
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `signature` — string · Response signature · e.g. 5a940ff7f1698f5d334527951519c84fa104c77ecf6691936093835bcac14d52
- `payment` — object · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none. See Section with Payment Attributes
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `all_payments` — object[] · All payments and bank transfers of the checkout
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `billing_address` — object · 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 · 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[] · Ordered products, `null` if not 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

### 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": {
         "note": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been."
       },
       "redirect_url": "https://eshop.example.com/payment/redirect",
       "signature": "5a940ff7f1698f5d334527951519c84fa104c77ecf6691936093835bcac14d52"
     }'
```


## List checkouts

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

You can use this request to retrieve list of checkouts. The newest checkouts are returned first.

### Parameters

- `limit` (query) — Maximum number of checkouts to return
- `offset` (query) — Number of checkouts to skip

### Response 200

- `object` — string · Object type · e.g. checkout
- `id` — integer · Checkout ID · e.g. 141447
- `external_id` — string · Client order's ID or another ID for reference to reason of 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 user will be redirected after payment form is filled · e.g. https://eshop.example.com/payment/redirect
- `idempotency_key` — string | null · Idempotency key of the request that created the checkout · e.g. 31f0ac6a-9ea6-01a7-7998-720437afb34c
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `checkout_url` — string · URL of payment form for users order. You should redirect user to this URL. · e.g. https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA
- `metadata` — object | null · Can be used for payment notation or also for internal use, for example set origin of payment if merchant has more systems. · e.g. {'source': 'eshop'}
- `status` — string · State of checkout, for more information check Checkout statuses · one of processing, requires_payment_method, requires_action, requires_authorization, requires_capture, requires_3ds, pisp_processing, awaiting_confirmation, succeeded, expired, cancelled, failed · e.g. processing
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `signature` — string · Response signature · e.g. 5a940ff7f1698f5d334527951519c84fa104c77ecf6691936093835bcac14d52
- `payment` — object · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none. See Section with Payment Attributes
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `all_payments` — object[] · All payments and bank transfers of the checkout
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `billing_address` — object · 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 · 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[] · Ordered products, `null` if not 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

### Example

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


## Retrieve checkout

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

You can use this request to retrieve information about specified checkout.

### How to verify the `signature`

Signature is created by few steps. First step is to create string concatenated with character `|` by joining arguments in following order:

1. `amount`
2. `currency`
3. `external_id`
4. `nonce`
5. `client_secret` (obtained from merchant's API key)

After this step we should have string that looks like this: `amount|currency|external_id|nonce|client_secret`

Now, we use SHA256 hashing algorithm to hash this string and encode it using Base16 in lowercase. Compare the result with `signature` from the response.

### Checkout statuses:
* `processing` - created payment form
* `requires_capture` - additional authorization requested (if some gateway has additional authorization)
* `succeeded` - from checkout created transaction
* `expired` - no transaction has been created. Expires after the checkout expiration time of your account (by default 10 days after creation)

Other statuses the API can return: `requires_payment_method`, `requires_action`, `requires_authorization`, `requires_3ds`, `pisp_processing`, `awaiting_confirmation`, `cancelled`, `failed`.

### Payment statuses:
* `pending` - this status should not create because the payment card is verified online
* `successful` - confirmation from acquirer that the transaction was successful
* `failed` - confirmation from acquirer that the transaction was failed
* `refunded` - transaction refund (automatically via API)
* `partialy_refunded` - part of the payment was refunded

### Bank transfer statuses:
* `in_transit` - created bank transfer
* `successful` - after reconciliation of the bank statement. (automatic matching)
* `refunded` - transaction refund (manually via IS Payout)
* `partialy_refunded` - part of the transfer was refunded
* `failed`, `expired`

### Funds statuses:
* `pending` - processed transaction, payment affecting pending balance
* `available` - processed transaction, payment affecting available balance
* `onhold`, `canceled`

### 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 · Client order's ID or another ID for reference to reason of 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 user will be redirected after payment form is filled · e.g. https://eshop.example.com/payment/redirect
- `idempotency_key` — string | null · Idempotency key of the request that created the checkout · e.g. 31f0ac6a-9ea6-01a7-7998-720437afb34c
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `checkout_url` — string · URL of payment form for users order. You should redirect user to this URL. · e.g. https://sandbox.payout.one/checkouts/U0ZNeU5UWS5FWEFNUExFLUNIRUNLT1VULVRPS0VOLm5vdC1hLXJlYWwtc2lnbmF0dXJl/?account_id=RVhBTVBMRS1BQ0NPVU5ULVRPS0VOLTAwMDAwMDAwMDA
- `metadata` — object | null · Can be used for payment notation or also for internal use, for example set origin of payment if merchant has more systems. · e.g. {'source': 'eshop'}
- `status` — string · State of checkout, for more information check Checkout statuses · one of processing, requires_payment_method, requires_action, requires_authorization, requires_capture, requires_3ds, pisp_processing, awaiting_confirmation, succeeded, expired, cancelled, failed · e.g. processing
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `signature` — string · Response signature · e.g. 5a940ff7f1698f5d334527951519c84fa104c77ecf6691936093835bcac14d52
- `payment` — object · Most recent payment or bank transfer (a successful one is preferred), `null` if there is none. See Section with Payment Attributes
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `all_payments` — object[] · All payments and bank transfers of the checkout
  - `object` — string · Object type · one of payment, bank_transfer · e.g. payment
  - `status` — string · State of payment, for more information check Payment statuses and Bank transfer statuses · one of pending, in_transit, successful, failed, expired, refunded, partialy_refunded · e.g. successful
  - `payment_method` — string · Payment method identificator · 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 · State of funds, for more information check Funds statuses · one of pending, available, onhold, canceled · e.g. available
  - `fee` — integer · Fee amount in cents · e.g. 30
  - `net` — integer · Net is what remains after subtracting all fees (in cents) · e.g. 1020
  - `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 the Checkout verification webhook guide).
    - `name` — string · 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.
    - `iban` — string · e.g. <encrypted>
- `billing_address` — object · 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 · 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[] · Ordered products, `null` if not 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

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/v1/checkouts/{checkout_id}' \
  -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 if a product or service is not delivered. Only checkouts for which the `checkout.captured` webhook was not triggered can be cancelled.

On success the checkout status changes to `failed` and a `checkout.canceled` webhook is sent.

### Parameters

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

### Example

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


## Capture pre-authorized checkout

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

In the case of card payments, it is possible to authorize a certain order amount (checkout created with `mode` `pre_authorization`) and capture full or only a portion of the funds deposited. This feature needs to be enabled for your account.

Send an empty body to capture the whole pre-authorized amount, or `amount` for a partial capture. After successful capture of funds the `checkout.captured` webhook is sent.

### 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

### Example

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


## Payment instructions (manual bank transfer)

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

Retrieves the data your customer needs to pay a checkout manually via bank transfer — recipient name, IBAN, local account number (CZ/SK), variable symbol, amount, currency and a ready-to-render QR code. No email is sent by this endpoint; it is intended for cases where you want to render the instructions in your own UI.

Bank transfer must be enabled for your account in the checkout's 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...

### Example

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


## Create withdrawal

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

Sends money from your Payout balance to the given IBAN.

Call it on the mTLS host with an approved QWAC, and sign the request with your QSEAL certificate: `Digest` is the SHA-256 of the exact request body, `X-JWS-Signature` a detached JWS over that `Digest` value. How to obtain and import the certificates and how to build the signature is described in [M2M Withdrawals](m2m.md#signing-payment-instructions-with-qseal) and [Certificates](certificates.md#setup).

To perform an idempotent request, provide an additional `Idempotency-Key: <key>` header. If a withdrawal with the same key already exists for your account, it is returned instead of creating a new one.

### Withdrawal statuses:
* `pending` - manualy created withdrawal
* `in_transit` - process withdrawal
* `paid` - processed withdrawal
* `canceled` - cancelled withdrawal
* `failed` - failed withdrawal

### Parameters

- `Idempotency-Key` (header) — Unique key of the request, used to recognize retries of the same request
- `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) · A positive number representing how much to send in the smallest currency unit (e.g. 100 cents to withdraw 1.00€). A numeric string is also accepted. · e.g. 1050
- `currency` — string (required) · Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in uppercase. · e.g. EUR
- `iban` — string (required) · IBAN of the bank account, where the amount will be sent. · e.g. SK3112000000198742637541
- `customer` — object (required) · Object containing customer's information.
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `external_id` — string · Identificator from your system, returned with the withdrawal. · e.g. PAYOUT-2026-0001
- `statement_descriptor` — string · Description that will appear on customer's statement. Only letters without accents, digits, spaces and the characters `/-?:().,'+` are allowed. · e.g. Simple statement description

### 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 · API key ID · e.g. 42
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. EUR
- `external_id` — string · Identificator from your system. · e.g. PAYOUT-2026-0001
- `iban` — string · IBAN · e.g. SK3112000000198742637541
- `idempotency_key` — string | null · Value of the `Idempotency-Key` header of the request that created the withdrawal · e.g. 7c9e6679-7425-40de-944b-e07fc1f90ae7
- `status` — string · State of withdrawal, for more information check Withdrawal statuses · one of pending, in_transit, paid, canceled, failed · e.g. pending
- `metadata` — object · Additional data about the withdrawal · e.g. {}
- `statement_descriptor` — string | null · Description that will appear on customer's statement · e.g. Simple statement description
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. 1759744800
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `signature` — string · Response signature · e.g. cee91937a98c89ea53440e84d367713ba6d196cbd0bf639f15f2f9c05b4762e9

### 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": "Simple statement description"
}'
DIGEST="SHA-256=$(printf %s "$BODY" | openssl dgst -sha256 -binary | base64)"
JWS_SIGNATURE="<detached JWS over $DIGEST>"  # QSEAL key, see M2M Withdrawals: Signing payment instructions with QSEAL

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`

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

### Parameters

- `limit` (query) — Maximum number of withdrawals to return
- `offset` (query) — Number of withdrawals to skip
- `order` (query) — Sort order by 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 · API key ID · e.g. 42
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. EUR
- `external_id` — string · Identificator from your system. · e.g. PAYOUT-2026-0001
- `iban` — string · IBAN · e.g. SK3112000000198742637541
- `idempotency_key` — string | null · Value of the `Idempotency-Key` header of the request that created the withdrawal · e.g. 7c9e6679-7425-40de-944b-e07fc1f90ae7
- `status` — string · State of withdrawal, for more information check Withdrawal statuses · one of pending, in_transit, paid, canceled, failed · e.g. pending
- `metadata` — object · Additional data about the withdrawal · e.g. {}
- `statement_descriptor` — string | null · Description that will appear on customer's statement · e.g. Simple statement description
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. 1759744800
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `signature` — string · Response signature · e.g. cee91937a98c89ea53440e84d367713ba6d196cbd0bf639f15f2f9c05b4762e9

### Example

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


## Retrieve withdrawal

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

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

### How to verify the `signature`

The response carries a `signature` you can check. Join these values with `|`:

1. `amount`
2. `currency`
3. `external_id`
4. `iban`
5. `nonce`
6. `client_secret` (obtained from merchant's API key)

After this step we should have string that looks like this: `amount|currency|external_id|iban|nonce|client_secret`

Now, we use SHA256 hashing algorithm to hash this string and encode it using Base16 in lowercase. Compare the result with `signature` from the response.

### Withdrawal statuses:
* `pending` - manualy created withdrawal
* `in_transit` - process withdrawal
* `paid` - processed withdrawal
* `canceled` - cancelled withdrawal
* `failed` - failed withdrawal

### 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 · API key ID · e.g. 42
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. EUR
- `external_id` — string · Identificator from your system. · e.g. PAYOUT-2026-0001
- `iban` — string · IBAN · e.g. SK3112000000198742637541
- `idempotency_key` — string | null · Value of the `Idempotency-Key` header of the request that created the withdrawal · e.g. 7c9e6679-7425-40de-944b-e07fc1f90ae7
- `status` — string · State of withdrawal, for more information check Withdrawal statuses · one of pending, in_transit, paid, canceled, failed · e.g. pending
- `metadata` — object · Additional data about the withdrawal · e.g. {}
- `statement_descriptor` — string | null · Description that will appear on customer's statement · e.g. Simple statement description
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. 1759744800
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `signature` — string · Response signature · e.g. cee91937a98c89ea53440e84d367713ba6d196cbd0bf639f15f2f9c05b4762e9

### Example

```bash
curl -X GET 'https://api-mtls-sandbox.payout.one/api/v2/withdrawals/{withdrawal_id}' \
  --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`

Cancels a withdrawal that has not been processed yet. Signed with QSEAL like Create withdrawal; the request has no body, so `Digest` is the SHA-256 of an empty body.

On success the response is the cancelled withdrawal. When it can no longer be cancelled, the response is `{"allowed": false, "status": "<current status>"}`, also with status 200. Use Check cancel allowed first if you need to know in advance.

### 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

- `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 · API key ID · e.g. 42
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. EUR
- `external_id` — string · Identificator from your system. · e.g. PAYOUT-2026-0001
- `iban` — string · IBAN · e.g. SK3112000000198742637541
- `idempotency_key` — string | null · Value of the `Idempotency-Key` header of the request that created the withdrawal · e.g. 7c9e6679-7425-40de-944b-e07fc1f90ae7
- `status` — string · State of withdrawal, for more information check Withdrawal statuses · one of pending, in_transit, paid, canceled, failed · e.g. pending
- `metadata` — object · Additional data about the withdrawal · e.g. {}
- `statement_descriptor` — string | null · Description that will appear on customer's statement · e.g. Simple statement description
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. 1759744800
- `nonce` — string · Random data used in the response signature · e.g. ZUc0Mk9sVXZDOXNsdklzMQ
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `signature` — string · Response signature · e.g. cee91937a98c89ea53440e84d367713ba6d196cbd0bf639f15f2f9c05b4762e9

### Example

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

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


## Check cancel allowed

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

Tells whether the withdrawal can still be cancelled. It is a POST and is signed with QSEAL like Cancel withdrawal (empty body).

### 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

- `allowed` — boolean (required) · Whether Cancel withdrawal would succeed now · e.g. True

### Example

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

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


## Refund payment

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

You can initiate refund process with this request. This marks given payment identified by `checkout_id` as refunded and creates a refund to the original customer.

Send `amount` for a partial refund; without it, the whole remaining amount 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.

### How to create the `signature`

Signature is created by few steps. First step is to create string concatenated with character `|` by joining arguments in following order:

1. `amount` (as sent in the request; if you omit `amount`, the checkout amount in cents)
2. `currency` (of the checkout)
3. `external_id` (of the checkout)
4. `iban` (as sent in the request; empty if omitted)
5. `nonce`
6. `client_secret` (obtained from merchant's API key)

After this step we should have string that looks like this: `amount|currency|external_id|iban|nonce|client_secret`

Now, we use SHA256 hashing algorithm to hash this string and encode it using Base16 in lowercase. The signature is now complete and you can send it with the request.

### Refund statuses:
* `pending` - manualy created refund
* `in_transit` - process refund
* `paid` - processed refund
* `canceled` - cancelled refund
* `failed` - failed refund

### Request body

- `checkout_id` — integer (required) · An ID of Checkout received from webhook, after it's been successfuly paid or after you retrieve successful Checkout object · e.g. 141447
- `amount` — integer · Amount to refund in cents (optional). Without it, the whole remaining amount is refunded. · e.g. 500
- `iban` — string · Customer's IBAN (optional). It is part of the `signature`. · e.g. SK3112000000198742637541
- `statement_descriptor` — string · Description which will appear on customer's statement (optional). 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 alpha-numeric string, which will be used when creating `signature`. Max. 64 characters. · e.g. cnd0aXJ0cnVuZXg
- `signature` — string (required) · Hash containing vital information about the refund, that will confirm authenticity of the request. Please refer to section below, if you want to know how to create this signature. · e.g. 2804703f1e9f40f709ac42c691eefddf207e0c16ffa16b9666cdd850d9565d75

### Response 200

- `id` — integer · Refund ID · e.g. 52332
- `object` — string · Object type · e.g. refund
- `amount` — integer · Refunded 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` — string | null · e.g. None
- `customer` — object · Customer details. See Section with Customer attributes
  - `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 (optional). Characters other than digits and `+` are removed. · e.g. +421900000000
  - `note` — string | null · Note about the customer (optional) · e.g. None
- `status` — string · State of refund, for more information check Refund statuses · e.g. pending
- `metadata` — object · e.g. {}
- `statement_descriptor` — string | null · Description which will appear on customer's statement · e.g. Refund for order 1001
- `created_at` — integer · Timestamp (Unix time in seconds) · e.g. 1759744800
- `nonce` — string · Random data used in the response signature · e.g. QjJqWEtiVDBNSmMyTm11dg
- `signature` — string · Response signature · e.g. f0269fef27c86d64f58276b75d169e9f65625fd1ae4f76f2e13db48a492cd4d4

### 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,
       "iban": "SK3112000000198742637541",
       "statement_descriptor": "Refund for order 1001",
       "offer_id": "PREMIUM",
       "nonce": "cnd0aXJ0cnVuZXg",
       "signature": "2804703f1e9f40f709ac42c691eefddf207e0c16ffa16b9666cdd850d9565d75"
     }'
```


## List payment methods

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

You can use this request to retrieve list of payment methods enabled for your account. The `identificator` can be used as `payment_method` when creating a checkout.

### Response 200

- `name` — string · Payment method name · e.g. Card Payment
- `identificator` — string · Payment method identificator · e.g. card
- `fixed_fee` — integer · Fixed fee in cents · e.g. 20
- `percentual_fee` — number · Percentual fee · e.g. 1.5

### Example

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


## Balance of current account

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

Retrieves balance of current account. Keep in mind, that every API key belongs to a specific account.

### Response 200

- `available` — integer · Available balance in cents · e.g. 1567243
- `pending` — integer · Pending balance in cents · e.g. 14768
- `currency` — string · Currency code by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) · e.g. EUR

### Example

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


## Import mTLS certificate

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

Imports a QWAC or QSEAL certificate used by the server-to-server APIs (for example M2M withdrawals). Upload the PEM-encoded certificate — the public part only, never the private key. The certificate must be issued by a QTSP in Payout's trust store.

The certificate starts in status `pending`; Payout verifies it manually and changes the status to `approved` (or `rejected`). See the mTLS client certificates guide.

### Request body

- `type` — string (required) · Certificate profile · one of qwac, qseal · e.g. qwac
- `pem` — string (required) · PEM-encoded certificate · e.g. -----BEGIN CERTIFICATE-----
MIIF...
-----END CERTIFICATE-----


### Response 201

- `thumbprint` — string · SHA-256 fingerprint of the certificate (lowercase hex) · e.g. 103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57
- `type` — string · one of qwac, qseal · e.g. qwac
- `status` — string · one of pending, approved, rejected · e.g. pending
- `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> · e.g. 2026-06-09T06:23:06Z
- `valid_until` — string<date-time> · e.g. 2027-06-09T06:23:06Z
- `rejection_reason` — string | null · e.g. None
- `validated_at` — string<date-time> | null · When Payout approved or rejected the certificate · e.g. None

### 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 mTLS certificates

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

Lists the certificates imported for your account, newest first.

### Response 200

- `data` — object[]
  - `thumbprint` — string · SHA-256 fingerprint of the certificate (lowercase hex) · e.g. 103a697b2fddcad32f63b842fbe48dd47eaf70340edb6df2e6677c7b70889a57
  - `type` — string · one of qwac, qseal · e.g. qwac
  - `status` — string · one of pending, approved, rejected · e.g. approved
  - `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> · e.g. 2027-06-09T06:23:06Z

### Example

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


## Certificate approval status

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

Returns the approval status of one of your certificates. After approval the status changes to `approved` and the certificate becomes usable.

### 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 · one of pending, approved, rejected · e.g. pending
- `rejection_reason` — string | null · Reason of rejection, if the certificate was rejected · e.g. None

### Example

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


## Remove mTLS certificate

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

Removes one of your certificates.

### Parameters

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

### Example

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

