Payment Instruments

Save cards on file as payment instruments and reuse them for repeat charges, subscriptions, and other merchant-initiated transactions.

A payment instrument is a saved payment method — typically a card — kept on file for a customer so you can charge it again without re-collecting card data. Instruments are the backbone of repeat purchases, one-click upsells, and merchant-initiated charges such as subscription renewals.

Tokeflow stores only a non-sensitive reference and metadata for each instrument (pi_…, brand, last 4, expiry). The card itself is encrypted at collection time and is never handled by your servers.

Tokeflow is a payment orchestration platform. It does not process or settle funds — your connected payment providers do. A payment instrument is an orchestration-level reference that lets Tokeflow route a saved-card charge to the right provider on your behalf.

How instruments come to exist

You never create a payment instrument by sending raw card numbers to the API. The card is always collected by the Bridge SDK in the browser, and the ciphertext it returns must be minted for enrollment — purpose: 'instrument_enrollment' (standalone) or saveCard: true (inside a checkout session). See Tokenization → Options. From there, an instrument is created in one of three ways:

PathWhen to use itWhat happens
Zero-dollar verification — POST /sessions/:sessionId/payment-instruments or a transaction with charge_type: "setup_verification"Save a card without billing it — a billing portal, a free trial.The provider verifies the card (and runs 3DS where applicable) without capturing money, then the instrument is stored.
Save while charging — POST /transactions with save_payment_instrument: trueA one-time purchase after which you want to offer one-click upsells.The instrument is created before routing, the submitted ciphertext is charged, and the provider's reusable credential is kept on the approving connector. The response carries payment_instrument_id.
Checkout session — the session's save_card flag, or a recurring offerHosted or SDK-driven checkouts.The session enrolls the card itself; the charge response carries payment_instrument_id.

The POST /merchants/:merchant_id/payment-instruments endpoint below stores an enrollment ciphertext directly, without a verification or a charge. An instrument created that way exists, but holds no provider credential until one successful cardholder-present charge or card verification runs through it — so it cannot be charged with credential_on_file yet.

The card-collection and enrollment flow is a client-side concern handled entirely by the Bridge SDK. See the SDK overview and card enrollment guides for the browser implementation. This page covers the server-side REST API for managing and using instruments after they exist.

:::tip Secure card collection Tokeflow's secure fields run inside isolated, cross-origin iframes. Card data is encrypted in the browser and never touches your servers, so a payment instrument is the only card reference your backend ever sees. :::

How instruments are used

Once an instrument exists, reference it by id wherever a saved card can be charged:

  • One-click charges — pass payment_instrument_id with credential_on_file: true to POST /api/v1/transactions. The charge uses the provider credential kept at enrollment — no card data, no CVV. See Stored-credential charges.
  • Saved card with a re-typed CVV — pass payment_instrument_id together with a fresh card_ciphertext_id for the same card, when you want a cardholder-present charge (3DS possible).
  • Subscriptions — set or change the card a subscription bills against via change-payment-instrument. Future renewals run as merchant-initiated charges against the new instrument.
{
  "payment_method": "credit_card",
  "charge_type": "payment",
  "country": "BR",
  "customer_id": "cust_john_01",
  "payment_instrument_id": "pi_a1b2c3",
  "credential_on_file": true,
  "amount": 15000,
  "currency": "BRL"
}

payment_instrument_id alone is refused with 400: the request must say how the card is presented — credential_on_file: true for a one-click charge, or a fresh card_ciphertext_id for a re-typed CVV.

The payment instrument object

FieldTypeDescription
idstringUnique identifier, prefixed pi_.
merchant_idstringMerchant that owns the instrument (mrc_…).
customer_idstringCustomer the instrument belongs to (cust_…).
instrument_typestringInstrument family. Currently card.
card_brandstring | nullCard brand, e.g. visa, mastercard, amex.
card_typestring | nullcredit or debit.
last4string | nullLast 4 digits of the card.
binstring | nullIssuer identification number (6- or 8-digit).
issuer_countrystring | nullISO 3166-1 alpha-2 country of the issuer.
exp_monthinteger | nullCard expiration month (1–12).
exp_yearinteger | nullCard expiration year (4-digit).
statusstringactive, expired, or revoked.
created_atstringCreation timestamp (ISO 8601 UTC).

Full card data is never stored by you. A payment instrument is only a stable reference (pi_…) plus non-sensitive metadata — brand, last 4, expiry, and issuer details. The primary account number cannot be read back through the API.

Status values

StatusMeaning
activeUsable for charges.
expiredPast the card's expiration date; cannot be charged.
revokedDisabled for security or compliance reasons; cannot be charged.

Example object

{
  "id": "pi_a1b2c3",
  "merchant_id": "mrc_123",
  "customer_id": "cust_john_01",
  "instrument_type": "card",
  "card_brand": "visa",
  "card_type": "credit",
  "last4": "4242",
  "bin": "424242",
  "issuer_country": "BR",
  "exp_month": 12,
  "exp_year": 2028,
  "status": "active",
  "created_at": "2026-01-15T12:30:00.000Z"
}

Endpoints

All instrument endpoints are merchant-scoped and live under a merchant path.

  • Merchant key — the merchant is inferred from the key; supply your merchant id in the path.
  • Organization key — pass the target merchant id in the path; the org key must have access to that merchant.

Required scopes: instruments:read for reads, instruments:write for mutations.

POST/api/v1/merchants/:merchant_id/payment-instruments

OrgMerchant

Auth: Organization key (with merchant_id) or Merchant key.

