Overview
The Payment Method Tokenized Webhook is sent when Finrelay stores a card for future payments, for example after a payment where the customer chose to save the card. It carries the saved payment method's ID, which you use to charge the card later, and the transaction that saved it.
Subscribe an endpoint to it in the portal: see Configure webhooks in the portal. Its event service is separate from the transaction events, so it needs an endpoint of its own.
Supported Events
| Event Value | Description |
|---|---|
tokenization-webhook:payment-method:tokenized |
A payment method was saved |
Request Details
| Detail | Value |
|---|---|
| HTTP Method | POST |
| Content-Type | application/json |
| Authorization Header | Bearer <JWT> |
| Timeout | 15 seconds per attempt |
| Retries | 3, with exponential backoff (about 1, 2 and 4 seconds, each varying by up to 50%). A slow endpoint can receive more; see Delivery and Retry Policy |
| After the last retry | No further attempts |
| Signature Validation | JWT signed using Merchant Private Key |
The headers, the JWT and the retry policy are the same as for every webhook: see Security and Signature Verification and Delivery and Retry Policy.
Payload Schema
{
"event": "tokenization-webhook:payment-method:tokenized",
"payload": {
"payment_method": {
"id": "abc123def456ghi789jk",
"type": "CARD",
"card": {
"brand": "VISA",
"last_4": "1111",
"exp_month": 12,
"exp_year": 2028,
"bin": "411111",
"masked": "******1111"
}
},
"transaction_id": "KlLQpgjqCmsmogHfNjuS",
"customer": {
"id": "CUST123456",
"first_name": "Carey",
"last_name": "Kuhn",
"email": "carey.kuhn@example.com"
},
"merchant_id": "eyCnTugDzIMADoQLTUJF",
"created_at": "2025-04-28T12:42:27.144339Z"
}
}
Field Descriptions
| Field | Type | Description |
|---|---|---|
event |
string |
Always tokenization-webhook:payment-method:tokenized |
payload.payment_method.id |
string |
The saved payment method's ID. Use it to charge the card later, or to delete it with DELETE /api/payment-methods/{payment_method_id} |
payload.payment_method.type |
string |
The payment method type, uppercase, e.g. CARD |
payload.payment_method.card.brand |
string or null |
Card brand, e.g. VISA |
payload.payment_method.card.last_4 |
string or null |
Last four digits of the card number |
payload.payment_method.card.exp_month |
integer or null |
Expiry month, 1–12 |
payload.payment_method.card.exp_year |
integer or null |
Expiry year, four digits |
payload.payment_method.card.bin |
string or null |
The card's BIN |
payload.payment_method.card.masked |
string or null |
The masked card number |
payload.transaction_id |
string or null |
The transaction that saved the card |
payload.customer.id |
string or null |
Your customer's ID, when the transaction named one |
payload.customer.first_name |
string or null |
Customer first name |
payload.customer.last_name |
string or null |
Customer last name |
payload.customer.email |
string or null |
Customer email |
payload.merchant_id |
string |
Merchant identifier |
payload.created_at |
string (ISO-8601 datetime) |
When the event was created |
Fields without a value are sent as null, not left out.
JSON Schema
Here is the JSON Schema for validating the Payment Method Tokenized Webhook payload (download and view):
payment-method-tokenized-payload.json
New fields can be added to the payload. The schema accepts fields it doesn't list, so don't reject a webhook because it carries a field you don't know.
Important Notes
- Always verify the JWT signature using your merchant public key, and the SHA-512 digest of the body.
- Duplicate deliveries are possible: key your handler on
payload.payment_method.id. - A test sent from the portal's Test endpoint tab carries
X-Webhook-Test: true. Itspayment_method.idandtransaction_idresolve to nothing, and itsmerchant_idis yours.