Order Webhooks & Notifications

The Orders module supports outbound webhooks for external integrations and configurable notification rules for customer/team alerts.

Outbound Webhooks

Register HTTP endpoints to receive real-time order event notifications.

Creating an Endpoint

POST /api/v1/order-webhooks

{
  "url": "https://yourapp.com/webhook/orders",
  "secret": "whsec_your_signing_secret",
  "events": [
    "order.created",
    "order.status_changed",
    "order.delivered",
    "order.cancelled"
  ],
  "is_active": true
}

Webhook Delivery

When an order event occurs, the system:

  1. Finds all active endpoints subscribed to that event
  2. Dispatches a SendOutboundWebhookJob for each (queued, 3 retries with 60s backoff)
  3. Sends POST request with JSON body:
{
  "event": "order.status_changed",
  "payload": {
    "order_id": "uuid",
    "order_number": "ORD-20260305-A1B2",
    "old_status": "pending",
    "new_status": "confirmed"
  },
  "timestamp": "2026-03-05T10:30:00+00:00"
}

Signature Verification

If a secret is configured, the request includes an X-Webhook-Signature header:

X-Webhook-Signature: <HMAC-SHA256 of JSON body using secret>

Verify in your receiver:

import hmac, hashlib

signature = request.headers['X-Webhook-Signature']
expected = hmac.new(secret.encode(), request.body, hashlib.sha256).hexdigest()
assert hmac.compare_digest(signature, expected)

Failure Handling

  • Failed deliveries are retried 3 times with 60-second backoff
  • After 10 consecutive failures, the endpoint is automatically disabled
  • All deliveries are logged with response status, body (truncated to 2KB), and duration

Delivery Logs

GET /api/v1/order-webhooks/{endpoint}/logs

Returns paginated delivery history with status codes and response times.


Notification Rules

Configure automatic notifications triggered by order events.

Creating a Rule

POST /api/v1/order-notification-rules

{
  "name": "Order Shipped SMS",
  "event": "order.fulfilled",
  "channel": "sms",
  "recipient_type": "customer",
  "template": "Hi {{customer_name}}, your order #{{order_number}} has been shipped! Track: {{tracking_url}}",
  "conditions": {},
  "is_active": true
}

Supported Channels

Channel Delivery
sms Via SMS provider module (bus call)
whatsapp Via WhatsApp channel module (bus call)
email Via email service (bus call)
in_app Via NotificationService (in-app notifications)

Template Placeholders

Placeholder Value
{{order_number}} Order number
{{customer_name}} Customer full name
{{total}} Order total
{{status}} Current order status
{{tracking_url}} Shipment tracking URL
{{return_number}} Return number (for return events)

Conditions

Rules can include conditions to filter which events trigger them:

{
  "conditions": {
    "new_status": "confirmed",
    "payment_status": "cod"
  }
}

Test Send

POST /api/v1/order-notification-rules/{rule}/test

Sends a test notification with sample data to verify the template and delivery channel.


Custom Fields

Define tenant-specific custom fields that appear on orders.

Field Types

Type Description Options
text Free text input
number Numeric input
select Dropdown selection Array of option values
boolean Toggle (yes/no)
date Date picker

Creating a Field

POST /api/v1/order-custom-fields

{
  "field_key": "priority_level",
  "field_label": "Priority Level",
  "field_type": "select",
  "options": ["low", "normal", "high", "urgent"],
  "is_required": false,
  "is_filterable": true,
  "sort_order": 1
}

Using Custom Fields

Custom field values are stored in the order's custom_fields JSONB column:

PATCH /api/v1/orders/{order}

{
  "custom_fields": {
    "priority_level": "high",
    "delivery_instructions": "Leave at door"
  }
}

Fields marked as is_filterable can be used in order list queries.