Webhooks & retries
Server-side integrations with explicit payment confirmation and safe retries.
Register a receiver
Set your website and callback URL when creating an API key. The callback must use the same public HTTPS origin, port 443, and no redirect. Atlas Pay sends JSON by POST with an Atlas-Signature header. Copy the signing secret once and keep it server-side.
Events include payment.risk_updated, checkout.updated, refund.updated, order.paid, order.payment_updated, order.fulfilled, order.risk_blocked and order.risk_review. Risk events stop dispatch or fulfillment until the current order permits it. Each contains id, type, created_at, livemode, and data. The data object follows the corresponding resource schema in OpenAPI. Order events require the catalog/order release and migrations; see Products & orders.
Verify the raw body
Compute HMAC-SHA256 over timestamp + "." + rawBody using the signing secret. Require a timestamp within five minutes and compare the signature in constant time. Do not parse and reserialize the JSON before checking it.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody, signature, secret) {
const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(signature || '');
if (!match || !secret) return false;
if (Math.abs(Date.now() / 1000 - Number(match[1])) > 300) return false;
const expected = createHmac('sha256', secret)
.update(match[1] + '.' + rawBody).digest();
return timingSafeEqual(expected, Buffer.from(match[2], 'hex'));
}
Apply updates safely
- Verify the signature, payload size, and test/live mode. Reject invalid requests.
- Deduplicate by event ID using durable storage. Events can be delivered more than once or out of order.
- Retrieve the current checkout, order, or refund from Atlas Pay. Match reference, items, amount, currency and mode. For
on_deliverycatalog orders, require a freshauthorizedstatus, known unexpiredcapture_before, no settlement action, and no refund/dispute before dispatching. Capture follows trusted delivery confirmation;order.deliveredis not proof of captured payment. For legacyautomaticorders and standalone checkouts, require verified paid status first. Do not allow an older event to regress payment state or trigger duplicate dispatch. Read Delivery & payment holds. - Persist the update and deduplication record, then return a 2xx response. If processing fails, return a non-2xx response so the delivery can retry.
Delivery & recovery
Verified Stripe events are stored in Cloudflare D1 before callback delivery. A scheduled worker checks the outbox once per minute, processing up to 20 deliveries per run. Requests time out after eight seconds. Failed deliveries retry up to 12 attempts with exponential backoff capped at six hours. Delivery is at least once, not exactly once, and callback latency increases with backlog.
For recovery, read GET /events?after=0. Each page contains up to 100 events, a monotonically increasing sequence, next_cursor, and has_more. Persist the cursor only after processing the page. Sequence gaps are normal. The feed is workspace/mode scoped, including events from older keys. Retrieve current resource status before applying a recovered event.
Key expiration blocks API access but does not stop already-configured callbacks. Revocation stops both API access and that key’s callback delivery. For rotation, install the replacement key, reconcile old pending checkouts/refunds with the event feed, then revoke the old key. A single-secret plugin cannot verify both callback secrets simultaneously, so use a maintenance window.
This preview does not yet include a callback-delivery dashboard or a one-click replay control. Your integration must monitor failures and implement event-feed recovery before a live launch.
Standalone payment risk updates
payment.risk_updated contains payment_id, risk_decision and fulfillment_allowed. It is sent to the API key that created the associated checkout, using the same signed outbox and durable event feed. It can arrive after checkout completion. Stop fulfillment for review or block; retrieve the current checkout and verify status=paid, risk_decision=allow, fulfillment_allowed=true and your expected order details before fulfilling. A callback is a snapshot and may arrive late or out of order. Subscriptions and payment links without an API checkout association appear in the merchant dashboard and private admin alerts; this event does not add a subscription entitlement webhook.