Recurrent payment
On this page
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, steps 1 and 2.
Steps
-
Create a checkout that stores the card
Create the checkout as in Simple payment, with
"mode": "store_card"and"recurring": true, and redirect the customer tocheckout_urlfrom the response."recurring": truemarks 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.Command Linecurl --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": "[email protected]" }, "external_id": "order-3001", "nonce": "QU02YWNWazBKcnAxZWg2eg", "redirect_url": "https://eshop.example.com/payment/redirect", "signature": "e539cd250d16627408a3017904fac9e85e9141cfd3d4a621050740996f91a859" }'amountis in cents: 300 is 3.00 EUR. Sign the request as in Simple payment:TEXTPattern: amount|currency|external_id|nonce|client_secret Input: 300|EUR|order-3001|QU02YWNWazBKcnAxZWg2eg|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: e539cd250d16627408a3017904fac9e85e9141cfd3d4a621050740996f91a859Note
Signatures are SHA-256 hashes in lowercase hex. Some libraries return uppercase hex; convert it to lowercase before you send or compare it.
-
Receive the recurrent token
After a successful payment, Payout sends two webhooks:
checkout.succeeded, as in Simple payment, andpayu_token.created. The second one carries the masked card number incard_maskand the recurrent token intoken_value. It also contains the card expiry inexp_monthandexp_year.payu_token.createdpayload: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. For this webhook:
TEXTPattern: external_id|type|nonce|client_secret Input: order-3001|payu_token.created|R1NHWGpSUzBzMFM4QXBVVQ|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: e06940e780fcdf14039776f6f9e665c71d21ec1e38eda0b1a76b001126e187c2Save
token_valuewith the customer's account. -
Charge the card
For each recurrent payment, create a new checkout like the one in step 1, with a new
Idempotency-Keyheader 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_tokenis thetoken_valuefrom thepayu_token.createdwebhook. The signature is computed from the new values:TEXTPattern: amount|currency|external_id|nonce|client_secret Input: 300|EUR|order-3002|ZVRVYW5uU3JQM3pCcXdRRQ|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: a92120698baf7729dccce17922ab1f614d2411572c3e45a58ceb732cf570f00cThe customer doesn't take part: Payout charges the card in the background, so there is no redirect.
-
Wait for the result
After a successful payment, Payout sends
checkout.succeeded; handle it as in Simple payment, steps 7 to 9. If the payment fails, Payout sendsrecurrent.failed.
Next steps
- Try the flow in the sandbox with the test cards.
- For payments that the customer confirms each time, see Store card.
- Need help? Contact support.
- Questions? Contact sales.
- Service status? status.payout.one.
- LLM? Read llms.txt.