Orders & Postbacks  ›  Retries & Idempotency

Retries & Idempotency

PriceFirst automatically retries failed postbacks with exponential backoff. Every attempt is logged on the order, and every retry carries the same order_code / X-PriceFirst-Idempotency so your handler can safely dedupe.

Attempt schedule

The first delivery is immediate (background task kicked off on order creation). If it fails, subsequent attempts are scheduled with the following delays:

AttemptDelay from previous failure
21 minute
35 minutes
415 minutes
51 hour
66 hours
724 hours

Retries stop as soon as:

  • The marchant responds HTTP 200 with a valid JSON body { status: 200, order_id }, or
  • The attempt count reaches (default 6), or
  • An admin manually marks the order delivered, or
  • postbackRetryEnabled is toggled false. Existing retries are left in place — they will either succeed or hit the attempt ceiling.

Admins can still manually trigger a resend at any time.

Idempotency

Every attempt for the same order sends:

  • The same JSON payload (order_code stays constant).
  • The same X-PriceFirst-Idempotency header (equal to order_code).
  • A different X-PriceFirst-Timestamp and therefore a different X-PriceFirst-Signature.

Dedupe on order_code (or X-PriceFirst-Idempotency), not on the signature. If you see the same order_code twice, return the same transaction ID you returned the first time — don't create a new internal record.

Attempt history on the order

Each order stores a full append-only log under Order.attempts in dashboard that is provided to marchat:

{
  "attemptNumber": 3,
  "startedAt": "2026-04-22T10:02:00.000Z",
  "finishedAt": "2026-04-22T10:02:01.187Z",
  "status": "failure",
  "httpStatus": 502,
  "responseBody": "<html><body>Bad Gateway</body></html>",
  "error": "HTTP 502: Bad Gateway",
  "durationMs": 1187
}
  • status is pending, success, or failure.
  • responseBody is truncated to 512 characters.

Failure classification

Any of the following marks an attempt as failure:

  • Non-2xx HTTP status.
  • Connection error (refused, DNS, TLS).
  • Timeout ( > 30 s).
  • Empty response body.
  • Body isn't valid JSON, or isn't a JSON object.
  • JSON body missing status: 200 or missing / empty order_id string.
  • Unhandled exception before the response is received.