Postback URLs do not replace the Automations module - they are complementary. Automations are great for branching logic, retries with conditions, and connecting many third-party services. Postback URLs are great for “fire-and-forget” event forwarding.
Where to configure
In your brand:- Go to Settings → Merchants → pick a merchant → Edit.
- Open the Postback URLs tab.
- For each event you care about, set:
- Postback URL -
https://your-app.example.com/webhooks/elasticfunnels - Bearer Token (optional) - sent as
Authorization: Bearer <token>so you can do basic auth from a reverse proxy. - Enabled - must be checked for the URL to fire.
- Postback URL -
- Use the Send test button next to each URL to deliver a sample payload right away.
- The Recent deliveries section shows status, HTTP code, attempts, the exact payload that was sent, and lets you retry failed deliveries manually.
Supported events
You can configure a different URL per event, or use the same URL for every event - your handler can branch on the
event field and on the X-EF-Event header.
Request format
Every request looks like this:Verifying the signature
Reject any request whose recomputed signature does not matchX-EF-Signature. Always compare with a constant-time function (hash_equals in PHP, crypto.timingSafeEqual in Node, etc.). It is also a good idea to reject requests whose X-EF-Timestamp is more than a few minutes in the past or future.
Response handling
- Return any
2xxstatus to acknowledge the delivery. The body is ignored (but stored in the deliveries log for debugging - keep it under a few KB). - Any non-2xx response, timeout, or connection error counts as a failure.
- Failed deliveries are retried automatically with exponential backoff:
1m → 5m → 30m → 2h → 12h(up to 5 attempts). After the final failure the delivery is marked dead and stops retrying. You can re-queue it manually from the Postback URLs tab. - Each delivery has a unique
X-EF-Delivery-Id. Use it to dedupe on your end.
Standardized payload
All events share the same envelope. Fields that don’t apply to a given event are present butnull. The full schema:
Event-specific notes
refund/chargeback-amounts.totalis negative for the refunded portion, andorder.original_conversion_codereferences the original purchase row.subscription_renewal_failed-order.subscription.retry_countandorder.subscription.next_charge_atreflect the dunning schedule, andmeta.payment_statuswill typically befailedwith a populatedorder.subscription.decline_reason.subscription_cancel-order.subscription.statusiscancelledandorder.subscription.cancel_reasonis filled when available.shipped- fires the first time a tracking number is set on an order.shipping.tracking_number,shipping.tracking_url, andshipping.carrierare populated. We dedupe per order so you only get oneshippedevent.abandon-order.statusisabandonedandcustomermay be partially populated depending on how far the visitor got in checkout.test- Postbacks fired from the Send test button or originating from a sandbox merchant settest: true. Use it to gate side effects in your handler.
Example: minimal Express.js handler
Operational details
- Deliveries are processed asynchronously so they do not block the gateway request that triggered them.
- Failed deliveries are retried automatically after the configured backoff window has elapsed.
- The Postback URLs tab shows recent deliveries, including the URL, payload, headers, response body, attempts, and final status.
- The signing secret is stored encrypted at rest. Rotating it invalidates all previous signatures immediately - only do it if you can update your verifier in lockstep.