Skip to main content

Attach a token to a customer

A tokenization call returns a short-lived token. Before you can charge the customer, you attach that token to a customer record. The attach call creates a payment instrument on the customer, consuming the token in the process.

To choose between FramePay and the server-side endpoint, see When to use what. For the full lifecycle of a token, including creation, expiry, and consumption details, see Token lifecycle.

Flow overview

Attach call

curl --location \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/customers/${CUSTOMER_ID}/payment-instruments" \
--header "Content-Type: application/json" \
--header "Authorization: ApiKey ${API_KEY}" \
--data '{
"token": "Token value from tokenization step"
}'

Replace staging-api.payments.ai with api.payments.ai for production environments.

The response returns a PaymentInstrument object. Its id field contains the value you pass as the paymentInstrumentId parameter on subsequent POST /transactions and POST /subscriptions requests.

{
"id": "c114b68a-432e-4e94-b8ba-1658ef3258e2",
"type": "payment-card",
"creditCard": { "creditCardLastFourDigits": "1234", "brand": "visa", "expireYear": 2034, "expireMonth": 12 },
"billingAddress": { ... }
}

Using the new payment instrument: paymentInstruction variants

Once you have the id from the attach response, you can charge the account using one of two methods. Pick the variant that matches your workflow.

Variant A: Fresh token (guest, not attached)

For a one-off charge from a token that was not attached to a customer (typical guest checkout):

"paymentInstruction": { "token": "<framepay-or-tokenization-token-id>" }

The token is consumed directly by the transaction itself. No separate attach step is required.

Variant B: Saved payment instrument (attached)

For a returning customer charged against a payment instrument already on file:

"paymentInstruction": { "paymentInstrumentId": "<id-from-attach-response>" }

The paymentInstrumentId uses the exact id field returned by POST /customers/{id}/payment-instruments above. This same identifier applies to POST /subscriptions when starting a recurring charge.

Use Variant A for stateless one-time charges. Use Variant B for subscriptions and any flow where the customer maintains a saved instrument.

What happens on attach

  • The token is consumed and cannot be reused for another attach call.
  • A payment instrument is created on the customer record in an inactive state. PaymentsAI does not auto-charge inactive instruments; the instrument transitions to active only after the customer completes their first payment on the hosted payment form. See Payment instrument lifecycle.
  • If the attach call fails due to token expiration, network drops, or validation errors, the token cannot be reused. You must re-tokenize the card to obtain a new one.

Common mistakes

MistakeResult
Reusing a token across two attach callsThe second call returns an error because the token was consumed by the first call.
Sending the token after its expirationTime has passedThe attach call fails. You must re-tokenize the card.
Treating the new paymentInstrumentId as auto-chargeableSubscriptions created against an inactive instrument return a status: "pending" response and require an initial hosted-form payment. See Subscription troubleshooting.