Manual Provisioning
The complete callback sequence when a cardholder types their card into a wallet, and exactly what you must return at each step.
Manual provisioning is when the cardholder opens Apple Pay or Google Pay and types the card number, expiry and CVV in by hand. Because anyone who can read a card number could do that, the cardholder must prove they own the card by entering a one-time code.
This is the path with the most work on your side. UnDosTres cannot complete it alone, because UnDosTres does not hold your cardholder's phone number or email address. You do.
The full sequence
%%{init: {"sequence": {"actorMargin": 8, "boxMargin": 6, "noteMargin": 6, "messageMargin": 26, "width": 110, "diagramMarginX": 8, "diagramMarginY": 8}}}%%
sequenceDiagram
autonumber
participant CH as Cardholder
participant W as Wallet
participant MC as Mastercard MDES
participant UDT as UnDosTres
participant P as You
CH->>W: Types card number, expiry, CVV
W->>MC: Checks the card is eligible
MC-->>W: Terms and conditions
W-->>CH: Displays the terms
CH->>W: Accepts
W->>MC: Starts digitization
Note over MC,P: Step 1 - contact methods
MC->>UDT: Requests activation methods
UDT->>P: digitization.activationmethods
P-->>UDT: Masked phone and email
UDT-->>MC: Activation methods
MC-->>W: Options
W-->>CH: How do you want your code
CH->>W: Chooses SMS
Note over MC,P: Step 2 - deliver the code
MC->>MC: Generates the activation code
MC->>UDT: Activation code
UDT->>P: digitization.activation
P->>CH: Sends the code by SMS
CH->>W: Enters the code
W->>MC: Submits the code
MC->>MC: Validates the code
Note over MC,P: Step 3 - done
MC->>MC: Activates the token
MC->>UDT: Digitization complete
UDT->>P: digitization.complete
P->>CH: Confirms card added
MC-->>W: Provisioning complete
W-->>CH: Card appears in the wallet
How the callbacks reach you
All four messages arrive as XML-RPC AdministrativeMessage calls to your endpoint, in the same shape as every other administrative message on this platform. See Administrative Message for the envelope.
Seven parameters, in order:
| # | Parameter | Notes |
|---|---|---|
| 1 | terminalID | Your terminal ID, 10 characters |
| 2 | reference | The wallet reference the message concerns |
| 3 | messageName | Which message this is. The four values below |
| 4 | messageData | The payload, KLV encoded |
| 5 | transactionID | Generated by the caller. Not unique, may repeat |
| 6 | transactionDate | ISO 8601 |
| 7 | checksum | HMAC-SHA256 of the method name concatenated with all argument values, keyed with your terminal password |
You respond to all of them with resultCode. 1 means accepted.
1. digitization.activationmethods
digitization.activationmethodsWhen: at the very start, once the cardholder has accepted the terms.
What it means: a provisioning attempt has started and MDES needs to know how the cardholder can be reached, so the wallet can offer them a choice.
What you must return: the contact methods available for this cardholder. This is the one message where your response carries real data rather than just an acknowledgement.
KLV keys present: 910 digitized device id, 915 digitized token requestor id, 929 digitization path, 930 wallet recommendation, 931 tokenization pan source.
Activation methods
| Type | Method |
|---|---|
| 1 | Masked mobile phone number |
| 2 | Masked email address |
| 3 | Call to an automated call centre, initiated by the cardholder |
| 4 | Call to a staffed call centre, initiated by the cardholder |
| 5 | Website |
| 6 | Mobile application |
| 7 | Issuer voice call to the cardholder's phone |
Return only the methods you can actually service. If you return type 1, you must be able to send an SMS. If you return type 4, you must have a call centre that can authenticate a cardholder and act on the result.
Mask the values you return. There is no scheme-mandated masking format, but the convention is:
- Email: keep the first two characters and the whole domain, star the rest.
ag*****@gmail.com- Phone: star everything except the last four digits, keeping any hyphens.
**-***-****-1234The masked value is displayed to the cardholder inside the wallet, so it has to be recognisable to them and useless to anyone else.
Response
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>resultCode</name>
<value><int>1</int></value>
</member>
<member>
<name>activationMethods</name>
<value>
<array>
<data>
<value>
<struct>
<member><name>type</name><value>1</value></member>
<member><name>value</name><value>555-444-2222</value></member>
</struct>
</value>
<value>
<struct>
<member><name>type</name><value>2</value></member>
<member><name>value</name><value>[email protected]</value></member>
</struct>
</value>
</data>
</array>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>
If you return nothing here, provisioning stops. An empty or failed response means the wallet has no way to verify the cardholder, and the attempt dies. This is the single most common cause of a manual provisioning that silently never completes.
2. digitization.activation
digitization.activationWhen: after the cardholder picks a method.
What it means: MDES has generated the activation code. You deliver it to the cardholder over the channel they chose.
What you must return: resultCode only.
KLV keys present: 901 activation code, 902 activation method type, 903 activation method value, 904 activation expiry, 915 digitized token requestor id.
The code is generated and validated by MDES, not by you. You are the delivery channel. Do not generate your own code, do not modify it, and do not validate it. Read 901, send it, and acknowledge.
Note 904, the expiry. Deliver promptly; a code that arrives after it expires produces a digitization.event.Digitization_Exception and a confused cardholder.
3. digitization.complete
digitization.completeWhen: MDES has validated the code and activated the token.
What it means: the card is now live in the wallet.
What you must return: resultCode only.
KLV keys present: 254 digitized pan, 255 digitized wallet id, 910 device id, 911 pan expiry, 912 masked FPAN, 913 Token Unique Reference, 915 token requestor id, 923 event type, 924 event reason code.
This is your trigger to notify the cardholder. Wallet programmes require the issuer to tell the cardholder, over a channel they already trust, that their card was added. Send an in-app message, SMS or email on receipt of this callback. It is a launch requirement, not a nicety, and it is also the main way a cardholder finds out if someone else added their card.Store
913, the Token Unique Reference. It is the identifier you pass astoken_referencefor every lifecycle operation afterwards.
4. digitization.event.Digitization_Exception
digitization.event.Digitization_ExceptionWhen: the provisioning attempt failed.
What it means: one of the following happened:
- the activation code retries were exceeded
- an expired activation code was used
- an invalid activation code was used
- an incorrect activation code was entered
What you must return: resultCode only.
KLV keys present: the same set as digitization.complete.
Treat this as a closed, failed attempt. The cardholder may start again from scratch. If you are tracking provisioning funnels, this and digitization.complete are your two terminal outcomes.
Tracking an attempt end to end
A provisioning attempt is started by digitization.activationmethods and finished by either digitization.complete or digitization.event.Digitization_Exception.
Store every incoming message with the timestamp you received it. You will need that for three things:
- Correlating messages to one attempt. Use the Token Unique Reference where present, or the card, to tie the sequence together.
- Abandoned provisioning. A cardholder who starts and never finishes should be reminded. See Use Cases and Runbook.
- Support. When a cardholder calls to say "it didn't work", the stored sequence tells you exactly which step it stopped at.
Related
- Push Provisioning — the path with no OTP
- Token Lifecycle Management — what happens after activation
- Use Cases and Runbook — abandoned and failed attempts
- KLV Lookup
Updated about 2 hours ago

