Store card
On this page
Save the customer's card during a payment and use it for later payments that the customer confirms on the Payout payment page.
Before you begin
- Storing cards 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": false, and redirect the customer tocheckout_urlfrom the response.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: 32737315-b1ee-4668-90ca-67f61c2498b4' \ --data-raw '{ "amount": 300, "currency": "EUR", "mode": "store_card", "recurring": false, "customer": { "first_name": "John", "last_name": "Doe", "email": "[email protected]" }, "external_id": "order-2001", "nonce": "T3hjOURyd0NNOWRZQXd3Vg", "redirect_url": "https://eshop.example.com/payment/redirect", "signature": "6ea1e196061e9c6270cc87d848515d22f8daba4f86b3f15730f9fe4d4671683e" }'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-2001|T3hjOURyd0NNOWRZQXd3Vg|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: 6ea1e196061e9c6270cc87d848515d22f8daba4f86b3f15730f9fe4d4671683eNote
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 card 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 token of the stored card intoken_value. It also contains the card expiry inexp_monthandexp_year.payu_token.createdpayload:JSON{ "external_id": "order-2001", "object": "webhook", "type": "payu_token.created", "data": { "object": "payu_token", "checkout_id": 141501, "card_mask": "424575******9685", "token_value": "QTEyOEdDTQ.ZXhhbXBsZS1lbmNyeXB0ZWQta2V5.ZXhhbXBsZS1pdg.ZXhhbXBsZS1jYXJkLXRva2VuLW5vdC1yZWFs.ZXhhbXBsZS10YWc" }, "nonce": "Z21yWnhhOTkyR3FzZDFqaA", "signature": "6743d5f48f5f035a759a2f0c67d21120eb9634a2e82ac7261351a01c4ae7ef85" }Verify the signature of both webhooks as in Simple payment. For this webhook:
TEXTPattern: external_id|type|nonce|client_secret Input: order-2001|payu_token.created|Z21yWnhhOTkyR3FzZDFqaA|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: 6743d5f48f5f035a759a2f0c67d21120eb9634a2e82ac7261351a01c4ae7ef85Save
token_valuewith the customer's account. -
Pay with the stored card
For the next payment, create a new checkout with
"mode": "card_on_file"and the saved token incard_token. Give it its ownIdempotency-Key,external_id,nonceandsignature.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: 0a38d06d-164e-43fd-ba6b-19d30c64ee41' \ --data-raw '{ "amount": 300, "currency": "EUR", "mode": "card_on_file", "card_token": "QTEyOEdDTQ.ZXhhbXBsZS1lbmNyeXB0ZWQta2V5.ZXhhbXBsZS1pdg.ZXhhbXBsZS1jYXJkLXRva2VuLW5vdC1yZWFs.ZXhhbXBsZS10YWc", "customer": { "first_name": "John", "last_name": "Doe", "email": "[email protected]" }, "external_id": "order-2002", "nonce": "WFBsWk9HdTJaQTl6eEhHVw", "redirect_url": "https://eshop.example.com/payment/redirect", "signature": "3a32015e39dd0fd5397b4dd7568dfa0be48be4188766e85efa52a6864e2ea326" }'Signature of this request:
TEXTPattern: amount|currency|external_id|nonce|client_secret Input: 300|EUR|order-2002|WFBsWk9HdTJaQTl6eEhHVw|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C SHA-256: 3a32015e39dd0fd5397b4dd7568dfa0be48be4188766e85efa52a6864e2ea326 -
Redirect the customer to confirm the payment
Depending on the amount, a payment with a stored card may go through without 3-D Secure. This is not guaranteed, and 3-D Secure is more likely to be required. Always redirect the customer to
checkout_urlfrom the response, where they can confirm the payment. -
Wait for the webhook
After a successful payment, Payout sends
checkout.succeeded. Handle it as in Simple payment, steps 7 to 9.
Next steps
- Try the flow in the sandbox with the test cards.
- To charge a stored card without the customer, see Recurrent payment.
- Need help? Contact support.
- Questions? Contact sales.
- Service status? status.payout.one.
- LLM? Read llms.txt.