Customer Portal payment methods
Let a customer manage their saved payment methods in the portal — list, add, and remove cards using in-browser tokenization.
These endpoints let a signed-in customer manage their own payment methods: list saved instruments, add a new one, and remove one. Adding a card uses the same in-browser tokenization as checkout — card data is encrypted in isolated iframes and never reaches your servers or Tokeflow in the clear.
What the customer sees is the non-sensitive summary — brand, last four, expiry — never the full card. Removing an instrument that a subscription still bills against is guarded so a renewal is not orphaned.
These endpoints power the Customer Portal — the self-service surface your end customers use, under your brand. They are authenticated by a portal session cookie, established through the magic-link flow (request a link, then verify the token), not by an API key. See Sessions & config.
The payment method object
Returned by the list and retrieve endpoints on this page.
| Field | Type | Description |
|---|---|---|
id | string | — |
instrument_type | string | — |
card_brand | string | null | — |
last4 | string | null | — |
exp_month | number | null | — |
exp_year | number | null | — |
is_default | boolean | — |
status | string | — |
Endpoints
GET/api/v1/portal/payment-methods
Auth: Customer Portal session (cookie set by the magic-link flow).
List cards on file.
Example request
curl https://api.tokeflow.com/api/v1/portal/payment-methods \
-H "Cookie: tf_portal_session=…"Example response — 200
{
"data": [
{
"id": "pi_123",
"instrument_type": "card",
"card_brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2027,
"is_default": true,
"status": "active"
}
]
}POST/api/v1/portal/payment-methods
Auth: Customer Portal session (cookie set by the magic-link flow).
Enroll a new card on file.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
card_ciphertext_id | string | Yes | the encryption provider card-ciphertext id from the client SDK. |
Example request
curl -X POST https://api.tokeflow.com/api/v1/portal/payment-methods \
-H "Cookie: tf_portal_session=…" \
-H "Content-Type: application/json" \
-d '{
"card_ciphertext_id": "tok_8f3c2a1b9d4e"
}'Example response — 201
{
"id": "pi_123",
"instrument_type": "card",
"card_brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2027,
"is_default": true,
"status": "active"
}DELETE/api/v1/portal/payment-methods/:id
Auth: Customer Portal session (cookie set by the magic-link flow).
Remove a card on file.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | — |
Example request
curl -X DELETE https://api.tokeflow.com/api/v1/portal/payment-methods/obj_1a2b3c4d \
-H "Cookie: tf_portal_session=…"Example response — 204 No Content
An empty body is returned on success.
POST/api/v1/portal/payment-methods/:id/set-default
Auth: Customer Portal session (cookie set by the magic-link flow).
Set a card as the wallet default.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | — |
Example request
curl -X POST https://api.tokeflow.com/api/v1/portal/payment-methods/obj_1a2b3c4d/set-default \
-H "Cookie: tf_portal_session=…"Example response — 200
{
"id": "pi_123",
"instrument_type": "card",
"card_brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2027,
"is_default": true,
"status": "active"
}POST/api/v1/portal/tokenization/session
Auth: Customer Portal session (cookie set by the magic-link flow).
Start a tokenization session (encryption credentials).
Example request
curl -X POST https://api.tokeflow.com/api/v1/portal/tokenization/session \
-H "Cookie: tf_portal_session=…"Example response — 201
{
"session_id": "sess_...",
"sdk": {
"js_url": "https://vault.tokeflow.com/v2",
"sri_expires_at": 1
},
"expires_at": "2026-01-15T12:30:00.000Z"
}POST/api/v1/portal/tokenization/tokens
Auth: Customer Portal session (cookie set by the magic-link flow).
Register an encrypted card.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | Portal tokenization session id. |
encryptedCard | object | Yes | — |
metadata | object | Yes | — |
Example request
curl -X POST https://api.tokeflow.com/api/v1/portal/tokenization/tokens \
-H "Cookie: tf_portal_session=…" \
-H "Content-Type: application/json" \
-d '{
"session_id": "sess_...",
"encryptedCard": {
"number": "ev:QkTC:q6/SoVBehipxsy6j:...",
"cvc": "ev:QkTC:JfW5fyt5eOb2vXAX:...",
"expiryMonth": "12",
"expiryYear": "25",
"name": "ev:QkTC:..."
},
"metadata": {
"brand": "visa",
"last4": "4242",
"expiryMonth": "12",
"expiryYear": "2025",
"bin": "424242"
}
}'Example response — 201
{
"token_id": "tok_8f3c2a1b9d4e",
"brand": "visa",
"last4": "4242",
"exp_month": "12",
"exp_year": "2027"
}Errors
Errors use the standard envelope. The most common cases here:
| HTTP | Meaning |
|---|---|
400 | Invalid parameters or a state that does not allow this operation. |
401 | Missing, expired, or invalid Dashboard session token. |
403 | Authenticated, but the signed-in user lacks access to this entity. |
404 | The record does not exist or is not visible to this entity. |