Skip to main content

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, your company data and masked payout clabe,
  • a summary (transaction count, subtotal, commission, commission VAT, and the settlement totals grossPaid / returnedTotal / net totalPaid),
  • signed download links (files.json and files.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:

  1. It gathers your APPROVED sandbox sales created in the current settlement window (see The settlement window below), up to 1000 sales.

  2. 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 − commissionIva

    In production the real, negotiated commission of your commerce is used instead of this estimate.

  3. It gathers your RETURNED sandbox sales whose return date falls in the same window and lists them under returns[], subtracting each one's full sale amount from grossPaid to obtain the net totalPaid (see Including returns).

  4. It generates real, downloadable JSON and XLSX files from that data — with your real razón social, RFC, masked CLABE, your folioExternal values, 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.

  5. It delivers the payload to your configured endpoint with test: true.

Step by step

1. Configure the webhook

  1. Open the Conciliación page in the hub (log in with an admin or developer account).
  2. In the Webhook Pago recibido card, click Configurar webhook and set your endpoint URL and request method.
  3. 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 to APPROVED about 5 seconds after creation. These APPROVED sales become the transactions[] of your test corte.
  • Optionally, return one or more of them with POST /commerce/return-transaction to populate returns[] (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 summary and reconcile it against your seeded sales,
  • download files.json and files.xlsx from the signed links and parse them,
  • handle retries idempotently (see the note on paymentId below).

The settlement window

The sandbox test window runs from Monday of the current week (00:00, America/Mexico_City) to now:

  • transactions[] includes APPROVED sales created within the window.
  • returns[] includes RETURNED sales 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 folioExternalsettlementImpact in returns[]Meaning
(none)NOT_YET_SETTLEDThe sale had not been paid to you yet
COMMERCE_SETTLEDDISCOUNT_NEXT_SETTLEMENTThe sale was already paid in a prior corte

See the return simulation flags for the full matrix.

Reconciliation note. totalPaid subtracts the full amount of each return, even when the returned sale was not part of this window's grossPaid. Treat grossPaid and the returns[] detail as the reconciliation source, not totalPaid alone.

Worked example

Seed three sales in the current week and then return the first one:

SaleamountStatus after returncommission (3.5%)commissionIva (16%)totalPaid
Sale A1000.00RETURNED
Sale B2000.00APPROVED70.0011.201918.80
Sale C3000.00APPROVED105.0016.802878.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

AspectSandbox testProduction
TriggerProbar button on the Conciliación page (on demand)Automatic, when the corte is paid out
testtruefalse
paymentId0 for every test deliveryThe real settlement id
CommissionEstimate (SANDBOX_COMMISSION_RATE, default 3.5% + VAT)Your negotiated commission
PeriodMonday → now (approximation)The closed weekly settlement window
FilesReal & downloadable when available, otherwise examplesReal settlement files
warning

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.