Stores a tokenized instrument against a customer. Enrollment is deduplicated: re-sending a token that already resolves to a stored instrument returns the existing one with deduplicated: true and a 200 instead of creating a duplicate.

Path parameters

FieldTypeRequiredDescription
merchant_idstringYes—

Request fields

FieldTypeRequiredDescription
customer_idstringYesFK → customers. Must belong to this merchant.
card_ciphertext_idstringYesThe encrypted card reference (tok_…) returned by the Bridge SDK, minted with purpose=instrument_enrollment (or saveCard: true inside a checkout session). A one_time ciphertext is refused with 400.
metadataobjectNoOptional customer or billing-address details for the enrollment.

Example request

curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/payment-instruments \
  -H "Authorization: Bearer sk_live_mer_…" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_2f9a71d4",
    "card_ciphertext_id": "tok_8f3c2a1b9d4e",
    "metadata": {}
  }'

Example response — 200

{
  "id": "pi_123",
  "merchant_id": "mrc_123",
  "customer_id": "cust_john_01",
  "card_brand": "visa",
  "card_type": "credit",
  "instrument_type": "card",
  "last4": "4242",
  "bin": "424242",
  "issuer_country": "BR",
  "exp_month": 12,
  "exp_year": 2028,
  "status": "active",
  "deduplicated": false,
  "created_at": "2025-11-20T10:00:00Z"
}

GET/api/v1/merchants/{merchant_id}/payment-instruments

List a merchant's payment instruments. Supports pagination and filtering.

Auth: Organization key (scoped to the merchant) or Merchant key.

Query parameters

FieldTypeRequiredDescription
customer_idstringNoFilter to one customer's instruments.
statusstringNoFilter by active, expired, or revoked.
card_brandstringNoFilter by brand, e.g. visa.
card_typestringNoFilter by credit or debit.
last4stringNoFilter by last 4 digits.
binstringNoFilter by issuer identification number.
issuer_countrystringNoFilter by ISO 3166-1 alpha-2 issuer country.
pageintegerNoPage number (default 1, min 1).
limitintegerNoItems per page (default 20, max 100).
curl "https://api.tokeflow.com/api/v1/merchants/mrc_123/payment-instruments?customer_id=cust_john_01&status=active&limit=20" \
  -H "Authorization: Bearer sk_live_mer_xxx"

Response 200 OK

{
  "success": true,
  "data": [
    {
      "id": "pi_a1b2c3",
      "merchant_id": "mrc_123",
      "customer_id": "cust_john_01",
      "instrument_type": "card",
      "card_brand": "visa",
      "card_type": "credit",
      "last4": "4242",
      "bin": "424242",
      "issuer_country": "BR",
      "exp_month": 12,
      "exp_year": 2028,
      "status": "active",
      "created_at": "2026-01-15T12:30:00.000Z"
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 1,
      "total_pages": 1,
      "has_next": false,
      "has_prev": false
    }
  },
  "request_id": "req_8f3c2a",
  "timestamp": "2026-01-15T12:30:00.000Z"
}

Use customer_id plus status=active to render a customer's wallet — for example, the saved cards shown at checkout or in a billing portal.

PATCH/api/v1/merchants/{merchant_id}/payment-instruments/{payment_instrument_id}

Update an instrument's status. The status is the only mutable field.

Auth: Organization key (scoped to the merchant) or Merchant key.

Body

FieldTypeRequiredDescription
statusstringYesNew status: active, expired, or revoked.
curl -X PATCH \
  "https://api.tokeflow.com/api/v1/merchants/mrc_123/payment-instruments/pi_a1b2c3" \
  -H "Authorization: Bearer sk_live_mer_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "status": "revoked" }'

Response 200 OK

{
  "success": true,
  "data": {
    "id": "pi_a1b2c3",
    "merchant_id": "mrc_123",
    "customer_id": "cust_john_01",
    "instrument_type": "card",
    "card_brand": "visa",
    "card_type": "credit",
    "last4": "4242",
    "bin": "424242",
    "issuer_country": "BR",
    "exp_month": 12,
    "exp_year": 2028,
    "status": "revoked",
    "created_at": "2026-01-15T12:30:00.000Z"
  },
  "request_id": "req_91ad04",
  "timestamp": "2026-01-15T12:31:00.000Z"
}

DELETE/api/v1/merchants/{merchant_id}/payment-instruments/{payment_instrument_id}

Revoke an instrument. After revocation it can no longer be charged. Active subscriptions billing against it must be moved to another instrument first.

Auth: Organization key (scoped to the merchant) or Merchant key.

curl -X DELETE \
  "https://api.tokeflow.com/api/v1/merchants/mrc_123/payment-instruments/pi_a1b2c3" \
  -H "Authorization: Bearer sk_live_mer_xxx"

Response 204 No Content

HTTP/1.1 204 No Content

Revoking an instrument is permanent. If a subscription still bills against it, move the subscription to another instrument with change-payment-instrument before revoking, or its next renewal will fail.

Errors

Failures use the standard error envelope.

HTTPTypeWhen
401authentication_errorMissing or invalid API key.
403authorization_errorKey lacks the required scope, or the org key cannot access this merchant.
404not_found_errorInstrument or merchant not found.
422business_rule_errorStatus transition not allowed (e.g. reactivating a revoked instrument).
{
  "error": {
    "type": "not_found_error",
    "code": "PAYMENT_INSTRUMENT_NOT_FOUND",
    "message": "Payment instrument pi_a1b2c3 was not found for this merchant.",
    "details": {},
    "request_id": "req_8f3c2a",
    "timestamp": "2026-01-15T12:30:00.000Z"
  }
}

On this page