Guides

Tokenisation & Card on File

Tokenisation converts a customer's card details into a reference token at the moment they're entered, before any charge or 3DS check runs. The token is unique to your merchant account; you use it in place of the card number on future charges.

Tokens are what make recurring billing, instalments and one-click repeat purchases possible without your systems ever storing a raw card number.

Before you start

  1. Nothing to activate in the ArtsPay dashboard: tokenisation isn't a separate feature you turn on. Every successful card payment already returns a token you can store, whatever integration method you're using.
  2. A token is an opaque reference, not a disguised card number. It can't be reversed back into the original card details, and it only ever works on your own ArtsPay account, in place of card_number on future charges.
  3. If you'll ever need to charge a stored card again automatically (recurring billing, instalments, or billing a customer who isn't present), decide that upfront: it determines which extra fields you send later, covered below.
  4. A tokenisation error is not a decline. It means the card details themselves couldn't be stored, usually a validation problem, so the customer needs to re-enter their card rather than retry the same charge. See the FAQ below.

Every purchase already returns a token

You don't have to make a special call just to get a token: every successful card transaction tokenizes the card and returns it in the response, whether it came through the API, a Hosted Payment Page, or a wallet purchase. Store that token after the order completes if you'll need to charge the customer again.

Tokenizing a card directly

To store a card without charging it (e.g. a "save this card" flow), call the tokenize endpoint directly:

json
// POST /v1.0/credit_cards{  "card_number": "5123456789012346",  "card_holder": "Bob Smith",  "card_expiry": "05/2030",  "cvv": "987"}
json
// Response{  "successful": true,  "response": {    "token": "fke8jmra",    "card_holder": "Bob Smith",    "card_number": "512345XXXXXX2346",    "card_expiry": "2030-05-31",    "card_type": "MasterCard",    "authorized": true,    "alias": null  }}

The same result is available via the Hosted Payment Page using tokenize_only=true. See the Hosted Payment Pages guide.

Charging a stored token

Use card_token in place of card_number on a normal purchase call:

json
// POST /v1.0/purchases{  "amount": 100,  "currency": "AUD",  "card_token": "fke8jmra",  "reference": "transact_with_token"}

Fields for recurring, instalment & merchant-initiated charges

These transaction types all count as card-on-file transactions and carry extra fields under extra in the purchase payload:

ecm (eCommerce indicator)

A two-digit code describing the order channel and cycle:

First digit (order channel)Second digit (cycle)
1 Telephone Order1 Single, 2 Recurring, 3 Instalment
2 Mail Order1 Single, 2 Recurring, 3 Instalment
3 Internet Order1 Single, 2 Recurring, 3 Instalment
json
{ "extra": { "ecm": 32 } }

32 above means: Internet Order, Instalment.

stored_credential_indicator

Marks whether this is the first charge in a recurring/instalment series or a later one:

ValueMeaning
I Initial transaction
S Subsequent transaction
json
{ "extra": { "stored_credential_indicator": "I" } }

auth_reason (merchant-initiated transactions)

A merchant-initiated transaction is one your system triggers with the customer's prior consent, without them present at checkout, e.g. billing a saved card for a subscription renewal or a no-show fee.

ReasonValue
Resubmission Paymentresubmission
Delayed Charges Paymentdelayed_charges
Re-authorization Paymentreauthorization
No Showno_show
Account Topupaccount_topup
Unscheduled Paymentunscheduled
Incrementalincremental
Instalmentinstalment
Recurring Subscription (fixed value)subscription
Partial Shipmentpartial_shipment
json
{ "extra": { "auth_reason": "no_show" } }

card_on_file

Indicates the card being charged came from your vault. You usually don't need to set this yourself. ArtsPay applies it automatically for recurring, instalment and merchant-initiated transactions.

omit_expiry

For recurring transactions against a card that's since expired, set omit_expiry: true to send the transaction without the expiry field. This typically improves approval rates for recurring billing on expired cards.

json
{ "extra": { "omit_expiry": true, "ecm": 32 } }

Putting it together: a subsequent recurring charge

json
{  "amount": 4999,  "currency": "AUD",  "card_token": "fke8jmra",  "reference": "sub_2026_09",  "extra": {    "ecm": 32,    "stored_credential_indicator": "S"  }}

Managing stored tokens

Testing

Use the standard test card numbers. Tokenizing a test card behaves the same as a live one in sandbox; no special test tokens are needed.

Card NumberScenarioTesting
4005 5500 0000 0001 The card payment succeeds.Fill out the payment form using the credit card number with any expiration and CVC.
4557 0123 4567 8902 The card is marked as declined with a declined code.Fill out the payment form using the credit card number with any expiration and CVC.
4000 0000 0000 1091 The card payment requires liability shift 3DS/SCA authentication.Fill out the payment form using the credit card number with any expiration and CVC.

FAQ

What's the difference between a tokenisation error and a decline?

A tokenisation error means the card details couldn't be stored at all, usually a validation problem (bad card number, expired card format). A decline means the card was valid and tokenized but the bank refused the charge. Handle them differently: a tokenisation error should send the customer back to re-enter their card; a decline can offer a retry or a different card.

Do I need to call the tokenize endpoint separately if I'm already taking a payment?

No. Every successful purchase already returns a token you can store. Only call the tokenize endpoint directly when you want to save a card without charging it.

Do I need to set card_on_file manually?

No, in almost all cases. ArtsPay applies it automatically whenever ecm, stored_credential_indicator or auth_reason indicate a recurring, instalment or merchant-initiated transaction.

Can I store cards captured via Apple Pay or Google Pay for later recurring billing?

Yes. The card_token from the first wallet transaction can be reused for subsequent charges the same way as any other stored card. See the Apple Pay and Google Pay guides. Acquirer support for recurring wallet transactions varies, so confirm with your acquirer first.

Do stored cards ever need re-authentication with 3D Secure?

Only the initial card-holder-present transaction typically goes through a 3DS2 check. Subsequent card-on-file charges are usually exempt as merchant-initiated transactions, but this depends on your acquirer and issuer rules. See the 3D Secure guide if you're unsure which of your flows need it.