Testing the Payment Received (Conciliación) webhook
This guide explains how to exercise the Payment Received webhook (settlement / conciliación of your cortes) end to end in the sandbox environment — without waiting for a real weekly settlement to be paid out.
For the full, field-by-field payload contract and the settlement file format, see Webhooks → Payment Received (Conciliación). This page focuses on the testing process.
What the webhook delivers
In production, PAYMENT_RECEIVED is emitted once per week, when your corte is paid out and the bank transfer is confirmed. It carries a fixed, versioned payload (version: "1.0") with:
- the settlement
period, yourcompanydata and masked payoutclabe, - a
summary(transaction count, subtotal, commission, commission VAT, and the settlement totalsgrossPaid/returnedTotal/ nettotalPaid), - signed download links (
files.jsonandfiles.xlsx) for the full settlement detail, valid for 24 hours.
The sandbox test reproduces exactly this payload so you can validate your endpoint, your signature/verification, your idempotency handling and your file download logic before going live.
How the sandbox test works
When you trigger a test, ZazPay builds an approximation of your real corte from your own sandbox data:
-
It gathers your
APPROVEDsandbox sales created in the current settlement window (see The settlement window below), up to 1000 sales. -
It estimates the commission per sale — by default 3.5% of the sale, plus 16% VAT on that commission (
SANDBOX_COMMISSION_RATE, configurable):commission = amount × 0.035
commissionIva = commission × 0.16
totalPaid = amount − commission − commissionIvaIn production the real, negotiated commission of your commerce is used instead of this estimate.
-
It gathers your
RETURNEDsandbox sales whose return date falls in the same window and lists them underreturns[], subtracting each one's full sale amount fromgrossPaidto obtain the nettotalPaid(see Including returns). -
It generates real, downloadable JSON and XLSX files from that data — with your real razón social, RFC, masked CLABE, your
folioExternalvalues, your external store ids and the returns detail — signed for 24 hours. If file generation is temporarily unavailable (or your sandbox commerce has no linked settlement profile), example file links are sent instead; the rest of the payload is still delivered. -
It delivers the payload to your configured endpoint with
test: true.
Step by step
1. Configure the webhook
- Open the Conciliación page in the hub (log in with an admin or developer account).
- In the Webhook Pago recibido card, click Configurar webhook and set your endpoint URL and request method.
- Save. The card now lists your webhook with an Activo badge.
2. Seed sandbox sales for the current window
Create some sales so the test has data to aggregate. Using the Commerce API (see API endpoints):
POST /commerce/generate-sale— in sandbox a sale auto-transitions toAPPROVEDabout 5 seconds after creation. TheseAPPROVEDsales become thetransactions[]of your test corte.- Optionally, return one or more of them with
POST /commerce/return-transactionto populatereturns[](see below).
Only sales inside the current settlement window are included, so create them in the same ISO week you run the test.
3. Trigger the test
Back on the Conciliación page, each configured webhook shows a Probar button in sandbox only. Click it. The button shows Enviando… while the test payload is built and delivered to your endpoint.
4. Verify on your side
At your endpoint you should receive a PAYMENT_RECEIVED request with test: true. Confirm that you:
- validate the request the same way you will in production (Bearer token / headers),
- read the
summaryand reconcile it against your seeded sales, - download
files.jsonandfiles.xlsxfrom the signed links and parse them, - handle retries idempotently (see the note on
paymentIdbelow).
The settlement window
The sandbox test window runs from Monday of the current week (00:00, America/Mexico_City) to now:
transactions[]includesAPPROVEDsales created within the window.returns[]includesRETURNEDsales whose return date falls within the window.
This mirrors the shape of the real weekly corte, but it is an approximation — the real production window is the closed settlement period.
Including returns (devoluciones)
A returned sale moves out of transactions[] (its status is no longer APPROVED) and appears in returns[]. Its full sale amount is subtracted from grossPaid, so:
totalPaid = grossPaid − returnedTotal
To seed returns, return an already-APPROVED sandbox sale with POST /commerce/return-transaction. The sandbox settlementImpact is driven by keywords in the original folioExternal:
Keyword in folioExternal | settlementImpact in returns[] | Meaning |
|---|---|---|
| (none) | NOT_YET_SETTLED | The sale had not been paid to you yet |
COMMERCE_SETTLED | DISCOUNT_NEXT_SETTLEMENT | The sale was already paid in a prior corte |
See the return simulation flags for the full matrix.
Reconciliation note.
totalPaidsubtracts the full amount of each return, even when the returned sale was not part of this window'sgrossPaid. TreatgrossPaidand thereturns[]detail as the reconciliation source, nottotalPaidalone.
Worked example
Seed three sales in the current week and then return the first one:
| Sale | amount | Status after return | commission (3.5%) | commissionIva (16%) | totalPaid |
|---|---|---|---|---|---|
| Sale A | 1000.00 | RETURNED | — | — | — |
| Sale B | 2000.00 | APPROVED | 70.00 | 11.20 | 1918.80 |
| Sale C | 3000.00 | APPROVED | 105.00 | 16.80 | 2878.20 |
The resulting summary is:
{
"transactionCount": 2,
"subtotal": 5000.0,
"commission": 175.0,
"commissionIva": 28.0,
"grossPaid": 4797.0,
"returnCount": 1,
"returnedTotal": 1000.0,
"totalPaid": 3797.0
}
transactions[] holds Sale B and Sale C; returns[] holds Sale A with amount: 1000.0. grossPaid (4797.00) minus returnedTotal (1000.00) gives the net totalPaid of 3797.00.
Sandbox vs production
| Aspect | Sandbox test | Production |
|---|---|---|
| Trigger | Probar button on the Conciliación page (on demand) | Automatic, when the corte is paid out |
test | true | false |
paymentId | 0 for every test delivery | The real settlement id |
| Commission | Estimate (SANDBOX_COMMISSION_RATE, default 3.5% + VAT) | Your negotiated commission |
| Period | Monday → now (approximation) | The closed weekly settlement window |
| Files | Real & downloadable when available, otherwise examples | Real settlement files |
Because every sandbox test delivery uses paymentId: 0, do not rely on paymentId to deduplicate deliveries while testing. In production paymentId is unique per settlement and is the idempotency key.
Related pages
- Webhooks → Payment Received (Conciliación) — full payload and file contract.
- API endpoints — creating and returning sales.
- Sandbox Guide — general sandbox behavior and test patterns.