Payment tokens
What the payer pays to — each method issues its own kind of token.
A payment token is the thing you put in front of the payer: the address the money is sent to. Each payment method defines its own kind of token — and some methods need none at all, because the payer is sent to the provider's own flow instead of paying to an address. That is why payment_tokens is a per-method map: one entry per accepted method that issues a token, and no entry for methods that do not.
Today, with Bre-B as the only live method, tokens come in two forms: a key (in Colombia, a llave: a short alias like a cellphone number or a code, registered in the Bre-B directory) and an optional QR code that encodes the same destination so the payer can scan instead of type.
Templates and intents both carry tokens, and the difference between them is the difference between a poster on a wall and a ticket with your name on it: a template's token is shared by every payer; an intent's token identifies one expected payment.
The Bre-B token
payment_tokens.co_breb has three parts:
| Field | What it is |
|---|---|
key_type | The kind of key: cellphone, email, alphanumeric, identification, or merchant_code. Assigned by the network when the key is registered — it is not known at creation time. |
key_value | The key itself — what the payer enters in their bank's app to address the transfer. |
qr | The QR generated for the key, when one was requested (create_qr: true). |
The QR object carries everything needed to display or embed it: the EMV payload in plain text (emvco), a rendered image in base64 (image, with image_width and error_correction_level), the provider's payment_id, its usage_mode, and — for dynamic QRs — the fixed amount and expires_at.
You can request a custom key alias with method_params.co_breb.custom_key_value, and override the QR's merchant data (merchant_category_code, receiver_city, receiver_postal_code) with qr_code_data. If omitted, Mono generates the key and uses your program's configuration.
Key per template or key per intent
method_params.co_breb.key_per decides at which level the Bre-B key is minted, and it shapes the whole collection model:
key_per | Token lives on | QR kind | Payments are… |
|---|---|---|---|
template (default) | The template | Static — multiple use, no amount | Anonymous until they arrive: any payer, any number of payments. |
intent | Each intent | Dynamic — single use, fixed amount, expires | Referenced: each payment maps back to the intent that expected it. |
A template with key_per: "template" receives payments directly — it cannot host intents, because a shared key cannot tell which intent a payment belongs to. A template with key_per: "intent" has no key of its own (payment_tokens stays null): every key is minted when an intent is created. A templateless intent gets its own dedicated key too.
Token setup is asynchronous
Registering a token with the method's network takes a callback round-trip, which is why templates and intents are born in created — neither is payable until the token is confirmed:
- The template moves to
readyand fillspayment_tokenswhen every pending token is confirmed — announced bypayin_template_ready. - The intent moves to
ready_to_payand fillspayment_tokens— announced bypayin_intent_ready_to_pay.
If registration exhausts its retries, the template ends failed (key_registration_failed, key_already_registered) or the intent ends failed (key_registration_failed, payment_token_registration_failed).
Tokens are torn down
A token only lives while its owner can be paid. When a template is pruned or deleted, or an intent reaches a final state (successful, failed, or expired), Mono deregisters its tokens with the method's provider. The owner's prune_state / prune_reason fields track that teardown.