Introduction
A provider token is a reusable card token issued by a payment provider, not by Finrelay. It is useful when your customers' cards are already stored at that provider. The provider-token payment method sends such a token instead of card data.
- Available only for payment providers that support it (today: Ilixium), and only when the payment provider has provider tokens turned on. Ask your account manager.
- Accepted on the server-to-server API only (
POST /api/transactions/authorize). The hosted payment page, the SDKs and embedded fields refuse it. - The terminal must have exactly one payment provider account with provider tokens turned on: the token works only on the provider account that issued it, so the payment is never routed anywhere else and never falls back to another provider.
- The provider may still run 3-D Secure, so send
browser_infoas for a card payment. Ilixium also needs everything a card payment needs, includingoptions.date_of_birth(see Ilixium).
Data fields
| Field | Required | Description |
|---|---|---|
payment_method.type |
Yes | provider-token |
payment_method.data.encrypted_token |
Yes | The provider token, encrypted with your merchant public key, exactly like encrypted_cvv (see the encryption example). |
payment_method.data.encrypted_cvv |
Provider-specific | The card's CVV, encrypted with your merchant public key. Ilixium requires it with every token payment. |
customer.id |
Provider-specific | Ilixium binds a token to the customer it was issued for: send the same customer.id as on the payment that returned the token. Without customer.id on that first payment, Ilixium returns no token. |
curl -X POST https://api.finrelay.io/api/transactions/authorize \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"terminal_id": "TERM001",
"reference": "ORDER-123457",
"transaction_type": "PURCHASE",
"amount": 2000,
"currency": "CAD",
"customer": { "id": "CUST-42", "first_name": "Ana", "last_name": "Test", "email": "ana@example.com" },
"browser_info": { "user_agent": "Mozilla/5.0", "accept_header": "text/html", "java_enabled": false, "color_depth": 24, "screen_height": 1080, "screen_width": 1920, "time_zone_offset": -60, "language": "en" },
"options": { "date_of_birth": "1975-04-03" },
"payment_method": {
"type": "provider-token",
"data": { "encrypted_token": "BASE64_RSA_CIPHERTEXT", "encrypted_cvv": "BASE64_RSA_CIPHERTEXT" }
}
}'
A payment that cannot be routed is INVALID with INVALID_REQUEST_PAYMENT_METHOD_NOT_SUPPORTED:
- no payment provider on the terminal accepts provider tokens;
- several payment providers on the terminal accept provider tokens (use a terminal with one).
Get the token
When the payment provider has provider tokens turned on and returns a token with an approved card payment, the transaction carries payment_provider_token โ only in the response of your own server-to-server API (POST /api/transactions/authorize, GET /api/transactions/{id}, GET /api/transactions/{id}/status). Webhooks, the dashboard and the cardholder channels never carry it.
"payment_provider_token": { "token": "709d4c1e8a2b4f6e9d3c5b7a1e0f0715" }
The field is absent when the provider returned no token, on a declined payment, and when the token was bound to a customer id the gateway derived from the e-mail (send customer.id to get a reusable token). Store the token as a card credential: with the CVV it can charge the card. Never log the token or the CVV, and never send either to the browser.