Initialization
Idempotent on (`shop_id`, `orderId`, `amountCents`, `currency`, optional `remittanceInfo`). Safe to retry.
Custom REST integrations are split across three retry surfaces: payment initialization, status polling, and webhook handling. Each has different idempotency guarantees and retry policies on Foxpay's side.
Idempotent on (`shop_id`, `orderId`, `amountCents`, `currency`, optional `remittanceInfo`). Safe to retry.
Read-only and naturally idempotent. Safe to retry on 5xx; redirect buyers based on the latest read.
At-least-once delivery, up to 3 attempts. Process by `X-Foxpay-Delivery` for deduplication.
POST /payments/initialize reuses an existing pending transaction when the new request shares the merchant store, order id, amount in cents, currency, and (when supplied) the same merchant-supplied remittance reference. The reuse response includes message: "Using existing pending transaction to prevent duplicate" so you can distinguish reuse from a fresh creation.
| Match field | Source | Behavior on mismatch |
|---|---|---|
shop_id | Resolved from `merchantId` (or the `shopId` alias) | 404 invalid merchant ID |
order_id | Request body orderId | New transaction created (different order) |
amount | Request body amountCents | New transaction created (amount-correction case) |
currency | Request body currency | New transaction created |
remittance_info | Request body remittanceInfo (only when supplied) | New transaction created when the supplied value differs; if you omit remittanceInfo, any pending transaction matching the other four fields is eligible for reuse |
orderId for the lifetime of an order. Never recycle order ids across distinct buyer attempts.paymentId immediately. If your request retries before persistence, the next call will return the same paymentId via reuse.GET /payments/{paymentId}/status is read-only and idempotent.GET /payments/{paymentId}/bank-details?orderId=… is also read-only.Foxpay treats outbound webhook delivery as at-least-once. Your handler is responsible for deduplication and idempotent processing.
| Surface | Foxpay side | Merchant side |
|---|---|---|
| Attempts (queue path) | Up to 12 per delivery across ~7 days with ±20% jitter | Use X-Foxpay-Delivery as the dedupe key |
| Attempts (legacy path) | Up to 3 per delivery; being rolled forward per merchant | Same dedupe key applies |
| Schedule (queue path) | Inline, then 30s · 2m · 10m · 30m · 2h · 6h · 24h (hot), then +24h · +24h · +36h · +48h (long-tail) | Persist + ack before downstream business logic |
| Per-attempt timeout | 30s on the queue path; 30s/45s/60s on the legacy path | Respond well within 30s to avoid retries |
| No-retry HTTP statuses | 400, 401, 403, 404, 410 (both paths) | Surface fixable failures with these codes; surface transient failures with 5xx |
| Manual redelivery | Per-transaction Resend button on the Technical Info tab of /transactions | Brings the next attempt due within ~1 minute and resets the curve when reopening a terminal job |
| Failure escalation | One "webhook delivery failed" email when the job moves to the terminal state (exhausted / dead) | Trigger redelivery from the panel after fixing |
(merchant_id, foxpay_delivery_id) to absorb duplicate deliveries.orderId, amountCents, or currency across retries — that breaks reuse and creates duplicate pending transactions.message field to know whether you triggered a fresh create or hit reuse.