payout / developers
Guide

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

  1. 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 to checkout_url from the response.

    Command Line
    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: 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"
    }'
    

    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-2001|T3hjOURyd0NNOWRZQXd3Vg|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
    SHA-256: 6ea1e196061e9c6270cc87d848515d22f8daba4f86b3f15730f9fe4d4671683e
    

    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 card token

    After a successful payment, Payout sends two webhooks: checkout.succeeded, as in Simple payment, and payu_token.created. The second one carries the masked card number in card_mask and the token of the stored card in token_value. It also contains the card expiry in exp_month and exp_year.

    payu_token.created payload:

    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:

    TEXT
    Pattern: external_id|type|nonce|client_secret
    Input:   order-2001|payu_token.created|Z21yWnhhOTkyR3FzZDFqaA|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
    SHA-256: 6743d5f48f5f035a759a2f0c67d21120eb9634a2e82ac7261351a01c4ae7ef85
    

    Save token_value with the customer's account.

  3. Pay with the stored card

    For the next payment, create a new checkout with "mode": "card_on_file" and the saved token in card_token. Give it its own Idempotency-Key, external_id, nonce and signature.

    Command Line
    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: 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:

    TEXT
    Pattern: amount|currency|external_id|nonce|client_secret
    Input:   300|EUR|order-2002|WFBsWk9HdTJaQTl6eEhHVw|q3dpHpYtDrH-KmGD4HMn5OTEx6IsZPBokQ8CqMONWqMSEePWy9bXd3Ua3KvO7f6C
    SHA-256: 3a32015e39dd0fd5397b4dd7568dfa0be48be4188766e85efa52a6864e2ea326
    
  4. 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_url from the response, where they can confirm the payment.

  5. Wait for the webhook

    After a successful payment, Payout sends checkout.succeeded. Handle it as in Simple payment, steps 7 to 9.

Next steps

Was this page helpful?