Webhook Events
Reference for all webhook event types, payload variables, delivery mechanics, and signature verification.
Event Types
| Event Type | Trigger |
|---|---|
order.created |
Order created via hosted payment page or API submission. |
order.imported |
Order created via CSV import. |
order.fulfilment_requested |
A store order reached its fulfil point and entered the fulfilment queue. Integration-facing: never sent as a customer email. Same variables as order.created. |
order.fulfilled |
A store order was marked as fulfilled (picked and packed). Same variables as order.created. |
order.shipped |
A shipment was created for a store order. Carries the shipment; see the order.shipped variables below. |
order.delivered |
The latest shipment of a store order was marked as delivered. Same variables as order.shipped. |
order.returned |
A shipped or delivered store order was marked as returned. Same variables as order.shipped. |
transaction.created |
Transaction created via hosted payment page or API submission. |
transaction.imported |
Transaction created via CSV import. |
transaction.status_changed |
Transaction status updated (e.g., settlement CSV or webhook). |
chargeback.created |
Chargeback created via API or webhook. |
chargeback.imported |
Chargeback created via CSV import. |
subscription.created |
Subscription created via hosted payment page or API submission. |
subscription.credentials_issued |
Product-site login first stored for a subscription (once per subscription). Same variables as subscription.created. |
subscription.imported |
Subscription created via CSV import. |
subscription.status_changed |
Subscription status updated. |
payment_session.completed |
Payment session reached COMPLETED status. |
Payload Variables Per Event
Payloads are built from a configurable mapping. Each endpoint defines which variables to include in its payload. Available variables per event type:
order.created
| Variable Key | Type | Description |
|---|---|---|
order.id |
uuid | Order ID |
order.order_number |
string | Order number |
order.total_amount |
decimal | Total amount |
order.currency |
string | Currency |
order.status |
string | Order status |
order.created_at |
datetime | Created timestamp |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
lead.iban |
string | Customer IBAN |
lead.phone |
string | Customer phone |
campaign.id |
uuid | Campaign ID |
campaign.name |
string | Campaign name |
offer.id |
uuid | Offer ID |
offer.name |
string | Offer name |
offer.price |
decimal | Offer price |
product.name |
string | Product name |
order.imported
| Variable Key | Type | Description |
|---|---|---|
order.id |
uuid | Order ID |
order.order_number |
string | Order number |
order.total_amount |
decimal | Total amount |
order.currency |
string | Currency |
order.status |
string | Order status |
order.created_at |
datetime | Created timestamp |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
lead.iban |
string | Customer IBAN |
campaign.name |
string | Campaign name |
offer.name |
string | Offer name |
transaction.created
| Variable Key | Type | Description |
|---|---|---|
transaction.id |
uuid | Transaction ID |
transaction.merchant_transaction_id |
string | Merchant transaction ID |
transaction.tenant_reference_id |
string (nullable) | Merchant-owned reconciliation reference from /pay/ submission. null when not provided. |
transaction.amount |
decimal | Amount |
transaction.currency |
string | Currency |
transaction.status |
string | Status |
transaction.type |
string | Type |
transaction.date_processed |
datetime | Date processed |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
lead.iban |
string | Customer IBAN |
order.order_number |
string | Order number |
order.id |
uuid | Order ID |
transaction.imported
| Variable Key | Type | Description |
|---|---|---|
transaction.id |
uuid | Transaction ID |
transaction.merchant_transaction_id |
string | Merchant transaction ID |
transaction.amount |
decimal | Amount |
transaction.currency |
string | Currency |
transaction.status |
string | Status |
transaction.type |
string | Type |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
order.order_number |
string | Order number |
transaction.status_changed
| Variable Key | Type | Description |
|---|---|---|
transaction.id |
uuid | Transaction ID |
transaction.merchant_transaction_id |
string | Merchant transaction ID |
transaction.tenant_reference_id |
string (nullable) | Merchant-owned reconciliation reference from /pay/ submission. null when not provided. |
transaction.amount |
decimal | Amount |
transaction.currency |
string | Currency |
transaction.status |
string | New status |
transaction.type |
string | Type |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
order.order_number |
string | Order number |
Endpoints can filter on specific status values via the status_filter list. Only triggers when the new status matches a value in the filter.
chargeback.created
| Variable Key | Type | Description |
|---|---|---|
chargeback.id |
uuid | Chargeback ID |
chargeback.merchant_transaction_id |
string | Merchant transaction ID |
chargeback.amount |
decimal | Amount |
chargeback.currency |
string | Currency |
chargeback.status |
string | Status |
chargeback.report_date |
datetime | Report date |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
lead.iban |
string | Customer IBAN |
transaction.merchant_transaction_id |
string | Original transaction ID |
transaction.tenant_reference_id |
string (nullable) | Merchant-owned reference from the original /pay/ submission. null when the chargeback is unlinked or when the original submission did not supply a reference. |
chargeback.imported
| Variable Key | Type | Description |
|---|---|---|
chargeback.id |
uuid | Chargeback ID |
chargeback.merchant_transaction_id |
string | Merchant transaction ID |
chargeback.amount |
decimal | Amount |
chargeback.currency |
string | Currency |
chargeback.status |
string | Status |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
subscription.created
| Variable Key | Type | Description |
|---|---|---|
subscription.id |
uuid | Subscription ID |
subscription.status |
string | Status |
subscription.billing_amount |
decimal | Billing amount |
subscription.currency |
string | Currency |
subscription.billing_frequency |
string | Billing frequency |
subscription.start_date |
datetime | Start date |
subscription.next_billing_date |
date | Next billing date |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
order.order_number |
string | Order number |
offer.name |
string | Offer name |
subscription.imported
| Variable Key | Type | Description |
|---|---|---|
subscription.id |
uuid | Subscription ID |
subscription.status |
string | Status |
subscription.billing_amount |
decimal | Billing amount |
subscription.currency |
string | Currency |
subscription.billing_frequency |
string | Billing frequency |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
order.order_number |
string | Order number |
subscription.status_changed
| Variable Key | Type | Description |
|---|---|---|
subscription.id |
uuid | Subscription ID |
subscription.status |
string | New status |
subscription.billing_amount |
decimal | Billing amount |
subscription.currency |
string | Currency |
subscription.next_billing_date |
date | Next billing date |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
order.order_number |
string | Order number |
payment_session.completed
| Variable Key | Type | Description |
|---|---|---|
session.token |
string | Session token |
session.status |
string | Session status |
order.id |
uuid | Order ID |
order.order_number |
string | Order number |
order.total_amount |
decimal | Total amount |
order.currency |
string | Currency |
lead.email |
string | Customer email |
lead.first_name |
string | Customer name (currently resolves to lead.full_name) |
lead.last_name |
string | Customer name (currently resolves to lead.full_name) |
campaign.name |
string | Campaign name |
transaction.tenant_reference_id |
string (nullable) | Merchant-owned reference from the session's /pay/ submission (resolved via the Transaction linked to session.order). null when the submission did not supply a reference. |
order.shipped
Also used by order.delivered and order.returned. The context is the shipment; order values are read from the shipment's order. Values a store order does not have (no storefront domain, no merchant profile field) are empty strings.
| Variable Key | Type | Description |
|---|---|---|
shipment.id |
uuid | Shipment ID |
shipment.carrier |
string | Carrier |
shipment.tracking_number |
string | Tracking number |
shipment.tracking_url |
url | Tracking URL |
shipment.shipped_at |
datetime | Shipped timestamp |
shipment.delivered_at |
datetime | Delivered timestamp (null until delivered) |
shipment.returned_at |
datetime | Returned timestamp (null until returned) |
order.id |
uuid | Order ID |
order.order_number |
string | Order number |
order.status |
string | Order status |
order.fulfilment_status |
string | Fulfilment status (unfulfilled, fulfilled, shipped, delivered, returned) |
order.total_amount |
decimal | Total amount |
order.currency |
string | Currency |
order.channel |
string | Order channel (store, funnel, csv, api) |
order.created_at |
datetime | Order created timestamp |
order.line_count |
integer | Number of order lines |
order.lines_json |
string | Order lines as a JSON array |
order.subtotal |
decimal | Subtotal (goods before discount) |
order.shipping_total |
decimal | Shipping total |
order.shipping_address_text |
string | Shipping address on one line |
shipping_address.name |
string | Ship to: name |
shipping_address.line1 |
string | Ship to: address line 1 |
shipping_address.line2 |
string | Ship to: address line 2 |
shipping_address.city |
string | Ship to: city |
shipping_address.postal_code |
string | Ship to: postal code |
shipping_address.country |
string | Ship to: country (ISO alpha-2) |
shipping_address.phone |
string | Ship to: phone |
lead.email |
string | Customer email |
lead.full_name |
string | Customer name |
lead.phone |
string | Customer phone |
lead.country |
string | Customer country |
storefront.name |
string | Storefront name |
storefront.url |
url | Storefront URL |
storefront.locale |
string | Storefront language |
storefront.legal_urls.terms |
url | Terms page URL |
storefront.legal_urls.privacy |
url | Privacy page URL |
storefront.legal_urls.withdrawal |
url | Withdrawal page URL |
storefront.legal_urls.imprint |
url | Imprint page URL |
shipping_method.name |
string | Shipping rate chosen at checkout |
order_lookup_url |
url | The storefront's order lookup page |
merchant.legal_name |
string | Merchant legal name |
merchant.creditor_id |
string | SEPA creditor ID |
merchant.support_email |
Merchant support email | |
merchant.logo_url |
url | Merchant logo URL |
merchant.address |
string | Merchant address on one line |
merchant.vat_id |
string | Merchant VAT ID |
merchant.register_number |
string | Merchant register number |
merchant.contact_phone |
string | Merchant contact phone |
The order.created, order.fulfilment_requested and order.fulfilled events carry the same order.fulfilment_status, order.shipping_address_text, order.line_count, shipping_address.*, lead.country, storefront.*, shipping_method.name, order_lookup_url and merchant.* variables, read from the order itself.
Delivery Methods
Each webhook endpoint is configured with one of two delivery methods:
| Method | HTTP | Payload Location |
|---|---|---|
JSON_POST |
POST | JSON request body |
URL_PARAMS |
GET | URL query parameters |
Signature Verification
All webhook deliveries include an HMAC-SHA256 signature for payload verification.
Headers
| Header | Value |
|---|---|
Content-Type |
application/json |
X-WaveRunner-Event |
Event type string (e.g., order.created) |
X-WaveRunner-Signature |
HMAC-SHA256 hex digest |
User-Agent |
WaveRunner-Webhook/1.0 |
Signature Computation
- Serialize the JSON payload with sorted keys and compact separators:
json.dumps(payload, sort_keys=True, separators=(',', ':')) - Compute HMAC-SHA256 using the webhook profile's
signing_secretas the key. - The result is a lowercase hex digest in the
X-WaveRunner-Signatureheader.
The signing secret is generated per webhook profile (44 characters, base64url-encoded, 256 bits of entropy).
Retry Schedule
Failed deliveries (HTTP 5xx or 429) are retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |
Maximum retries: 5. After all retries are exhausted, the delivery is marked as FAILED.
Network errors (connection timeout, DNS failure) follow the same retry schedule.
Circuit Breaker
Each webhook endpoint tracks consecutive failures. After 20 consecutive failures, the endpoint is automatically disabled (is_active = false).
A successful delivery (HTTP 2xx) resets the failure counter to 0.
HTTP Requirements for Webhook Endpoints
- Must respond within 15 seconds (request timeout).
- Must return an HTTP 2xx status code to indicate successful receipt.
- HTTP 4xx responses (except 429) are treated as permanent failures and are not retried.
- HTTP 429 and 5xx responses trigger retry with backoff.
- Response body is logged (truncated to 5,000 characters).
Webhook Queues
| Queue | Used For |
|---|---|
webhooks_high |
Real-time events (API/HPP submissions). |
webhooks_low |
Bulk events (CSV imports). |
See Webhooks for setup instructions.