Skip to content

Stored credentials

Stored credentials let a merchant reuse a card the customer has agreed to keep on file — for card-on-file checkout, recurring billing, or installment plans. Card networks require that these transactions carry extra intent signals: who initiated the payment (the cardholder or the merchant), whether it is the first time the credential is stored or a later reuse, and a scheme reference that links each reuse back to the transaction where the customer first consented.

Paygasus surfaces all of this on the existing card payment intent flow — there are no new endpoints. You add an optional stored_credential object when you create the intent, and Paygasus returns the issuer’s scheme reference after a successful authorization so you can pass it back on the next payment.

Include this object in the POST /payments/card create request. Every field is optional at the schema level, but scheme_reference_transaction_id becomes required for subsequent transactions — see the validation rule below.

Field Type Description
initiator string Who triggered the payment. "cardholder" for a customer-initiated transaction (CIT), "merchant" for a merchant-initiated transaction (MIT).
sequence string "first" when the credential is being stored for the first time, "subsequent" when reusing a previously stored credential.
scheduled boolean Optional. Set to true for a planned, recurring charge (e.g. a subscription cycle). Omit or false for one-off use of a stored credential.
scheme_reference_transaction_id string Optional in general, required when sequence is "subsequent". The value returned in a prior transaction’s response — it ties this reuse back to the original consent.

The CardPaymentIntentResponse (returned by create, get, authorize, and commit) gains two related fields:

Field Type Description
stored_credential object Echoes the object you supplied on create, so every read of the intent shows how it was flagged.
scheme_reference_transaction_id string The issuer scheme reference assigned after a successful authorize/sale. Store this — you pass it back as stored_credential.scheme_reference_transaction_id on the next subsequent transaction.

The pattern is a first transaction that stores the credential, followed by any number of subsequent transactions that reference it. This walk-through covers the cardholder-initiated case: the customer is present for both the initial store and the reuse.

  1. Create the initial intent, flagged as first. Add the stored_credential object with initiator: "cardholder" and sequence: "first". Amounts are integers in the currency’s minor units — 1000 is $10.00.

    Create the first stored-credential intent
    curl https://api.paygasus.com/payments/card \
    -H "Authorization: Bearer sk_test_…" \
    -H "Content-Type: application/json" \
    -d '{
    "amount": 1000,
    "currency": "USD",
    "capture_method": "automatic",
    "description": "initial card-on-file charge",
    "stored_credential": {
    "initiator": "cardholder",
    "sequence": "first"
    }
    }'

    The intent comes back in the created state. stored_credential echoes your input, and scheme_reference_transaction_id is null — the issuer does not assign it until the payment is authorized:

    201 Created
    {
    "id": "pi_card_9Z3K01ARZ3NDEKTSV4RRFFQ69G5FAV",
    "amount": 1000,
    "amount_captured": 0,
    "amount_refunded": 0,
    "currency": "USD",
    "status": "created",
    "capture_method": "automatic",
    "payment_method": null,
    "stored_credential": {
    "initiator": "cardholder",
    "sequence": "first"
    },
    "scheme_reference_transaction_id": null,
    "description": "initial card-on-file charge",
    "metadata": {},
    "created": 1746500000,
    "updated": 1746500000,
    "livemode": false
    }
  2. Authorize with the encrypted card block. This is the same authorize step as the Quickstart — attach the client-side encrypted card block. The customer is present and consenting, which is what makes this a valid credential-storage transaction.

    Authorize the intent
    curl -X POST https://api.paygasus.com/payments/card/pi_card_9Z3K01ARZ3NDEKTSV4RRFFQ69G5FAV/authorize \
    -H "Authorization: Bearer sk_test_…" \
    -H "Content-Type: application/json" \
    -d '{
    "payload": "eyJhbGciOiJSU0Et…ENCRYPTED…",
    "key_id": "cek_…",
    "layout": [{ "field": "Pan", "len": 16 }, { "field": "Cvc", "len": 3 }]
    }'

    On success the processor returns the issuer scheme reference, which Paygasus surfaces as scheme_reference_transaction_id:

    200 OK
    {
    "id": "pi_card_9Z3K01ARZ3NDEKTSV4RRFFQ69G5FAV",
    "amount": 1000,
    "amount_captured": 1000,
    "amount_refunded": 0,
    "currency": "USD",
    "status": "committed",
    "capture_method": "automatic",
    "payment_method": { "brand": "visa", "last4": "0019" },
    "stored_credential": {
    "initiator": "cardholder",
    "sequence": "first"
    },
    "scheme_reference_transaction_id": "MCC1234567890ABCDE",
    "processor_ref": "ch_0k2f8a91b3",
    "description": "initial card-on-file charge",
    "metadata": {},
    "created": 1746500000,
    "updated": 1746500071,
    "livemode": false
    }
  3. Persist the scheme reference. Store scheme_reference_transaction_id (MCC1234567890ABCDE above) against the customer’s saved payment method on your side. This is the link the networks require between the consent and every future reuse.

  4. Create the next payment as subsequent. When the customer returns (or you charge the stored card again), create a fresh intent with sequence: "subsequent" and pass the stored reference back in scheme_reference_transaction_id.

    Create a subsequent stored-credential intent
    curl https://api.paygasus.com/payments/card \
    -H "Authorization: Bearer sk_test_…" \
    -H "Content-Type: application/json" \
    -d '{
    "amount": 2500,
    "currency": "USD",
    "capture_method": "automatic",
    "description": "repeat card-on-file charge",
    "stored_credential": {
    "initiator": "cardholder",
    "sequence": "subsequent",
    "scheme_reference_transaction_id": "MCC1234567890ABCDE"
    }
    }'

    Authorize this intent exactly as before. Each authorized transaction can return its own scheme reference — follow the issuer’s guidance on whether to keep chaining from the original reference or update to the most recent one.

Validation: subsequent requires a reference

Section titled “Validation: subsequent requires a reference”

When sequence is "subsequent", scheme_reference_transaction_id is mandatory. Creating a subsequent intent without it is rejected at create time with a 400 and the standard error envelope:

400 Bad Request
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "stored_credential.scheme_reference_transaction_id is required when sequence is 'subsequent'",
"param": "stored_credential.scheme_reference_transaction_id"
}
}

Branch on error.param to identify the offending field, not the message. A "first" transaction never requires the reference — you have nothing to chain from yet.

  • Review the Quickstart for the create → authorize → commit lifecycle these examples build on.
  • See Client-side card encryption for building the encrypted block attached at authorize.
  • Browse the full API reference for every field on the card payment intent.