Reconciling PayIns in Mexico means matching the credit Transaction a SPEI collection produces on your Cobre Balance to the entity or request it settles — using metadata.account_reference, a field required on every spei_credit Transaction. Whether that collection also involved a Money Movement first (Direct Link R2P SPEI) or not (a standing CLABE linked to a Cobre Balance or Virtual CLABE) changes where that account_reference value comes from, but not the fact that it's always the key you reconcile on.
Money Movements vs. Transactions#
| Identifier | Prefix | Generated when | Represents |
|---|
| Money Movement ID | mm_ | A Direct Link R2P SPEI collection is created | The collection intent and its lifecycle status |
| Transaction ID | trx_ | The PayIn completes and funds are credited | The actual balance-affecting ledger entry |
Always provide external_id when creating a Direct Link PayIn Money Movement. It's echoed back and is the simplest way to match a Cobre collection to your internal invoice or order — but it's a field on the Money Movement, not on the resulting Transaction. See below for how the Transaction itself is keyed.
This doesn't apply to a CLABE-linked SPEI credit — see below. Those have no Money Movement and no external_id.
Example — how a Direct Link R2P SPEI PayIn and its Transaction unfold, step by step:1
Money Movement created
Cobre mints a short-lived
dynamic CLABE for this specific request (
metadata.virtual_account, 5-minute default validity) and hands it to the payer.
{
"id": "mm_8pf9xbiJkAdiAO",
"external_id": "ORDER-MX-2026-010",
"type": "direct_link",
"geo": "mex",
"status": {
"state": "initiated",
"code": "",
"description": ""
},
"source_id": "cp_5YFeIDhNkz",
"destination_id": "acc_XI7W2HQYuE",
"currency": "mxn",
"amount": 10000,
"metadata": {
"r2p_rail": "spei",
"virtual_account": "706180301111111111"
},
"created_at": "2025-11-06T16:44:10Z",
"updated_at": "2025-11-06T16:44:10Z"
}
2
Payer sends the SPEI transfer to the dynamic CLABE — credit Transaction applied
{
"id": "trx_j51T77qTrVj0lH8TAQlq",
"type": "spei_credit",
"account_id": "acc_XI7W2HQYuE",
"amount": 10000,
"previous_balance": 0,
"current_balance": 10000,
"currency": "mxn",
"credit_debit_type": "credit",
"transaction_date": "2025-11-06T16:44:24Z",
"created_at": "2025-11-06T16:44:24Z",
"metadata": {
"account_reference": "706180301111111111",
"sender_account_number": "002180700856249796",
"sender_name": "JOHN,DOE/SMITH",
"reference": "91025",
"tracking_key": "085905789870328253",
"description": "Transferencia interbancaria"
}
}
spei_credit Transactions have no money_movement_id field at all. The Transaction's metadata.account_reference (706180301111111111) matches the Money Movement's metadata.virtual_account — that's the field you match on to tie the two together.3
Money Movement reaches completed
{
"id": "mm_8pf9xbiJkAdiAO",
"external_id": "ORDER-MX-2026-010",
"type": "direct_link",
"geo": "mex",
"status": {
"state": "completed",
"code": "",
"description": ""
},
"source_id": "cp_5YFeIDhNkz",
"destination_id": "acc_XI7W2HQYuE",
"currency": "mxn",
"amount": 10000,
"metadata": {
"r2p_rail": "spei",
"virtual_account": "706180301111111111"
},
"created_at": "2025-11-06T16:44:10Z",
"updated_at": "2025-11-06T16:44:24Z"
}
A CLABE-linked SPEI credit (no Direct Link involved) produces the exact same Transaction shape and also keys off account_reference — but there's no Money Movement behind it, and the CLABE is a standing one rather than a short-lived one minted per request. See below for how to tell the two apart.
Mexico Credit Transaction Types#
| Transaction type | Collection method | Backed by a Money Movement? |
|---|
spei_credit | SPEI transfer to a CLABE linked to a Cobre Balance or Virtual CLABE | No — see below |
spei_credit | Direct Link R2P SPEI collection | Yes |
mex_credit | Connect Account credit (bank-reported) | Yes |
internal_spei_credit / internal_credit | Internal transfer between Cobre-hosted accounts | Yes |
SPEI credit Transactions carry the sender's account and identification data directly in metadata, which is what makes Mexico refunds a single-endpoint operation — see below.metadata.account_reference is a required field on every spei_credit Transaction, regardless of whether a Money Movement is involved. It's always your reconciliation key for this transaction type.
CLABE-Linked SPEI Credits Don't Create a Money Movement#
A CLABE linked to a Cobre Balance, or a Virtual CLABE, is available to receive SPEI transfers at any moment — like a static Cobre Key in Colombia, there's no Cobre-initiated request to track. Because of this, no Money Movement is created: the transfer simply produces a spei_credit Transaction directly on your Cobre Balance.Example — a spei_credit Transaction from a CLABE-linked SPEI collection:{
"id": "trx_h5G3wRz88mAxVe2",
"type": "spei_credit",
"account_id": "acc_6euTJ0ikgi",
"amount": 100,
"previous_balance": 0,
"current_balance": 100,
"currency": "mxn",
"credit_debit_type": "credit",
"transaction_date": "2025-10-09T19:26:13Z",
"created_at": "2025-10-09T19:26:14Z",
"metadata": {
"account_reference": "706180301111111100",
"intended_beneficiary_id": "ND",
"reference": "91025",
"intended_beneficiary_name": "PEXTO MEXICO",
"sender_account_number": "002180700856249796",
"description": "Transferencia interbancaria",
"sender_name": "JOHN,DOE/SMITH",
"tracking_key": "085905789870328253",
"sender_id": "GAAP920820PP7"
}
}
There is no money_movement_id anywhere on this Transaction. metadata.account_reference (706180301111111100 in this example — the standing CLABE that received the funds) is your reconciliation key. account_id, reference, and tracking_key are useful supporting fields, but account_reference is what to key your matching logic on.
By contrast, a Direct Link R2P SPEI collection does create a Money Movement first — it's a request-to-pay flow, not a standing account waiting to receive funds. Its resulting spei_credit Transaction still reconciles via metadata.account_reference, but that value is the Money Movement's own dynamically generated virtual_account (a short-lived CLABE minted just for this request) rather than a standing one. Match metadata.account_reference on the Transaction against metadata.virtual_account on the Money Movement to tie the two together.
PayIn Lifecycle and Balance Impact#
For Money-Movement-backed collections (Direct Link R2P SPEI), a Transaction is only created when the Money Movement reaches completed:| Terminal state | Transaction created? | Net balance impact |
|---|
completed | Yes — 1 credit (spei_credit) | Positive (funds received) |
rejected / failed | No | None |
CLABE-linked SPEI credits don't go through this lifecycle at all — see above.
Refunds Affect Reconciliation Too#
Mexico refunds a SPEI credit through a dedicated endpoint: Return a Money Movement (POST /money_movements_return). Because SPEI credit Transactions retain the sender's account details, Cobre auto-creates the destination counterparty and a new spei_return Money Movement, producing a spei_debit Transaction on your Cobre Balance — both carrying metadata.money_movement_id, unlike the original spei_credit. When reconciling a period, don't assume a completed PayIn's balance impact is permanent — check for a later spei_debit linked to the same original transaction before closing out the period. See Processing Refunds in Mexico for the full flow.Returns are currently limited to spei_credit transactions on supported account providers (starting with pr_mex_cobre3, others coming soon) — see the endpoint reference for the current list.
Reconciling Mexico PayIns#
On demand: For Direct Link R2P SPEI, query Obtain all Money Movements filtered by state, external_id, destination_id (your Cobre Balance), or a date range to get the Money Movement's metadata.virtual_account, then cross-reference Obtain an Account Transactions filtered by credit_debit_type=credit and metadata.account_reference equal to that value. For CLABE-linked SPEI credits, query Transactions directly and match metadata.account_reference against your own map of issued CLABEs — there's no Money Movement to query.In bulk: Generate a Money Movement report (money_movement_mex_spei_csv_v1 or money_movement_csv_v1 for CSV, money_movement_v1 for JSON) and a Transaction report (transactions_csv_v1 for CSV, account_transactions_v1 for JSON) via Reports, and filter the exported rows to currency = MXN. Group all spei_credit rows by metadata.account_reference — this works uniformly whether the CLABE is standing or minted for a single Direct Link request. For Direct Link rows specifically, cross-reference the Money Movement report's metadata.virtual_account to confirm which request each credit settles.In real time: Subscribe to Notifications & Subscriptions instead of polling. For Direct Link R2P SPEI, money_movements.status.completed (and .rejected / .failed) fires as soon as the status changes. CLABE-linked SPEI credits have no Money Movement to emit a status event for — use accounts.balance.credit instead, and match it back using the event's metadata.account_reference.Webhook delivery is best-effort, not guaranteed forever — see Notifications & Subscriptions for the retry window. Treat webhooks as your real-time signal and on-demand queries or Reports as the periodic fallback that catches anything a webhook missed.
Allowed Actions on Payin Reconciliation in México#
🔍 Retrieval — Money Movements
🔍 Retrieval — Transactions