- Callback Events
- Order Events
Callback Events
Order Events
Webhook event providing real-time order lifecycle updates including status changes, shipments, and shorts
Order Events provide real-time notifications for all order lifecycle changes, including status updates, shipment information, and inventory shorts. This is the primary mechanism for tracking order fulfillment progress.
Orders can ship in multiple packages. The shipments array may contain multiple shipment records for a single order.
​Event Payload
{
"callback_url": "https://client.com/api/orderEvent",
"message_type": "orderEvent",
"message_id": "0896116f-e54b-4756-9d3e-1b0c4a25d821",
"data": [
{
"order_id": "8f1316d5-859f-4802-98b0-63d03a9517ac",
"customer_identifier": "12345",
"status": "fulfilled",
"shipments": [
{
"shipment_id": "88888",
"shipping_provider": "UPS",
"shipper_service_level": "ground",
"tracking_number": "1z324897234nferg45",
"tracking_url": "http://ups.com/tracking/1z324897234nferg45",
"shipment_date_time": "2018-08-06T15:11:19Z",
"shipment_line_items": [
{
"sku_customer_id": "shirts872340",
"quantity": 2
}
]
}
],
"shorts": [
{
"sku_customer_id": "pants3422",
"quantity": 1,
"reason": "damage"
}
]
}
]
}
​Payload Fields
Your registered webhook endpoint URL
Always orderEvent for this event type
Unique identifier for this event. Use for idempotency checks.
Array of order updates. Each record contains:
​Order Status Values
atWarehouse
Order received at distribution center
inProcess
Order being picked and packed
packed
Order packed and ready to ship
fulfilled
Order shipped to customer
delivered
Order delivered to customer
canceled
Order canceled (see cancel reasons)
​Multi-Shipment Orders
Orders can ship in multiple packages when:
- Items are too large for a single package
- Items ship from different warehouse locations
- Inventory availability requires split shipments
- Business rules dictate splitting
​Multi-Shipment Example
{
"data": [
{
"order_id": "8f1316d5-859f-4802-98b0-63d03a9517ac",
"customer_identifier": "12345",
"status": "fulfilled",
"shipments": [
{
"shipment_id": "shipment-1",
"tracking_number": "1z324897234nferg45",
"shipment_line_items": [
{ "sku_customer_id": "shirts872340", "quantity": 2 }
]
},
{
"shipment_id": "shipment-2",
"tracking_number": "1z987654321abcdef",
"shipment_line_items": [
{ "sku_customer_id": "pants3422", "quantity": 1 }
]
}
]
}
]
}
Always handle multiple shipments per order. Iterate through the shipments array rather than assuming a single shipment.
​Implementation Example
@app.route('/api/orderEvent', methods=['POST'])
def handle_order_event():
try:
payload = request.get_json()
message_id = payload['message_id']
# Check if already processed
if is_message_processed(message_id):
return 'OK', 200
# Process each order update
for order in payload['data']:
order_id = order['customer_identifier']
status = order['status']
# Update order status
update_order_status(order_id, status)
# Handle shipments
if 'shipments' in order and order['shipments']:
for shipment in order['shipments']:
tracking = shipment['tracking_number']
carrier = shipment['shipping_provider']
# Update shipment info
add_shipment_tracking(order_id, tracking, carrier)
# Send customer notification
send_shipping_notification(order_id, tracking)
# Handle shorts
if 'shorts' in order and order['shorts']:
for short in order['shorts']:
sku = short['sku_customer_id']
qty = short['quantity']
reason = short['reason']
# Log short and notify customer
log_inventory_short(order_id, sku, qty, reason)
notify_customer_of_short(order_id, sku, qty)
mark_message_processed(message_id)
return 'OK', 200
except Exception as e:
logger.error(f"Order event webhook error: {e}")
return 'Error', 500
app.post('/api/orderEvent', async (req, res) => {
try {
const payload = req.body;
const messageId = payload.message_id;
// Check if already processed
if (await isMessageProcessed(messageId)) {
return res.status(200).send('OK');
}
// Process each order update
for (const order of payload.data) {
const orderId = order.customer_identifier;
const status = order.status;
// Update order status
await updateOrderStatus(orderId, status);
// Handle shipments
if (order.shipments?.length > 0) {
for (const shipment of order.shipments) {
await addShipmentTracking(
orderId,
shipment.tracking_number,
shipment.shipping_provider
);
// Send customer notification
await sendShippingNotification(orderId, shipment.tracking_number);
}
}
// Handle shorts
if (order.shorts?.length > 0) {
for (const short of order.shorts) {
await logInventoryShort(
orderId,
short.sku_customer_id,
short.quantity,
short.reason
);
await notifyCustomerOfShort(orderId, short.sku_customer_id);
}
}
}
await markMessageProcessed(messageId);
res.status(200).send('OK');
} catch (error) {
console.error('Order event webhook error:', error);
res.status(500).send('Error');
}
});
​Use Cases
Customer Notifications
Send shipping confirmations and tracking links automatically
Order Tracking
Update order status in customer portals and dashboards
Inventory Alerts
Monitor shorts to identify inventory issues
Analytics
Track fulfillment metrics and carrier performance
​Best Practices
Idempotency
Use message_id to prevent duplicate processing
Multi-Shipment Support
Always iterate through the shipments array
Error Handling
Handle missing fields gracefully (shipments/shorts may be absent)
Customer Communication
Automate shipping notifications for better customer experience
​Response Requirements
Your webhook endpoint must:
- Respond within 30 seconds - Return HTTP 200 to acknowledge receipt
- Use proper status codes:
200- Event processed successfully500- Processing error (MasonHub will retry)
- Handle all statuses - Support all order status values
- Process arrays - Handle multiple shipments and shorts per order
​Related Events
- Order Update Resolutions - Confirmation of order update requests
- Order Cancel Resolutions - Confirmation of cancel requests
- SKU Inventory Change Event - Inventory updates when orders ship