# Recurrent payment

Save the customer's card once and charge it later without the customer, for example for a subscription.

## Before you begin

- Recurrent payments 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.

## Steps

1. **Create a checkout that stores the card**

   Create the checkout as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-3), with `"mode": "store_card"` and `"recurring": true`, and redirect the customer to `checkout_url` from the response. `"recurring": true` marks the stored card for recurrent payments. Without it, the card issuer may ask for 3-D Secure on later payments, which fails because the customer isn't there to confirm it.

   ```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: 314261f7-75ea-4e69-bd19-8c790ceb76d3' \
   --data-raw '{
       "amount": 300,
       "currency": "EUR",
       "mode": "store_card",
       "recurring": true,
       "customer": {
           "first_name": "John",
           "last_name": "Doe",
           "email": "john.doe@example.com"
       },
       "external_id": "order-3001",
       "nonce": "QU02YWNWazBKcnAxZWg2eg",
       "redirect_url": "https://eshop.example.com/payment/redirect",
       "signature": "e539cd250d16627408a3017904fac9e85e9141cfd3d4a621050740996f91a859"
   }'
   ```

   `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-3001|QU02YWNWazBKcnAxZWg2eg|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: e539cd250d16627408a3017904fac9e85e9141cfd3d4a621050740996f91a859
   ```

   > [!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 recurrent token**

   After a successful payment, Payout sends two webhooks: `checkout.succeeded`, as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-7), and `payu_token.created`. The second one carries the masked card number in `card_mask` and the recurrent token in `token_value`. It also contains the card expiry in `exp_month` and `exp_year`.

   `payu_token.created` payload:

   ```json
   {
       "external_id": "order-3001",
       "object": "webhook",
       "type": "payu_token.created",
       "data": {
           "object": "payu_token",
           "checkout_id": 141601,
           "card_mask": "424575******9685",
           "token_value": "QTEyOEdDTQ.ZXhhbXBsZS1lbmNyeXB0ZWQta2V5.ZXhhbXBsZS1pdg.ZXhhbXBsZS1jYXJkLXRva2VuLW5vdC1yZWFs.ZXhhbXBsZS10YWc"
       },
       "nonce": "R1NHWGpSUzBzMFM4QXBVVQ",
       "signature": "e06940e780fcdf14039776f6f9e665c71d21ec1e38eda0b1a76b001126e187c2"
   }
   ```

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

   ```text
   Pattern: external_id|type|nonce|client_secret
   Input:   order-3001|payu_token.created|R1NHWGpSUzBzMFM4QXBVVQ|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: e06940e780fcdf14039776f6f9e665c71d21ec1e38eda0b1a76b001126e187c2
   ```

   Save `token_value` with the customer's account.

3. **Charge the card**

   For each recurrent payment, create a new checkout like the one in step 1, with a new `Idempotency-Key` header and these changes in the body:

   ```json
   {
       "mode": "recurrent",
       "recurrent_token": "QTEyOEdDTQ.ZXhhbXBsZS1lbmNyeXB0ZWQta2V5.ZXhhbXBsZS1pdg.ZXhhbXBsZS1jYXJkLXRva2VuLW5vdC1yZWFs.ZXhhbXBsZS10YWc",
       "external_id": "order-3002",
       "nonce": "ZVRVYW5uU3JQM3pCcXdRRQ",
       "signature": "a92120698baf7729dccce17922ab1f614d2411572c3e45a58ceb732cf570f00c"
   }
   ```

   `recurrent_token` is the `token_value` from the `payu_token.created` webhook. The signature is computed from the new values:

   ```text
   Pattern: amount|currency|external_id|nonce|client_secret
   Input:   300|EUR|order-3002|ZVRVYW5uU3JQM3pCcXdRRQ|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
   SHA-256: a92120698baf7729dccce17922ab1f614d2411572c3e45a58ceb732cf570f00c
   ```

   The customer doesn't take part: Payout charges the card in the background, so there is no redirect.

4. **Wait for the result**

   After a successful payment, Payout sends `checkout.succeeded`; handle it as in [Simple payment](https://developers.payout.tech/guides/payment-gateway-use-cases-simple-payment.html#step-7), steps 7 to 9. If the payment fails, Payout sends `recurrent.failed`.

## 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).
- For payments that the customer confirms each time, see [Store card](https://developers.payout.tech/guides/payment-gateway-use-cases-store-card.html).
