Skip to main content

Tokens

POST /v1/tokens creates a reusable payment-method token. Token IDs use the vp_pmt_test_* / vp_pmt_live_* prefix.

This is the server-side token endpoint. For the browser/embedded flow — where the Embedded Fields SDK (vora.js) mints a token from card fields the buyer types — see Tokenization.

Required key: secret key (vp_sk_*). Available in SDK 0.6.0.

Create a token

curl https://checkout.vonpay.com/v1/tokens \
-H "Authorization: Bearer vp_sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "buyer_id": "buyer_abc", "provider_reference": "pm_token_abc123" }'
const token = await client.tokens.create({
buyerId: "buyer_abc",
providerReference: "pm_token_abc123",
});

Request — CreateTokenRequest

All fields are optional, and the schema is strict (unknown fields are rejected).

FieldTypeRequiredDescription
buyer_idstringBuyer to associate the token with (enables reuse / MIT).
buyerobjectNested buyer profile (snake_case): external_id, email, name, phone, company, address, metadata. Upserts the same buyer record as POST /v1/buyers and associates the vaulted token with it — buyer.external_id feeds the same buyer association as the flat buyer_id, which remains supported. Must carry an identity (buyer.external_id or buyer.email) directly or via buyer_id, else 400 validation_error. Sending buyer_id AND buyer.external_id with equal values is fine; different values return 400 validation_error. Echoed back on the response (present only when sent; buyer.metadata echoed post-scrub).
provider_referencestringA gateway-specific reference for the payment method — depending on the underlying gateway, an iframe-vault payment-method handle or a server-side setup reference. Required for live tokenization (see below); ignored in sandbox. Max 255 chars.
card_last4stringLast four digits, for display.
card_brandstringCard network — one of visa, mastercard, amex, discover, unionpay, jcb, diners, unknown.
exp_monthinteger1–12.
exp_yearintegerFour-digit year (≥ 2025).
metadataobjectRecord with string keys and arbitrary JSON values (size-capped, scrubbed).
setup_for_future_usestringPermission to charge the card again — off_session or on_session. Omitted, the token is single-use and a merchant-initiated charge against it is refused with payment_method_consent_missing. Recorded once at vault time; nothing adds it later.
allow_redisplaystringPermission to show the card back to the buyer in a later checkout — always, limited, or unspecified. A different permission from setup_for_future_use above: agreeing to a subscription is not agreeing to see that card offered on an unrelated purchase months later. Only always permits display. Send unspecified when you did not ask — that is a real answer, and omitting the field is not. Like consent, it can only be captured on the call that first vaults the card and can never be added afterwards. Echoed back on the response when sent.
billing_addressobjectBuyer billing address, stored encrypted on the token to seed a future charge's address verification. Never returned. No verification result is produced at vault time, because no payment is made. See Address verification.
stored_credential_usestringDeclares what the stored card is for — recurring, installment, or unscheduled. The server-to-server counterpart of storedCredentialUse on POST /v1/sessionsnote the different casing on each surface. Use the same value you will later send as mit.reason. Reaching the card networks additionally requires currency and buyer_id on this request plus account-level enablement; when it does not, the token is still vaulted and the response carries a warnings entry rather than an error. See Recurring & saved cards.
currencystringThree-character currency for the zero-amount card verification. Vaulting a card creates no payment, so on its own there is nothing to carry a stored_credential_use declaration to the card networks; supplying a currency lets the vault run as a zero-amount verification that does. Deliberately un-defaulted — there is no correct fallback currency. Omit it and the card is vaulted with no verification.

Sandbox vs. live:

  • Sandbox keys auto-mint a mock card token when no card data is supplied — useful for SDK examples. provider_reference is ignored.
  • Live keys require a provider_reference (the payment method must already exist at the gateway). Without it, the request returns 400 validation_error.

Response — PaymentMethodToken

{
"id": "vp_pmt_test_QAqnXEJF_TCum1jg",
"status": "active",
"card": {
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2030
}
}
FieldTypeDescription
idstringToken ID (vp_pmt_test_* / vp_pmt_live_*).
statusstringactive or revoked.
card.brandstringCard network (e.g. visa).
card.last4stringLast four digits.
card.exp_monthinteger1–12.
card.exp_yearintegerFour-digit year.
idempotentbooleantrue when this response is a replay of an earlier request that used the same Idempotency-Key — no new token was vaulted, you are being handed the existing one. It only appears when you sent that header; without one, a retry vaults a second token. See Idempotency.
allow_redisplaystringEchoes the display permission you sent. Present only when you sent it.
warningsarrayPresent only when something about the request did not take effect. A warning never means the vault failed — the token in the same response is real and usable. Each entry carries code, message, and field.

Warning codes

CodeMeaning
stored_credential_use_not_appliedThe card was saved, but your stored_credential_use declaration did not reach the card networks, so no stored-credential declaration was made for this card — a later merchant-initiated charge on this token will not be anchored to one. Reaching the networks requires currency and buyer_id on the request plus account-level enablement; contact support to confirm enablement before relying on the declaration.

Status

StatusMeaning
activeThe token can be used to create a payment intent.
revokedThe token has been revoked and can no longer be used.

A token does not carry a separate expired status. Card expiry (exp_month / exp_year) is stored on the token's card object, but the token itself stays active until it is revoked.

Errors

StatusCodeCause
400validation_errorA live key was used without provider_reference (or another invalid request field).
501endpoint_not_implementedThe merchant's gateway does not expose tokenization through this endpoint — some gateways accept only browser-minted handles and bypass /v1/tokens entirely.

Using a token

Pass a token's id as payment_method.id when creating a payment intent ({ "payment_method": { "id": "vp_pmt_..._" } }). See Payment Intents.