# Refund

Return the money of a paid checkout to the customer, in full or in part.

## Before you begin

- An API key and a Bearer token, as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-1), steps 1 and 2.
- The `id`, `currency` and `external_id` of the paid checkout. They are in the [create checkout response](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-4) and in the `checkout.succeeded` webhook.

## Steps

1. **Create the refund**

   Send the checkout `id` as `checkout_id`. `amount` is optional: leave it out to refund the whole remaining amount, or send it in cents for a partial refund. Depending on the payment method, only a full refund may be possible.

   This request refunds 1.00 EUR of the 3.00 EUR checkout from [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html):

   ```bash
   curl --location --request POST 'https://sandbox.payout.one/api/v1/refunds' \
   --header 'Content-Type: application/json' \
   --header 'Accept: application/json' \
   --header 'Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU' \
   --data-raw '{
       "checkout_id": 141447,
       "amount": 100,
       "iban": "SK3112000000198742637541",
       "statement_descriptor": "Refund for order 1001",
       "nonce": "YmNHNzliRGhPMnNkNXVPZA",
       "signature": "755b4f84704efd8e69c4acf727f5f2f4a259f21163357e14ec2ac6ff014f45c3"
   }'
   ```

   [Refund payment](https://developers.payout.tech/api/payment.html#refund_payment) lists all fields.

   The `signature` combines values from the request with values of the checkout:

   - `amount`: as sent in the request; if you leave it out, the checkout amount in cents
   - `currency` and `external_id`: of the checkout; you don't send them in the request
   - `iban`: as sent in the request; an empty string if you leave it out
   - `nonce`: as sent in the request
   - `client_secret`: of your API key

   Join them with `|` and hash the string with SHA-256:

   ```text
   Pattern: amount|currency|external_id|iban|nonce|client_secret
   Input:   100|EUR|order-1001|SK3112000000198742637541|YmNHNzliRGhPMnNkNXVPZA|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: 755b4f84704efd8e69c4acf727f5f2f4a259f21163357e14ec2ac6ff014f45c3
   ```

   Without `amount` and `iban`, the input for the same checkout would be `300|EUR|order-1001||YmNHNzliRGhPMnNkNXVPZA|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C`.

   > [!NOTE]
   > Send the hash in lowercase hex. Some libraries return uppercase hex; convert it to lowercase.

2. **Check the response**

   The response is the new refund. It starts with `status` `pending`.

   ```json
   {
       "id": 52332,
       "object": "refund",
       "amount": 100,
       "currency": "EUR",
       "external_id": "order-1001",
       "idempotency_key": null,
       "customer": {
           "first_name": "John",
           "last_name": "Doe",
           "name": "John Doe",
           "email": "john.doe@example.com",
           "phone": "+421900000000",
           "note": null
       },
       "status": "pending",
       "metadata": {},
       "statement_descriptor": "Refund for order 1001",
       "created_at": 1759748400,
       "nonce": "Rzd5R1U2emlvSTlKeU85aQ",
       "signature": "91ed0b376d9305eb86583790d0f7699454f6f583ec8888e3192db11332773c8e"
   }
   ```

   Payout also sends a `checkout.refund_requested` webhook to your notify URL.

## Next steps

- Errors such as an unpaid or already refunded checkout are listed in [Refund payment](https://developers.payout.tech/api/payment.html#refund_payment).
- For checkouts split by `offer_id`, see [Transaction splitting](https://developers.payout.tech/guides/transaction-splitting.html#refund-handling).
