How to reconcile cross-border payments in Latin America?
If your company pays or collects money across multiple LATAM countries, you’ve probably lived this: the money “did arrive”… but no one knows when, through which channel, with what reference, or where the proof is. And when month-end hits, everything turns into detective work.
This guide is meant to prevent that. No unnecessary jargon. Just practical steps.
First things first: what does it mean to “reconcile” a payment?
Reconciliation is very simple:
Making sure what you intended to pay matches what actually happened and what finally shows up.
In practice, for every payment you should be able to answer these 3 questions:
- What did we ask to pay? (amount, currency, who, when)
- What did the provider/bank execute? (which channel it used and what tracking/reference number it has)
- What finally settled? (it’s confirmed, and there’s proof)
If you can’t answer that in 30–60 seconds per transaction, your reconciliation relies on “searching, guessing, and chasing emails.”
Why does LATAM become a headache?
Because in Latin America there isn’t “one payment system.” There are several, and every country has its own rules and receipts.
Examples (keeping it simple):
- Mexico: SPEI* (bank transfers).
- Brazil: Pix (instant payments).
- Colombia: PSE (bank-based payments).
Now add:
- More than one provider (bank + PSP + platform)
- FX (exchange rates)
- High-volume payouts (payroll, payouts, refunds)
- Daily operations (real incidents)
How to reconcile faster and avoid 80% of the chaos?
Every payment must have one unique internal “reference” from day one.
Call it whatever you want:
- reference
- internal_payment_id
- payment_reference
- operation_id
But it must exist before the money moves.
Why?
Because if you don’t have it, you end up reconciling like this:
- “I think it’s this one because the amount looks similar…”
- “It must be that one because it happened the same day…”
That’s exactly what makes reconciliation slow.
What to store as “minimum proof”?
Think of this as your survival kit. For every payment, store:
A) Your internal data (what you control)
- Internal reference (your unique ID)
- Created date/time
- Amount and currency
- Beneficiary (who you paid)
- Origin/destination country (if relevant)
B) Channel/provider data (what the bank/provider gives you)
- Channel used (SPEI* / Pix / PSE / etc.)
- Tracking/reference number for that channel
- Final status (confirmed / failed / returned)
- Confirmed date/time
C) Proof (the “receipt”)
- Receipt / confirmation / link / PDF / validated capture
- And most importantly: where it lives (central storage, not someone’s inbox)
What number do I need to track in each country?
Here’s the useful part. You don’t need to memorize fancy names—just know which data lets you look up the payment.
Mexico (SPEI*)
For SPEI*, what usually saves you is the “clave de rastreo” (think: “tracking number”).
Store:
- clave de rastreo
- sending/receiving bank
- beneficiary account identifier (e.g., CLABE if applicable)
- amount + date/time
- receipt / proof
Simple example:
“Supplier payment in Mexico. If someone asks ‘did it land?’, you search by clave de rastreo and pull the proof in 10 seconds.”
Brazil (Pix)
Pix also has a transaction identifier (your Pix “tracking number”).
Store:
- Pix transaction ID (whatever identifier your provider gives you)
- amount + date/time
- beneficiary
- receipt / proof
Simple example:
“It was paid via Pix. You don’t reconcile by ‘amount’… you reconcile by the Pix ID.”
Colombia (PSE)
In PSE flows, you typically get a transaction code/identifier (often shown as CUS or similar depending on the flow/provider).
Store:
- PSE transaction code (CUS or whatever ID your provider reports)
- amount + date/time
- final status
- proof
Key idea: across countries it’s the same concept: one channel tracking ID + your internal reference.
The “single sheet” that makes your life easier (minimum reconciliation template)
You can start in Excel/Sheets, but build it like a table.
One row = one payment.
Minimum columns that actually work:
|
Section |
Field (column name) |
What it means (in plain English) |
Example value |
|
Identification |
internal_reference |
Your unique internal ID for the payment (the “folio”) |
PAY-2026-000184 |
|
Identification |
provider_id |
The ID your provider/bank/PSP assigns |
prov_8f2a19 |
|
Identification |
channel |
The payment channel used |
SPEI* / Pix / PSE |
|
Identification |
channel_tracking_id |
The channel’s tracking/reference ID |
clave de rastreo / Pix ID / CUS |
|
Money |
amount_sent |
Amount you initiated |
10000 |
|
Money |
currency_sent |
Currency you initiated |
USD |
|
Money |
fee |
Fees charged (if any) |
12.50 |
|
Money |
exchange_rate |
FX rate applied (if any) |
17.23 |
|
Money |
amount_received |
Amount the beneficiary received |
171,900 |
|
Money |
currency_received |
Currency received |
MXN |
|
Time & status |
created_at |
When you created the payment order |
2026-03-02 10:15 |
|
Time & status |
executed_at |
When it was actually sent/executed |
2026-03-02 10:18 |
|
Time & status |
confirmed_at |
When it was confirmed/settled |
2026-03-02 10:21 |
|
Time & status |
status |
Your simplified status |
pending / confirmed / failed / returned / review |
|
Time & status |
reason |
Optional reason for status |
insufficient funds / invalid account |
|
Proof |
proof_link |
Where the receipt/proof lives (central storage) |
drive://proofs/PAY-2026-000184.pdf |
|
Control |
reconciled_by |
Who reconciled it |
maria.g |
|
Control |
reconciled_at |
When it was reconciled |
2026-03-02 18:05 |
|
Control |
exception_notes |
Notes if something didn’t match |
Provider status delayed; confirmed next day |
Missing one of these columns might feel harmless… until you have 500 payments and month-end makes you pay for it.
How to make “pending / confirmed / failed” understandable for everyone
Another common issue: every provider has 20 different statuses and the team gets confused.
To solve it: keep a small set of internal statuses and map everything into it.
A simple set:
- created (you generated it)
- submitted (provider accepted it)
- pending (not confirmed yet)
- confirmed (it settled)
- failed (it won’t settle)
- returned (money came back)
- review (something doesn’t match)
With that, everyone understands the flow—and you can measure where things get stuck.
High-volume payouts: how to reconcile without checking one by one
If you run payroll, user payouts, vendor payments at scale, refunds, etc., you need a different approach.
For mass payouts latin america, manual one-by-one reconciliation will always leave you behind.
The scalable method: reconcile in layers
Layer 1: “Does the batch match?”
- how many payments did I send
- total amount sent
- how many got confirmed
- what’s the delta (the “problem” ones)
Layer 2: “Touch only what failed”
- filter by status = failed / review / old pending
- those are the only ones humans need to handle
Layer 3: “Exceptions need an owner”
Each exception has:
- an owner
- a due date (internal SLA)
- proof attached once (no re-collecting)
This is the difference between “endless investigation” and “exception management.”
What if I use stablecoins?
.png?width=1200&height=800&name=20260227_Bitso_Cross%20border%20payments%20in%20Latin%20America_Blog%201%20(1).png)
If your flow includes stablecoins for business payments, think of it like this:
A stablecoin is like a “digital dollar” that can move quickly across borders. It can help with settlement and conversion, but it doesn’t remove reconciliation. It adds an extra leg you must track.
What do you store additionally?
- network used
- tx hash (the “reference” for the digital movement)
- token amount (e.g., USDC)
- timestamp
- origin/destination wallet (if relevant)
- proof (link/internal record)
One operational phrase that matters in Mexico is usdc to mxn liquidity.
In plain terms: “how easy and fast it is to go from USDC to Mexican pesos without friction.” If liquidity is low, execution can be slower or costlier.
From Excel to “autopilot”: what to ask from a platform/API
Excel helps you organize. But once volume grows, you’ll want automation.
If you’re evaluating an api for cross-border payments latam, don’t choose only on “price and coverage.” Ask operational questions:
- Do I get a clear transaction ID every time?
- Do I get automatic status updates (so I don’t have to check manually)?
- Can I export daily reports without manual work?
- Can I store proof centrally and consistently?
- Are statuses easy to understand and map?
The goal is to stop reconciliation from being “a painful month-end” and turn it into a quick daily process.
Reconciliation isn’t “accounting”, it’s operational speed
If you (or your team) spend hours hunting receipts, comparing amounts, and chasing references, your operation isn’t ready to scale.
The solution is not complicated:
- one internal reference per payment
- one channel tracking ID per payment
- simple statuses
- centralized proof
- exceptions with an owner
If you want, share how you reconcile today (even in bullets) and your rough monthly volume. With that, we can map the ideal “single sheet” and exception workflow for your real setup (channels, countries, and whether you use stablecoins).
*NVIO México enables direct access to SPEI and delivers payment services fully compliant with Mexican regulation. NVIO Pagos México, S.A.P.I. de C.V., IFPE (“NVIO México”) is authorised and regulated by the Mexican National Banking and Securities Commission (CNBV). Learn more at nvio.mx/terms.
You may also like
These related stories
Are stablecoins ready for marketplace payments in LATAM?
Global payroll for the remote era