# Capture and cancel

Authorize an amount on the customer's card first, then capture all of it or only a part, or cancel the authorization. This helps when some ordered items turn out to be unavailable, or when the final price is lower than the authorized amount, for example for a car rental.

## Before you begin

- Pre-authorization works with card payments and must be enabled for your account; contact support.
- 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.

## Capture

1. **Create a pre-authorization checkout**

   Create the checkout as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-3), with `"mode": "pre_authorization"` and the amount you want to authorize, and redirect the customer to `checkout_url` from the response.

   ```bash
   curl --location --request POST 'https://sandbox.payout.one/api/v1/checkouts' \
   --header 'Content-Type: application/json' \
   --header 'Accept: application/json' \
   --header 'Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU' \
   --header 'Idempotency-Key: 77746fd3-3b82-491f-9fe7-8612e6314a45' \
   --data-raw '{
       "amount": 300,
       "currency": "EUR",
       "mode": "pre_authorization",
       "customer": {
           "first_name": "John",
           "last_name": "Doe",
           "email": "john.doe@example.com"
       },
       "external_id": "order-4001",
       "nonce": "MnFLUkdUWENlWTdqVHdRUg",
       "redirect_url": "https://eshop.example.com/payment/redirect",
       "signature": "f956eb7122d8a1822a4c7daaa84bb71a2a3de5e02f3f0da84cc3c79f67598558"
   }'
   ```

   `amount` is in cents: 300 is 3.00 EUR. Sign the request as in Simple payment:

   ```text
   Pattern: amount|currency|external_id|nonce|client_secret
   Input:   300|EUR|order-4001|MnFLUkdUWENlWTdqVHdRUg|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: f956eb7122d8a1822a4c7daaa84bb71a2a3de5e02f3f0da84cc3c79f67598558
   ```

   > [!NOTE]
   > Signatures are SHA-256 hashes in lowercase hex. Some libraries return uppercase hex; convert it to lowercase before you send or compare it.

2. **Receive the `checkout.pre_authorized` webhook**

   When the customer authorizes the amount, Payout sends `checkout.pre_authorized` to your notify URL. Nothing is charged yet: `is_status_final` is `false` because the checkout can still be captured or cancelled. Use `type` to tell this webhook apart from a completed payment.

   `checkout.pre_authorized` payload:

   ```json
   {
       "external_id": "order-4001",
       "object": "webhook",
       "type": "checkout.pre_authorized",
       "data": {
           "object": "checkout",
           "id": 141701,
           "external_id": "order-4001",
           "amount": 300,
           "currency": "EUR",
           "redirect_url": "https://eshop.example.com/payment/redirect",
           "customer": {
               "first_name": "John",
               "last_name": "Doe",
               "email": "john.doe@example.com",
               "card_number_masked": ""
           },
           "payment": null,
           "metadata": {},
           "status": "succeeded",
           "is_status_final": false
       },
       "nonce": "WnF1bXBtMDhoc0U4Sk5wag",
       "signature": "b40cd606d4867aba4e8b56ce0ab2b377f92b4e96f18b5fbf9390ab37fc97880d"
   }
   ```

   Verify the signature as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-8):

   ```text
   Pattern: external_id|type|nonce|client_secret
   Input:   order-4001|checkout.pre_authorized|WnF1bXBtMDhoc0U4Sk5wag|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: b40cd606d4867aba4e8b56ce0ab2b377f92b4e96f18b5fbf9390ab37fc97880d
   ```

3. **Capture the funds**

   Charge the customer's card with the whole authorized amount or a part of it: send one of these requests with the checkout `id` in the path.

   Full capture, with an empty body:

   ```bash
   curl --location --request POST 'https://sandbox.payout.one/api/v1/checkouts/141701/capture' \
   --header 'Content-Type: application/json' \
   --header 'Accept: application/json' \
   --header 'Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU' \
   --data-raw '{}'
   ```

   Partial capture, with `amount` in cents. It can't be larger than the authorized amount.

   ```bash
   curl --location --request POST 'https://sandbox.payout.one/api/v1/checkouts/141701/capture' \
   --header 'Content-Type: application/json' \
   --header 'Accept: application/json' \
   --header 'Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU' \
   --data-raw '{
       "amount": 150
   }'
   ```

   A successful capture responds with:

   ```json
   "captured"
   ```

4. **Receive the `checkout.captured` webhook**

   After the funds are captured, Payout sends `checkout.captured`. The `amount` in its payload is the captured amount.

## Cancel

> [!WARNING]
> You can cancel only a checkout for which the `checkout.captured` webhook was not sent.

Cancel a pre-authorized checkout when you won't charge the customer, for example because a product or service can't be delivered. The authorized amount is released and the customer isn't charged.

Send a `DELETE` request with the checkout `id` in the path:

```bash
curl --location --request DELETE 'https://sandbox.payout.one/api/v1/checkouts/141701' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer SFMyNTY.EXAMPLE-TOKEN.dGhpcy1pcy1hLWZha2Utc2lnbmF0dXJlLWV4YW1wbGU'
```

A successful cancellation responds with `"pre-auth canceled"`. The checkout `status` changes to `failed` and Payout sends a `checkout.canceled` webhook.

## Next steps

- Try the flow in the sandbox with the [test cards](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#test-cards).
- To return money after a capture, create a [refund](https://developers.payout.tech/guides/payment-gateway-use-cases-refund.html).
