Card-on-file tokenization
Use this flow when you need to capture a guest's card at booking and charge a no-show fee later without the guest being present — for example, restaurant reservations.
Yeti stores an ownership index only. You store the storedPaymentMethodId from the tokenization result. Yeti verifies that MIT charges and token deletions match the merchant and site that created the token.
Prerequisites
- Card-on-file / unscheduled MIT must be enabled for your site.
- Use opaque
shopperReferencevalues (booking ID, internal guest UUID). Must be 3–256 characters. Must not be an email address or contain@. UseshopperEmailwhen you need to pass the guest's email. - Make each
shopperReferenceunique per guest in your system. If you operate multiple merchants or tenants on one integration, namespace the value yourself (for example{merchantId}:{guestId}) so guests cannot collide. - Charge or delete tokens within 1 year of tokenization. Yeti ownership records expire after 365 days.
No-show recipe
1. Tokenize at booking
Create a zero-amount session so the guest completes Drop-in for card verification only:
POST /v1/ecom/{siteId}/sessions
{
"amount": { "value": 0, "currency": "GBP" },
"returnUrl": "https://partner.example/booking/complete",
"reference": "booking-abc123",
"shopperReference": "guest-98765",
"storePaymentMethod": true,
"storePaymentMethodMode": "enabled",
"recurringProcessingModel": "UnscheduledCardOnFile"
}
| Field | Notes |
|---|---|
amount.value | Must be 0 when you are only verifying and storing the card. |
storePaymentMethod | true asks Adyen to create a token on successful authorisation. |
storePaymentMethodMode | Optional. enabled stores without a consent checkbox; askForConsent shows one; disabled turns storage off. |
recurringProcessingModel | Must be UnscheduledCardOnFile for this no-show recipe. |
shopperReference | Opaque guest id — required when storing. |
returnUrl | Must be a valid absolute URI (API Gateway validates the URL format). |
Run Drop-in with the returned session (id + sessionData) and your clientToken from GET /config.
Persist storedPaymentMethodId from:
- the session / Drop-in result when present, and/or
- the
authorisationwebhookadditionalData, typically:tokenization.storedPaymentMethodId, orrecurring.recurringDetailReference
Wait for the authorisation webhook before calling MIT or delete — Yeti registers token ownership asynchronously when that webhook arrives. If you call too early you will get yp_4009; retry after a short delay.
2. Guest shows up — delete the token
When the guest attends, remove the stored payment method so you do not keep the card on file:
DELETE /v1/ecom/{siteId}/stored-payment-methods/{storedPaymentMethodId}?shopperReference=guest-98765
Use the same siteId and same shopperReference as at booking. Returns 204 No Content on success.
3. Guest no-shows — charge the fee (MIT)
POST /v1/ecom/{siteId}/payments
{
"amount": { "value": 2500, "currency": "GBP" },
"reference": "noshow-booking-abc123",
"returnUrl": "https://partner.example/noshow/complete",
"shopperReference": "guest-98765",
"shopperInteraction": "ContAuth",
"recurringProcessingModel": "UnscheduledCardOnFile",
"industryUsage": "noShow",
"paymentMethod": {
"type": "scheme",
"storedPaymentMethodId": "TOKEN_FROM_BOOKING"
}
}
No Drop-in is required — this is a server-side merchant-initiated transaction. You can charge again later with the same token until you delete it (subject to scheme rules and ownership TTL).
Ownership errors
| Status | Code | Meaning |
|---|---|---|
| 404 | yp_4009 | Stored payment method not found — not yet registered (webhook pending), expired, or inaccessible |
Wrong merchant, account holder, or site returns the same response as an unknown token.
Webhooks
Token ownership is written when Yeti receives a successful Ecom AUTHORISATION webhook with tokenization.store.operationType=created and server-set metadata (merchantId, siteId, accountHolderId). Existing ownership rows are never overwritten. See Webhooks for the full notification flow.
Example additionalData keys to look for on a successful tokenize authorisation:
{
"tokenization.store.operationType": "created",
"tokenization.storedPaymentMethodId": "TOKEN_FROM_BOOKING",
"recurring.shopperReference": "guest-98765"
}
Try it on the demo
The public yetipay ECOM demo at demo.yetipay.me includes this flow:
- Book (card on file) — zero-amount Drop-in tokenization.
- Manage token — paste
storedPaymentMethodId+shopperReferencefrom your webhook to MIT-charge a no-show fee or delete the token when the guest attends.
Related endpoints
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /v1/ecom/{siteId}/sessions | Tokenize card at booking |
| POST | /v1/ecom/{siteId}/payments | MIT no-show charge |
| DELETE | /v1/ecom/{siteId}/stored-payment-methods/{id} | Remove token when guest attends |
See also Sessions and Payments for full request field reference.