Skip to main content

Webhooks

Webhooks allow your application to receive real-time notifications when specific events occur in your Wuilt store. Instead of repeatedly polling our API for changes, webhooks push event data to your application as soon as something happens.

Need Help with Webhooks?

Use our AI Assistant powered by Context7 to get instant answers and code examples for webhook setup and troubleshooting. Chat with the docs →

How to Set Up Webhooks​

1. Create a Webhook Endpoint​

First, create an endpoint in your application that can receive HTTP POST requests from Wuilt:

Example Nodejs Webhook implementation:

const express = require("express");
const app = express();

// Middleware to parse JSON payloads
app.use(express.json());

// Webhook endpoint
app.post("/webhooks/wuilt", (req, res) => {
console.log("Received webhook:", {
body: JSON.stringify(req.body, null, 2),
headers: req.headers,
});
// Always respond with 200 OK
res.status(200).send("OK");
if (req.body.test) {
return console.log("Received test webhook:", { body: req.body });
}
const { event, payload, metadata } = req.body;

// Process the webhook based on event type
switch (event) {
case "ORDER_PLACED":
handleOrderPlaced(payload);
break;
case "PRODUCT_UPDATED":
handleProductUpdated(payload);
break;
case "SHIPMENT_UPDATED":
handleShipmentUpdated(payload);
break;
case "CART_ITEM_ADDED":
handleCartItemAdded(payload);
break;
case "CHECKOUT_INITIATED":
handleCheckoutInitiated(payload);
break;
case "CART_ABANDONED":
handleCartAbandoned(payload);
break;
// Handle other events...
default:
console.log("Unknown event type:", event);
}
});

app.listen(3000, () => {
console.log("Webhook server listening on port 3000");
});

2. Access the Dev tools Section​

  1. From the left sidebar menu, scroll down to SETTINGS
  2. Click on Dev Tools at the bottom of the settings menu

Access & Permissions Menu

3. Notifications Webhooks​

Click on Notifications Webhooks card.

Access & Permissions Menu

4. Register Your Webhook in the Wuilt Dashboard​

To set up webhooks, navigate to your Wuilt dashboard and follow these steps:

  1. Access Webhook Settings: Go to your store settings and find the "Webhooks" section.

Webhook Settings

  1. Configure Your Webhook: Enter your webhook URL and select the events you want to receive notifications for.

Webhook Configuration

Available Events:

Order Events:

  • ORDER_PLACED - When a new order is created
  • ORDER_UPDATED - When an order is modified
  • ORDER_CANCELED - When an order is canceled

Product Events:

  • PRODUCT_CREATED - When a new product is added
  • PRODUCT_UPDATED - When a product is modified
  • PRODUCT_DELETED - When a product is removed

Customer Events:

  • CUSTOMER_CREATED - When a new customer registers
  • CUSTOMER_UPDATED - When customer information is updated

Shipment Events:

  • SHIPMENT_UPDATED - When a shipment status changes (pickup, delivery attempts, delivery, returns)

Cart & Checkout Events:

  • CART_ITEM_ADDED - When a customer adds an item to their cart
  • CHECKOUT_INITIATED - When a customer begins the checkout process
  • CART_ABANDONED - When a cart with contact information has been inactive for over 60 minutes

Event Payloads​

All webhook payloads follow the same structure defined by the WebhookPayload interface:

interface WebhookPayload<T = any> {
event: string; // Event type (e.g., 'ORDER_PLACED')
payload: T; // Event data, structure varies by event type
metadata: {
apiVersion: string; // API version used
timestamp: string; // ISO timestamp of when the event occurred
storeId: string; // ID of the store that triggered the event
};
}

interface OrderStatusEvent {
orderId: string;
airwayBillId: string;
companyName: string;
cost: number;
location: ShippingLocation;
storeId: string;
trackingNumber: string;
orderSerial: number;
}

interface ShippingLocation {
country: string;
governorate: string;
city: string;
fullAddress?: string;
}

Order Events​

ORDER_PLACED​

Triggered when a new order is successfully placed.

Payload Type: { order: OrderDocument }

