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
activeonly 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
| Mistake | Result |
|---|---|
| Reusing a token across two attach calls | The second call returns an error because the token was consumed by the first call. |
Sending the token after its expirationTime has passed | The attach call fails. You must re-tokenize the card. |
Treating the new paymentInstrumentId as auto-chargeable | Subscriptions created against an inactive instrument return a status: "pending" response and require an initial hosted-form payment. See Subscription troubleshooting. |