Skip to main content

Overview

Webhooks notify your server when events happen in Shoppex. Use them to:
  • Fulfill orders automatically
  • Update your database
  • Send custom notifications
  • Integrate with external services
This page covers normal Shoppex event webhooks like order:paid and subscription:created, including the secrets created in Settings -> Webhooks. If you are implementing a DYNAMIC product with dynamic_webhook, use Dynamic Product Delivery.
You can register webhooks through the dashboard or manage webhook subscriptions through the Developer API. The event payload is the same either way.

Setting Up Webhooks

1

Create Endpoint

Create an HTTP endpoint on your server that accepts POST requests:
2

Register in Dashboard

Go to Settings → Webhooks → Add Endpoint and enter your URL.
3

Select Events

Choose explicit event names, for example:
  • order:paid
  • order:cancelled
  • subscription:created
If you use the Dev API, fetch the full allowlist from GET /dev/v1/webhooks/events.

Webhook Payload

All webhooks follow this structure:
Dashboard test deliveries use the same top-level envelope as live deliveries: event, data, and created_at. The values inside data are synthetic, but the signature covers the full raw JSON body exactly the same way as a real webhook.
Top-level webhook created_at is a Unix timestamp. Nested timestamps inside data can be ISO 8601 strings.
One invoice can produce more than one payment attempt over time. For example, a customer can retry a payment or switch gateways. Treat the Shoppex invoice ID and event type as the durable business signal, not a single provider session.
Order webhooks can also include payment-context fields like exchange_rate, crypto_exchange_rate, crypto_gateway, and apm_method. These help with reconciliation and analytics without requiring a follow-up invoice fetch in common cases.

Available Events

Common Order Events

If a paid checkout reduces product stock, handle order:paid or order:paid:product. Shoppex does not send product:stock as a second event for every purchase-driven stock decrement. Use product:stock for direct catalog stock updates, for example when stock is edited through the dashboard or API.

Common Subscription Events

Shoppex supports more event names than the short guide tables above. Examples: order:created, order:updated, order:partial, order:disputed, subscription:trial:started, subscription:updated, subscription:renewed, subscription:upcoming, plus product/query/feedback/affiliate events. Use Webhook Events Reference or GET /dev/v1/webhooks/events for the full current list.

Verifying Webhooks

Always verify webhook signatures to ensure authenticity. New integrations should verify X-Shoppex-Signature-V2. Shoppex signs ${deliveryId}.${timestamp}.${rawBody} using HMAC-SHA256:
Shoppex signs the full JSON request body exactly as sent on the wire. Simple example: verify {"event":"order:paid","data":{...},"created_at":1775764170}, not just the inner data object. Use the per-webhook secret from Settings -> Webhooks for that endpoint. Per-payment callbacks created with the webhook field on POST /dev/v1/payments use the webhook_secret returned in that payment creation response instead. The v1 segment in X-Shoppex-Signature-V2 is a version marker, not the signature. Simple example: in v1,t=1775764170,h=abc..., verify the h value. Do not verify JSON.stringify(req.body) after parsing. Verify the raw body bytes from the incoming HTTP request instead.

Webhook Headers

X-Shoppex-Signature and X-Shoppex-Unescaped-Signature are deprecated legacy headers. Use X-Shoppex-Signature-V2 for new integrations.

Retry Policy

If your endpoint returns an error (non-2xx status), we retry: After the 5th failed attempt, the webhook is marked as failed. You can manually retry from the dashboard.
Your endpoint must respond within 30 seconds or the request will timeout.

Best Practices

Process webhooks asynchronously. Return 200 immediately and handle the event in a background job.
Webhooks may be delivered more than once. Use the delivery ID to deduplicate, and make your fulfillment logic idempotent.
A provider can have retries, delayed confirmations, or multiple attempts for one invoice. Good example: mark an order fulfilled when Shoppex tells you the invoice is paid, not when you first see a provider-specific session ID.
Always verify webhook signatures in production to prevent spoofing. Simple example: use the raw request body, not a parsed and re-serialized object.
Dashboard test deliveries now use the same webhook envelope and core order fields as live deliveries. Simple example: a test order:paid webhook includes fields like gateway, currency, total_display, and apm_method, not just a minimal placeholder object.

Next Steps

Webhook Events Reference

Full list of all event types and payload schemas

Dynamic Delivery

Real-time product delivery via webhook response