View ORDER_PLACED payload example
{
"event": "ORDER_PLACED",
"payload": {
"order": {
"_id": "cmdlpac7n000201pm3dgifkqu",
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"cartId": "d3f61199-b262-4deb-a42d-31a5b93952b0",
"status": "SUCCESSFUL",
"errors": [],
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"totalPrice": {
"amount": 3200,
"currencyCode": "EGP"
},
"shippingRateCost": {
"amount": 75,
"currencyCode": "EGP"
},
"fulfillmentStatus": "UNFULFILLED",
"notes": "",
"shippingRateId": "clzvqvezy0004017i4vwe4667",
"shippingRateName": "Bosta",
"promoCodeSnapshot": null,
"isArchived": false,
"isCanceled": false,
"isViewed": false,
"customerId": "cm4qwyzfv000g018y6mv39bnd",
"itemsCount": 1,
"fulfilledItems": 0,
"shippingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"billingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"promoCode": null,
"customer": {
"name": "John Doe",
"email": "john.doe@gmail.com",
"phone": "+201111111111",
"isSubscribedToNewsLetter": true
},
"storeData": {
"name": "John Doe",
"logo": null,
"email": "john.doe@gmail.com",
"phone": "115050"
},
"items": [
{
"_id": "08672157-9dc9-443d-a74c-cb55312162d4",
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"productSnapshot": {
"id": "cmdeh9e2h00d801xoco4ngtt5",
"type": "SIMPLE",
"media": ["cmdeh6b4c004201ceeufm8fqu", "cmdeh6b4c004301ceefuk40e4"],
"title": "Product Title",
"handle": "product-handle",
"locale": "en",
"source": "MANUAL",
"status": "ACTIVE",
"options": "",
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"taxable": false,
"isVisible": true,
"productTax": 0,
"translations": [],
"collectionIds": [],
"descriptionHtml": "",
"integrationProvider": {
"icon": {
"src": "",
"altText": ""
},
"name": "MANUAL",
"provider": "MANUAL",
"websiteLink": ""
}
},
"title": "Product Title",
"fulfilledItems": 0,
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"quantity": 1,
"discount": null,
"discounts": [],
"type": "SIMPLE",
"variantId": "cmdeh9e2h00d901xo8oqu5a2x",
"variantSnapshot": {
"id": "cmdeh9e2h00d901xo8oqu5a2x",
"sku": "product-sku",
"type": "variant",
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"quantity": 10,
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"externalId": "",
"trackQuantity": true,
"compareAtPrice": {
"amount": 3150,
"currencyCode": "EGP"
},
"selectedOptions": [],
"selectedOptionsIds": [],
"selectedOptionValuesIds": []
},
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"options": [],
"sourceType": "MANUAL",
"productTax": null,
"taxable": false,
"quantityChanged": false,
"categories": [],
"manualDiscounts": []
}
],
"externalActionMessage": [],
"paymentMethod": "CASH_ON_DELIVERY",
"paymentStatus": "PENDING",
"paidAmount": {
"amount": 0,
"currencyCode": "EGP"
},
"shippingStatus": "PENDING",
"taxSnapshot": null,
"receipt": {
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"discount": {
"amount": 0,
"currencyCode": "EGP"
},
"tax": {
"amount": 0,
"currencyCode": "EGP"
},
"shipping": {
"amount": 200,
"currencyCode": "EGP"
},
"total": {
"amount": 3200,
"currencyCode": "EGP"
},
"automaticDiscount": {
"amount": 0,
"currencyCode": "EGP"
}
},
"discounts": [],
"locale": "en",
"refCode": null,
"paymentIntentId": "cmdlpac07000d016o65sn713a",
"wuiltShipmentProvider": "Bosta",
"packagingDetails": {
"extraWeight": 0,
"extraVolumetricWeight": 0,
"weight": 0,
"volumetricWeight": 0.0003333333333333333,
"shippingCostDetails": {
"baseCost": 75,
"returnCost": 88,
"baseWeightLimit": 20,
"extraWeightCost": 0,
"extraWeightStep": 0,
"returnToOriginCost": 68
},
"flyer": "X_LARGE"
},
"tags": [],
"openPackageOption": null,
"manualDiscounts": [],
"orderSerial": "418",
"createdAt": "2025-07-27T13:14:03.056Z",
"updatedAt": "2025-07-27T13:14:03.056Z"
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-15T10:30:00Z",
"storeId": "store_abc123def456"
}
}

ORDER_UPDATED​

Triggered when an existing order is modified (status change, items updated, etc.).

Payload Type: { events: string[], order: OrderDocument }

View ORDER_UPDATED payload example
{
"event": "ORDER_UPDATED",
"payload": {
"events": ["status_changed", "fulfillment_updated"],
"order": {
"_id": "cmdlpac7n000201pm3dgifkqu",
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"cartId": "d3f61199-b262-4deb-a42d-31a5b93952b0",
"status": "SUCCESSFUL",
"errors": [],
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"totalPrice": {
"amount": 3200,
"currencyCode": "EGP"
},
"shippingRateCost": {
"amount": 75,
"currencyCode": "EGP"
},
"fulfillmentStatus": "UNFULFILLED",
"notes": "",
"shippingRateId": "clzvqvezy0004017i4vwe4667",
"shippingRateName": "Bosta",
"promoCodeSnapshot": null,
"isArchived": false,
"isCanceled": false,
"isViewed": false,
"customerId": "cm4qwyzfv000g018y6mv39bnd",
"itemsCount": 1,
"fulfilledItems": 0,
"shippingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"billingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"promoCode": null,
"customer": {
"name": "John Doe",
"email": "john.doe@gmail.com",
"phone": "+201111111111",
"isSubscribedToNewsLetter": true
},
"storeData": {
"name": "John Doe",
"logo": null,
"email": "john.doe@gmail.com",
"phone": "115050"
},
"items": [
{
"_id": "08672157-9dc9-443d-a74c-cb55312162d4",
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"productSnapshot": {
"id": "cmdeh9e2h00d801xoco4ngtt5",
"type": "SIMPLE",
"media": ["cmdeh6b4c004201ceeufm8fqu", "cmdeh6b4c004301ceefuk40e4"],
"title": "Product Title",
"handle": "product-handle",
"locale": "en",
"source": "MANUAL",
"status": "ACTIVE",
"options": "",
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"taxable": false,
"isVisible": true,
"productTax": 0,
"translations": [],
"collectionIds": [],
"descriptionHtml": "",
"integrationProvider": {
"icon": {
"src": "",
"altText": ""
},
"name": "MANUAL",
"provider": "MANUAL",
"websiteLink": ""
}
},
"title": "Product Title",
"fulfilledItems": 0,
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"quantity": 1,
"discount": null,
"discounts": [],
"type": "SIMPLE",
"variantId": "cmdeh9e2h00d901xo8oqu5a2x",
"variantSnapshot": {
"id": "cmdeh9e2h00d901xo8oqu5a2x",
"sku": "product-sku",
"type": "variant",
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"quantity": 10,
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"externalId": "",
"trackQuantity": true,
"compareAtPrice": {
"amount": 3150,
"currencyCode": "EGP"
},
"selectedOptions": [],
"selectedOptionsIds": [],
"selectedOptionValuesIds": []
},
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"options": [],
"sourceType": "MANUAL",
"productTax": null,
"taxable": false,
"quantityChanged": false,
"categories": [],
"manualDiscounts": []
}
],
"externalActionMessage": [],
"paymentMethod": "CASH_ON_DELIVERY",
"paymentStatus": "PENDING",
"paidAmount": {
"amount": 0,
"currencyCode": "EGP"
},
"shippingStatus": "PENDING",
"taxSnapshot": null,
"receipt": {
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"discount": {
"amount": 0,
"currencyCode": "EGP"
},
"tax": {
"amount": 0,
"currencyCode": "EGP"
},
"shipping": {
"amount": 200,
"currencyCode": "EGP"
},
"total": {
"amount": 3200,
"currencyCode": "EGP"
},
"automaticDiscount": {
"amount": 0,
"currencyCode": "EGP"
}
},
"discounts": [],
"locale": "en",
"refCode": null,
"paymentIntentId": "cmdlpac07000d016o65sn713a",
"wuiltShipmentProvider": "Bosta",
"packagingDetails": {
"extraWeight": 0,
"extraVolumetricWeight": 0,
"weight": 0,
"volumetricWeight": 0.0003333333333333333,
"shippingCostDetails": {
"baseCost": 75,
"returnCost": 88,
"baseWeightLimit": 20,
"extraWeightCost": 0,
"extraWeightStep": 0,
"returnToOriginCost": 68
},
"flyer": "X_LARGE"
},
"tags": [],
"openPackageOption": null,
"manualDiscounts": [],
"orderSerial": "418",
"createdAt": "2025-07-27T13:14:03.056Z",
"updatedAt": "2025-07-27T13:14:03.056Z"
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-16T14:22:00Z",
"storeId": "store_abc123def456"
}
}

ORDER_CANCELED​

Triggered when an order is canceled.

Payload Type: OrderDocument

View ORDER_CANCELED payload example
{
"event": "ORDER_CANCELED",
"payload": {
"order": {
"_id": "cmdlpac7n000201pm3dgifkqu",
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"cartId": "d3f61199-b262-4deb-a42d-31a5b93952b0",
"status": "SUCCESSFUL",
"errors": [],
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"totalPrice": {
"amount": 3200,
"currencyCode": "EGP"
},
"shippingRateCost": {
"amount": 75,
"currencyCode": "EGP"
},
"fulfillmentStatus": "UNFULFILLED",
"notes": "",
"shippingRateId": "clzvqvezy0004017i4vwe4667",
"shippingRateName": "Bosta",
"promoCodeSnapshot": null,
"isArchived": false,
"isCanceled": false,
"isViewed": false,
"customerId": "cm4qwyzfv000g018y6mv39bnd",
"itemsCount": 1,
"fulfilledItems": 0,
"shippingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"billingAddress": {
"addressLine1": "11th Districtttt",
"addressLine2": "12th apartment",
"phone": "+201111111111",
"secondPhone": null,
"postalCode": "001",
"notes": "",
"countryCode2": "EG",
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City",
"area": {
"countryId": "clzy5vtku0000kn9kagau94vi",
"stateId": "clzy5vtl6004rkn9k8dx8gmml",
"cityId": "clzy5vtl7004ukn9k1my75jhi"
},
"areaSnapshot": {
"countryName": "Egypt",
"stateName": "Alexandria",
"cityName": "Borg Al Arab City"
}
},
"promoCode": null,
"customer": {
"name": "John Doe",
"email": "john.doe@gmail.com",
"phone": "+201111111111",
"isSubscribedToNewsLetter": true
},
"storeData": {
"name": "John Doe",
"logo": null,
"email": "john.doe@gmail.com",
"phone": "115050"
},
"items": [
{
"_id": "08672157-9dc9-443d-a74c-cb55312162d4",
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"productSnapshot": {
"id": "cmdeh9e2h00d801xoco4ngtt5",
"type": "SIMPLE",
"media": ["cmdeh6b4c004201ceeufm8fqu", "cmdeh6b4c004301ceefuk40e4"],
"title": "Product Title",
"handle": "product-handle",
"locale": "en",
"source": "MANUAL",
"status": "ACTIVE",
"options": "",
"storeId": "cm4qwsv0e004s01k77o2f1f5e",
"taxable": false,
"isVisible": true,
"productTax": 0,
"translations": [],
"collectionIds": [],
"descriptionHtml": "",
"integrationProvider": {
"icon": {
"src": "",
"altText": ""
},
"name": "MANUAL",
"provider": "MANUAL",
"websiteLink": ""
}
},
"title": "Product Title",
"fulfilledItems": 0,
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"quantity": 1,
"discount": null,
"discounts": [],
"type": "SIMPLE",
"variantId": "cmdeh9e2h00d901xo8oqu5a2x",
"variantSnapshot": {
"id": "cmdeh9e2h00d901xo8oqu5a2x",
"sku": "product-sku",
"type": "variant",
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"quantity": 10,
"productId": "cmdeh9e2h00d801xoco4ngtt5",
"externalId": "",
"trackQuantity": true,
"compareAtPrice": {
"amount": 3150,
"currencyCode": "EGP"
},
"selectedOptions": [],
"selectedOptionsIds": [],
"selectedOptionValuesIds": []
},
"price": {
"amount": 3000,
"currencyCode": "EGP"
},
"options": [],
"sourceType": "MANUAL",
"productTax": null,
"taxable": false,
"quantityChanged": false,
"categories": [],
"manualDiscounts": []
}
],
"externalActionMessage": [],
"paymentMethod": "CASH_ON_DELIVERY",
"paymentStatus": "PENDING",
"paidAmount": {
"amount": 0,
"currencyCode": "EGP"
},
"shippingStatus": "PENDING",
"taxSnapshot": null,
"receipt": {
"subtotal": {
"amount": 3000,
"currencyCode": "EGP"
},
"discount": {
"amount": 0,
"currencyCode": "EGP"
},
"tax": {
"amount": 0,
"currencyCode": "EGP"
},
"shipping": {
"amount": 200,
"currencyCode": "EGP"
},
"total": {
"amount": 3200,
"currencyCode": "EGP"
},
"automaticDiscount": {
"amount": 0,
"currencyCode": "EGP"
}
},
"discounts": [],
"locale": "en",
"refCode": null,
"paymentIntentId": "cmdlpac07000d016o65sn713a",
"wuiltShipmentProvider": "Bosta",
"packagingDetails": {
"extraWeight": 0,
"extraVolumetricWeight": 0,
"weight": 0,
"volumetricWeight": 0.0003333333333333333,
"shippingCostDetails": {
"baseCost": 75,
"returnCost": 88,
"baseWeightLimit": 20,
"extraWeightCost": 0,
"extraWeightStep": 0,
"returnToOriginCost": 68
},
"flyer": "X_LARGE"
},
"tags": [],
"openPackageOption": null,
"manualDiscounts": [],
"orderSerial": "418",
"createdAt": "2025-07-27T13:14:03.056Z",
"updatedAt": "2025-07-27T13:14:03.056Z"
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-17T09:15:00Z",
"storeId": "store_abc123def456"
}
}

Product Events​

PRODUCT_CREATED​

Triggered when a new product is added to the store.

Note: Bulk import will not trigger this event.

Payload Type: ProductInfo

View PRODUCT_CREATED payload example
{
"event": "PRODUCT_CREATED",
"payload": {
"product": {
"_id": "cmdzpoejh1mee01m2fctjd4dj",
"type": "SIMPLE",
"storeId": "cmdnsqc2a067k01kif865gtcy",
"title": "Product Title",
"descriptionHtml": "<p>Product Description</p>",
"options": [],
"media": [],
"handle": "product-handle",
"isArchived": false,
"isVisible": true,
"isDeleted": false,
"seo": {
"title": "Product Title",
"description": "Product Description"
},
"locale": "en",
"shortDescription": "Product Description",
"collectionIds": [
"cmdritvm3148r01m282gg74ek",
"cmdr85b06160e01r5d8t24qwn"
],
"status": "ACTIVE",
"source": "MANUAL",
"attributes": [
{
"attributeId": "cmdo7jnx30z4z01m2bk5ddue6",
"valuesIds": ["cmdo7k1sg0z5001m2cu3ffo1k"],
"_id": "689313698435803e6b6f98d5"
},
{
"attributeId": "cmdo7la6h17gc01q7d66shgu8",
"valuesIds": ["cmdzpcttz1j5m01r5eqp11qdh"],
"_id": "689313698435803e6b6f98d6"
},
{
"attributeId": "cmdtyrxtz1fy501q76v7m8gic",
"valuesIds": ["cmdzpdfcn1me601m252059th1"],
"_id": "689313698435803e6b6f98d7"
},
{
"attributeId": "cmdtxb62800i301no82jg9mj2",
"valuesIds": [
"cmdy81c601gr801r5fq3b4oh6",
"cmdzpefr71me701m26jyq74ra"
],
"_id": "689313698435803e6b6f98d8"
}
],
"productVariants": [],
"productTax": null,
"taxable": false,
"createdAt": "2025-08-06T08:33:45.641Z",
"updatedAt": "2025-08-06T08:33:45.641Z",
"variants": [
{
"_id": "cmdzpoek01mef01m28ohd7kzk",
"type": "variant",
"productId": "cmdzpoejh1mee01m2fctjd4dj",
"storeId": "cmdn0qc2a067k01kif865gtcy",
"sku": "",
"trackQuantity": true,
"quantity": 0,
"price": {
"amount": 220,
"currencyCode": "EGP"
},
"compareAtPrice": {
"amount": 250,
"currencyCode": "EGP"
},
"selectedOptionsIds": [],
"selectedOptionValuesIds": [],
"isDeleted": false,
"cost": null,
"externalId": "",
"cartLimitsEnabled": false,
"minPerCart": 1,
"maxPerCart": 100,
"packageDetails": {
"weight": null,
"dimensions": {
"length": null,
"width": null,
"height": null
}
},
"reservations": [],
"createdAt": "2025-08-06T08:33:45.651Z",
"updatedAt": "2025-08-06T08:33:45.651Z"
}
],
"isTaxable": false
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-15T08:00:00Z",
"storeId": "store_abc123def456"
}
}

PRODUCT_UPDATED​

Triggered when product details are modified.

Payload Type: ProductInfo

View PRODUCT_UPDATED payload example
{
"event": "PRODUCT_UPDATED",
"payload": {
"product": {
"_id": "cmdzpoejh1mee01m2fctjd4dj",
"type": "SIMPLE",
"storeId": "cmdn0qc2s067k01kif865gtcy",
"title": "Product Title",
"descriptionHtml": "<p>Product Description</p>",
"options": [],
"media": [],
"handle": "product-handle",
"isArchived": false,
"isVisible": true,
"isDeleted": false,
"seo": {
"title": "Product Title",
"description": "Product Description"
},
"locale": "en",
"shortDescription": "Product Description",
"collectionIds": [
"cmdritvm3148r01m282gg74ek",
"cmdr85b06160e01r5d8t24qwn"
],
"status": "ACTIVE",
"source": "MANUAL",
"attributes": [
{
"attributeId": "cmdo7jnx30z4z01m2bk5ddue6",
"valuesIds": ["cmdo7k1sg0z5001m2cu3ffo1k"],
"_id": "689313698435803e6b6f98d5"
},
{
"attributeId": "cmdo7la6h17gc01q7d66shgu8",
"valuesIds": ["cmdzpcttz1j5m01r5eqp11qdh"],
"_id": "689313698435803e6b6f98d6"
},
{
"attributeId": "cmdtyrxtz1fy501q76v7m8gic",
"valuesIds": ["cmdzpdfcn1me601m252059th1"],
"_id": "689313698435803e6b6f98d7"
},
{
"attributeId": "cmdtxb62800i301no82jg9mj2",
"valuesIds": [
"cmdy81c601gr801r5fq3b4oh6",
"cmdzpefr71me701m26jyq74ra"
],
"_id": "689313698435803e6b6f98d8"
}
],
"productVariants": [],
"productTax": null,
"taxable": false,
"createdAt": "2025-08-06T08:33:45.641Z",
"updatedAt": "2025-08-06T08:33:45.641Z",
"variants": [
{
"_id": "cmdzpoek01mef01m28ohd7kzk",
"type": "variant",
"productId": "cmdzpoejh1mee01m2fctjd4dj",
"storeId": "cmdn0qc2a067k01kif865gtcy",
"sku": "",
"trackQuantity": true,
"quantity": 0,
"price": {
"amount": 220,
"currencyCode": "EGP"
},
"compareAtPrice": {
"amount": 250,
"currencyCode": "EGP"
},
"selectedOptionsIds": [],
"selectedOptionValuesIds": [],
"isDeleted": false,
"cost": null,
"externalId": "",
"cartLimitsEnabled": false,
"minPerCart": 1,
"maxPerCart": 100,
"packageDetails": {
"weight": null,
"dimensions": {
"length": null,
"width": null,
"height": null
}
},
"reservations": [],
"createdAt": "2025-08-06T08:33:45.651Z",
"updatedAt": "2025-08-06T08:33:45.651Z"
}
],
"isTaxable": false
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-16T11:30:00Z",
"storeId": "store_abc123def456"
}
}

PRODUCT_DELETED​

Triggered when a product is deleted from the store.

Payload Type: EntityDeletedEventPayload

View PRODUCT_DELETED payload example
{
"event": "PRODUCT_DELETED",
"payload": {
"id": "689313698435803e6b6f98d8",
"deletedAt": "2024-01-17T16:45:00Z"
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-17T16:45:00Z",
"storeId": "store_abc123def456"
}
}

SHIPMENT_UPDATED​

Triggered when a shipment status changes during the fulfillment process. This includes events like pickup, delivery attempts, successful delivery, and returns.

Payload Type: { events: string[], order: OrderStatusEvent }

Possible Event Types:

  • OrderShipmentPickedUp - Package has been picked up by carrier
  • OrderShipmentIsOnTheWay - Package is in transit
  • OrderShipmentDelivered - Package successfully delivered
  • OrderShipmentReturnedToSeller - Package returned to seller
  • OrderShipmentActionRequired - Action required for shipment processing
View SHIPMENT_UPDATED payload example
{
"event": "SHIPMENT_UPDATED",
"payload": {
"events": ["OrderShipmentDelivered"],
"order": {
"orderId": "cmdlpac7n000201pm3dgifkqu",
"airwayBillId": "AWB123456789",
"companyName": "Bosta",
"cost": 75,
"location": {
"country": "Egypt",
"governorate": "Alexandria",
"city": "Borg Al Arab City",
"fullAddress": "11th Districtttt, 12th apartment, Borg Al Arab City, Alexandria, Egypt"
},
"storeId": "cm4qwjv0e004s01k77o2f1f5e",
"trackingNumber": "TRACK123456",
"orderSerial": 418
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-20T14:30:00Z",
"storeId": "store_abc123def456"
}
}

Customer Events​

CUSTOMER_CREATED​

Triggered when a new customer account is created.

Payload Type: { customer: CustomerDocument }

View CUSTOMER_CREATED payload example
{
"event": "CUSTOMER_CREATED",
"payload": {
"customer": {
"_id": "cmdyk6iy44alh017007yhblv4",
"name": "John Doe",
"email": "john.doe@gmail.com",
"phone": "+201111111111",
"storeId": "clvbieoia04o601j8886abo1h",
"isGuest": true,
"preferredLocale": "en",
"addresses": [
{
"_id": "cmdyk6iy44alg01705vlvef5y",
"area": {
"stateId": "cl0pf3jxs02jtlwm1hs2u6g0z",
"countryId": "cl0pf3jxc00m1lwm1hw3u66ri"
},
"notes": "test note",
"secondPhone": "+201111111111",
"addressLine1": "123 Main St",
"addressLine2": "Apt 4B",
"isDefault": true
}
]
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-15T12:00:00Z",
"storeId": "cmdyk6iy44alh017007yhblv4"
}
}

CUSTOMER_UPDATED​

Triggered when customer information is modified.

Payload Type: { customer: CustomerDocument }

View CUSTOMER_UPDATED payload example
{
"event": "CUSTOMER_UPDATED",
"payload": {
"customer": {
"_id": "cmdyk6iy44alh017007yhblv4",
"name": "John Doe",
"email": "john.doe@gmail.com",
"phone": "+201111111111",
"storeId": "clvbieoia04o601j8886abo1h",
"isGuest": true,
"preferredLocale": "en",
"addresses": [
{
"_id": "cmdyk6iy44alg01705vlvef5y",
"area": {
"stateId": "cl0pf3jxs02jtlwm1hs2u6g0z",
"countryId": "cl0pf3jxc00m1lwm1hw3u66ri"
},
"notes": "test note",
"secondPhone": "+201111111111",
"addressLine1": "123 Main St",
"addressLine2": "Apt 4B",
"isDefault": true
}
]
}
},
"metadata": {
"apiVersion": "2024-01",
"timestamp": "2024-01-20T09:30:00Z",
"storeId": "store_abc123def456"
}
}

Cart & Checkout Events​

CART_ITEM_ADDED​

Triggered when a customer adds a simple or custom product item to their cart.

Payload Type: { storeId: string, item: CartItem }

FieldDescription
storeIdThe store where the item was added
item.idUnique item ID
item.quantityQuantity added
item.productIdProduct identifier
item.variantIdVariant identifier
item.pricePrice object with amount and currencyCode

Delivery: Real-time. Fires on every add-to-cart action (simple and custom items). If a customer adds the same product again (increasing quantity), a new event is fired.

Use cases:

  • Real-time inventory monitoring for popular items
  • Trigger upsell/cross-sell logic in external recommendation engines
  • Track add-to-cart events in external analytics platforms
View CART_ITEM_ADDED payload example
{
"event": "CART_ITEM_ADDED",
"payload": {
"storeId": "store-uuid",
"item": {
"id": "item-uuid",
"quantity": 1,
"productId": "product-uuid",
"variantId": "variant-uuid",
"price": {
"amount": 150,
"currencyCode": "EGP"
}
}
},
"metaData": {
"webhookId": "webhook-uuid",
"storeId": "store-uuid",
"timestamp": "2026-06-13T14:02:00.000Z",
"apiVersion": "V1"
}
}

CHECKOUT_INITIATED​

Triggered when a customer navigates to the checkout page.

Payload Type: { storeId: string, cart: CartDocument }

FieldDescription
storeIdThe store where checkout was initiated
cart.idCart identifier
cart.statusCart status (ACTIVE)
cart.cartSimpleItemsArray of simple product items in the cart
cart.cartCustomItemsArray of custom product items in the cart
cart.contactInfoCustomer contact information (email, name, phone)
cart.storeStore information
cart.receiptCart totals (subtotal, total, shipping)

Delivery: Real-time. Fires once when the customer navigates to checkout.

Use cases:

  • Track checkout funnel conversion in external analytics
  • Trigger real-time support chat for high-value carts
  • Sync checkout intent with CRM tools
View CHECKOUT_INITIATED payload example
{
"event": "CHECKOUT_INITIATED",
"payload": {
"storeId": "store-uuid",
"cart": {
"id": "uuid",
"status": "ACTIVE",
"cartSimpleItems": [
{
"id": "uuid",
"quantity": 2,
"productId": "uuid",
"variantId": "uuid",
"price": { "amount": 150, "currencyCode": "EGP" }
}
],
"cartCustomItems": [],
"contactInfo": {
"email": "customer@example.com",
"firstName": "Sara",
"lastName": "Ali"
},
"store": {
"id": "store-uuid",
"name": "My Store",
"currencyCode": "EGP"
},
"receipt": {
"subtotal": { "amount": 300, "currencyCode": "EGP" },
"total": { "amount": 350, "currencyCode": "EGP" }
},
"createdAt": "2026-06-13T14:00:00.000Z",
"updatedAt": "2026-06-13T14:05:00.000Z"
}
},
"metaData": {
"webhookId": "webhook-uuid",
"storeId": "store-uuid",
"timestamp": "2026-06-13T14:05:01.000Z",
"apiVersion": "V1"
}
}

CART_ABANDONED​

Triggered when a cart with contact information has been inactive for more than 60 minutes.

Payload Type: { cart: CartDocument, storeId: string, abandonedAt: string }

FieldDescription
cart.idCart identifier
cart.statusCart status (ABANDONED)
cart.cartSimpleItemsArray of simple product items in the cart
cart.cartCustomItemsArray of custom product items in the cart
cart.contactInfoCustomer contact information (email, name, phone)
cart.storeStore information
cart.receiptCart totals (subtotal, total, shipping)
storeIdThe store the cart belongs to
abandonedAtISO timestamp of when the cart was marked abandoned

Delivery: Scheduled (cron). Checked every few minutes; fires after 60 minutes of inactivity. The cart must have contact info (email or phone) — anonymous carts are never marked as abandoned.

Use cases:

  • Send recovery emails to customers who abandoned carts
  • Trigger retargeting ads or SMS reminders
  • Track abandonment rates in external analytics tools
View CART_ABANDONED payload example
{
"event": "CART_ABANDONED",
"payload": {
"cart": {
"id": "uuid",
"status": "ABANDONED",
"cartSimpleItems": [
{
"id": "uuid",
"quantity": 1,
"productId": "uuid",
"variantId": "uuid",
"price": { "amount": 200, "currencyCode": "EGP" }
}
],
"cartCustomItems": [],
"contactInfo": {
"email": "customer@example.com",
"firstName": "Ahmed",
"lastName": "Mohamed",
"phone": "+201234567890"
},
"store": {
"id": "store-uuid",
"name": "My Store",
"currencyCode": "EGP"
},
"receipt": {
"subtotal": { "amount": 200, "currencyCode": "EGP" },
"total": { "amount": 250, "currencyCode": "EGP" },
"shippingCost": { "amount": 50, "currencyCode": "EGP" }
},
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:30:00.000Z"
},
"storeId": "store-uuid",
"abandonedAt": "2026-06-10T11:30:00.000Z"
},
"metaData": {
"webhookId": "webhook-uuid",
"storeId": "store-uuid",
"timestamp": "2026-06-10T11:30:05.000Z",
"apiVersion": "V1"
}
}
Event Timing & Behavior
EventDeliveryNotes
CART_ITEM_ADDEDReal-timeFires on every add-to-cart action (simple and custom items)
CHECKOUT_INITIATEDReal-timeFires once when customer navigates to checkout
CART_ABANDONEDScheduled (cron)Checked every few minutes; fires after 60 min of inactivity. Cart must have contact info (email/phone).

Important: CART_ABANDONED does not fire in real-time. It runs on a periodic schedule and marks all qualifying carts as abandoned in batch. The abandonedAt timestamp indicates when the batch ran. A cart is eligible for abandonment only if it has contactInfo (email or phone). Anonymous carts without contact info are never marked as abandoned.

Best Practices​

1. Handle Webhooks Idempotently​

Wuilt may send the same webhook multiple times. Always handle webhooks idempotently:

const processedWebhooks = new Set();

app.post("/webhooks/wuilt", (req, res) => {
const { event, payload, metadata } = req.body;
const webhookId = `${event}-${payload.id}-${metadata.timestamp}`;

// Check if we've already processed this webhook
if (processedWebhooks.has(webhookId)) {
console.log("Webhook already processed:", webhookId);
return res.status(200).send("OK");
}

// Process the webhook
processWebhook(event, payload, metadata);

// Mark as processed
processedWebhooks.add(webhookId);

res.status(200).send("OK");
});

2. Respond Quickly​

Respond to webhooks within 10 seconds to avoid timeouts:

app.post("/webhooks/wuilt", (req, res) => {
// Respond immediately
res.status(200).send("OK");

// Process webhook asynchronously
setImmediate(() => {
processWebhookAsync(req.body);
});
});

3. Implement Retry Logic​

Handle webhook failures gracefully with exponential backoff:

async function processWebhookWithRetry(webhookData, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await processWebhook(webhookData);
return; // Success
} catch (error) {
console.error(`Webhook processing failed (attempt ${attempt}):`, error);

if (attempt === maxRetries) {
// Log to dead letter queue or alert system
console.error("Max retries exceeded for webhook:", webhookData);
return;
}

// Exponential backoff
const delay = Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}

4. Log Webhook Events​

Keep detailed logs for debugging and monitoring:

app.post("/webhooks/wuilt", (req, res) => {
const { event, payload, metadata } = req.body;

console.log("Webhook received:", {
event,
resourceId: payload.id,
storeId: metadata.storeId,
timestamp: metadata.timestamp,
apiVersion: metadata.apiVersion,
});

try {
processWebhook(event, payload, metadata);
console.log("Webhook processed successfully:", event, payload.id);
} catch (error) {
console.error("Webhook processing failed:", {
event,
resourceId: payload.id,
error: error.message,
stack: error.stack,
});
}

res.status(200).send("OK");
});

Testing Webhooks​

Option 1: Use Webhook.site (Quick Testing - No Setup Required)​

For quick testing without setting up a server, use Webhook.site:

  1. Visit webhook.site - You'll get a unique URL instantly
  2. Copy your unique URL (e.g., https://webhook.site/#!/abc123-def456-...)
  3. Register the URL in Wuilt Dashboard - Use the unique URL as your webhook endpoint
  4. Trigger events in your Wuilt store - Place an order, update a product, etc.
  5. View webhook payloads in real-time - All incoming webhooks appear instantly on webhook.site

Benefits:

  • ✅ No installation or setup required
  • ✅ Instant webhook URL generation
  • ✅ Real-time payload inspection
  • ✅ Request history and replay
  • ✅ Custom response configuration
  • ✅ Works from anywhere (no local server needed)

Perfect for:

  • Quick webhook testing and debugging
  • Inspecting webhook payload structure
  • Verifying webhook delivery
  • Testing without writing code

Option 2: Use ngrok for Local Development​

For testing with your own webhook handler code, expose your local endpoint:

# Install ngrok
npm install -g ngrok

# Expose your local server
ngrok http 3000

# Use the generated URL for webhook registration
# https://abc123.ngrok.io/webhooks/wuilt

Benefits:

  • ✅ Test with your actual webhook handler code
  • ✅ Debug your application logic
  • ✅ Develop and test simultaneously

3. Test with Sample Payloads​

Create test functions to simulate webhook events:

// Test webhook handler with sample data
function testOrderPlacedWebhook() {
const samplePayload = {
event: "ORDER_PLACED",
payload: {
id: "test_order_123",
orderNumber: "TEST-001",
status: "pending",
// ... other order fields
},
metadata: {
apiVersion: "2024-01",
timestamp: new Date().toISOString(),
storeId: "test_store_123",
},
};

// Simulate webhook call
handleWebhook(samplePayload);
}

Troubleshooting​

Common Issues​

  1. Webhook not receiving events: Check that your endpoint is publicly accessible and returns 200 OK
  2. Duplicate events: Implement idempotency checks using event ID and timestamp
  3. Timeout errors: Ensure your webhook responds within 10 seconds

Webhook Logs​

Monitor your webhook delivery status in the Wuilt dashboard to identify and resolve issues quickly.


For more information about the Wuilt Commerce API, visit our API Documentation.