Use Cases and Runbook
Every situation you will actually encounter, what happens, and exactly what you do about it.
The other guides explain how tokenization works. This one is a lookup table: something happens, and you need to know what to do.
Quick reference
| Situation | What happens | What you do |
|---|---|---|
| Cardholder adds the card to Google Pay by typing it in | digitization.activationmethods → digitization.activation → digitization.complete | Return contact methods, deliver the OTP, notify the cardholder |
| Cardholder taps "Add to Google Pay" in your app | GenerateTimeBasedSecret, then digitization.complete | Generate the secret, hand it to the SDK, notify the cardholder |
| Cardholder enters the wrong code too many times | digitization.event.Digitization_Exception | Close the attempt, let them retry |
| Cardholder starts and never finishes | digitization.activationmethods with no terminal event | Remind them within 24 hours |
| Cardholder reports the card lost | Nothing automatic | /token/stop with no token_reference, reason 1 |
| The card is found again | Nothing automatic | /token/unstop, same reason |
| Card is reissued on expiry | digitization.event.Replacement | Update your records. Do not delete |
| Cardholder deletes the card from their phone | digitization.event.Deleted_from_device | Update your token store |
| Cardholder closes the account | Nothing automatic | /token/delete for every token |
| Cardholder calls the call centre to activate | Nothing automatic | Authenticate, then /token/activate reason C |
| Cardholder asks "which phones is my card on?" | Nothing automatic | ListActiveTokens |
The rest of this page covers the ones with real subtlety.
Cardholder abandons provisioning
A cardholder starts adding a card and stops. Maybe the SMS was slow, maybe they got distracted. The token exists in an incomplete state.
How you detect it: you received digitization.activationmethods for an attempt, and neither digitization.complete nor digitization.event.Digitization_Exception has arrived.
This is why Manual Provisioning tells you to store every incoming message with a receipt timestamp. Without timestamps you cannot compute abandonment.
What you do:
| When | Action |
|---|---|
| Within 24 hours of abandonment | Notify the cardholder by in-app message, SMS or email, prompting them to finish |
| After 30 days | Delete the incomplete token |
Both are wallet programme requirements, not suggestions. They exist because a token left half-provisioned is a loose end nobody is watching.
Successful provisioning notification
This is a requirement, and it is the one most often missed.
When you receive digitization.complete, you must automatically tell the cardholder, over a channel they already trust, that their card was added to a wallet.
"Your UnDosTres card ending 4321 was added to Google Pay on Pixel 8."
Two reasons it is mandatory. First, the wallet programmes require it. Second, and more practically: if someone else provisioned the cardholder's card, this message is how the cardholder finds out. It is a fraud control disguised as a courtesy.
One exception. Do not send this notification for card-on-file tokens (token typeF). Those are provisioned to merchants in the background, often overnight in bulk, without the cardholder doing anything. Notifying them would be confusing noise about something they did not do. Notify only for wallet provisioning.
Card reported lost or stolen
The cardholder calls. You block the card. Blocking the card in your system does not block its tokens. They are separate objects and you must act on both.
flowchart TD
A["Cardholder reports card lost"] --> B["Block the card in your own system"]
A --> C["POST /token/stop - reason 1, no token_reference"]
C --> D{"Card recovered?"}
D -->|"Yes"| E["POST /token/unstop - same reason"]
D -->|"No, replacement issued"| F["POST /token/delete - per token"]
Omitting token_reference on /token/stop stops every token on the card in one call. That is what you want here: the cardholder does not know or care how many wallets the card reached, and you should not need to enumerate them first.
Use /token/stop rather than /token/delete while recovery is still possible. Stopping is reversible. Deleting is not, and a deleted token means the cardholder has to re-add the card to every device manually.
Card reissued on expiry
The card expires and a new one is issued with the same account but a new expiry, or a new PAN.
Do nothing to the tokens. The token-to-PAN mapping is updated for you, and the cardholder keeps paying from their phone throughout. You will receive digitization.event.Replacement.
The failure mode here is expensive and worth stating plainly: a partner who deletes tokens as part of their reissue routine forces every cardholder to re-add their card to every wallet. That produces a support spike, and a permanent drop in wallet usage because a meaningful share of cardholders never bother re-adding.
Cardholder deletes the card from their phone
They remove it in the wallet app. You get digitization.event.Deleted_from_device.
There is no API call from you and nothing to approve. Update your token store so your records match reality, and stop showing that device in any "your card is on these devices" view.
This is the clearest example of why your token state must be driven by callbacks. If you only update on your own API calls, this event is invisible to you and your data is wrong from that moment on.
Call centre activation
A token was provisioned but needs cardholder authentication before it can be used, and the cardholder chose the call centre option, or is calling because something else failed.
What your agent needs:
- To authenticate the cardholder to your normal standard.
- Access to a system that can see the cardholder's tokens and act on them.
ListAllTokensis the read side;/token/activateis the write side. - In some cases, fraud training. Wallet programmes route provisioning attempts they consider high risk to call centre authentication specifically, on the expectation that a trained human reviews them.
Then: POST /token/activate with card_id, token_reference, and reason: "C".
Use C, not A. C records that an agent did the authentication, which is what any later fraud review will look for.
Call centre support is expected of every issuer. Wallet programmes do not allow it to be shown as the default verification choice, because it is a poor experience compared to an SMS. But it must exist as a fallback. Plan for it even though most cardholders will never use it.
Cardholder asks which devices have their card
Call ListActiveTokens with the card_id. Useful fields for a cardholder-facing view:
| Field | Shows |
|---|---|
device_name | "Pixel 8" or "iPhone de Ana" — the nickname the cardholder will recognise |
token_requestor_name | Which wallet or merchant |
token_activated_date_time | When it was added |
current_status_description | Active or Suspended |
Use ListAllTokens instead when investigating a problem, because it also returns deleted and failed tokens with provisioning_status_description.
Something failed and you do not know why
- Find the card and pull
ListAllTokens.provisioning_status_descriptionexplains what happened to each attempt. - Pull your stored administrative messages for that card and read them in order. The sequence stops at the step that broke.
- Match the stopping point:
| Last message received | Likely cause |
|---|---|
digitization.activationmethods, nothing after | Your response was empty, malformed, or you returned no usable contact method |
digitization.activation, nothing after | The OTP never reached the cardholder, or arrived after expiry |
digitization.event.Digitization_Exception | Wrong or expired code entered, or retries exceeded |
| Nothing at all | The attempt did not reach us. Check the card is active and eligible |
If push provisioning fails before anything reaches you, check your backend clock first. GenerateTimeBasedSecret is time-based, and clock drift is the most common cause.
Related
Updated about 2 hours ago

