Docs/Operate your integration/Retries and reconciliation

Retries and reconciliation

Recover interrupted conversions without issuing twice or restoring points too early.

Track each conversion#

Store the customer account, intended wallet, issuer, chain, loyalty ID, amount, expiry, nonce, operationHash, exact request payload, session ID, operation ID, and completed receipt identity. These are different identifiers. Your brand ledger remains the source of offchain balances.

For Add to wallet, reserve or deduct eligible points atomically before publishing the request. Use an outbox to publish after committing that reservation. For Add from wallet, credit the customer only after a finalized burn has been verified and recorded exactly once.

Retry without creating another conversion#

SituationNext action
POST times out or returns 5xxRetain the reservation and retry the exact payload. Do not generate a new nonce or deadline.
Duplicate responseAssociate the returned session with the existing conversion. Never reserve points again.
409 conflictCompare the stored payload and nonce. Reconcile the existing operation before changing anything.
Wallet submission is uncertainCheck the existing transaction and operation. Do not create a second checkout to work around the delay.
Webhook arrives twice or out of orderDeduplicate in the same database transaction as the balance update. Reconcile current state before applying a late event.

Release a reservation only when execution is impossible#

A local timeout, failed API call, disabled key, rejected label, or closed browser does not prove that a signed action cannot execute. Check finalized chain state and the nonce, and account for completed receipts. Use a verified safe-expiry event or the expiry checks in Receipts and webhooks before releasing reserved points. A zero deadline cannot provide deadline-based release.

Recover after downtime and handle reversals#

Use cursor-based issuance and redemption receipt queries scoped to the expected chain, issuer, and program. Verify canonical finalized receipts and match the stored conversion. Commit the event record and balance adjustment together. Newly enabled webhook endpoints do not automatically backfill older activity.

For loyfin.reversed, locate data.originalIdempotencyKey and reverse or flag the original adjustment under your ledger policy. A receipt re-included in another block may have a new completion key: reconcile its earlier state instead of crediting it twice. See event payloads, signature verification, and replay.