Skip to main content

Reconciliation

Notifications can be missed — a webhook endpoint is down past the retry window, a callback never fires because the customer closed the tab. Reconciliation is the safety net that guarantees every payment eventually reaches the right end state on your side, without a human chasing it.

The whole approach rests on one property: verify is idempotent and always returns the current authoritative state, including a harmless PENDING for payments that have not resolved yet. That makes it safe to call verify as often as you like.

The pattern​

  1. Store paymentUid at creation. It is your correlation key for the callback, the webhook, and verify — persist it against your order immediately.
  2. Deduplicate triggers by paymentId. Webhook delivery is at-least-once; if you have already processed a terminal status for a payment, acknowledge with 200 and do nothing.
  3. Fulfil only from a verified outcome. On any trigger, call verify and act on its status — never on the callback or webhook payload.
  4. Sweep unresolved payments. Run a periodic job that calls verify for every payment still unresolved on your side after its deadline (createdAt + timeoutSeconds, i.e. past expiresAt). A missed webhook can then never strand an order.

Which statuses to act on​

Verified statusAction
SUCCESS, ACCEPTABLEFulfil the order.
MISMATCHHold for manual review — check deviationUsd.
EXPIREDCancel the order.
PENDINGNot resolved yet — leave it; the sweep will pick it up on a later pass.

Do not auto-fulfil PENDING, MISMATCH, or EXPIRED.

Notes​

  • Verifying quiets a still-pending webhook — if your sweep verifies first, Finomesh skips the now-redundant webhook. The two channels self-dedupe.
  • A reasonable sweep cadence is every few minutes over payments created in the last day that you have not yet marked resolved. Tune to your volume.
  • If a customer insists they paid but the payment is still PENDING well past its expiry, you can hand us their transaction hash directly — see Submit transaction inquiry. It's a support escalation, not part of the sweep: attempts are limited and each one drives live chain lookups.