Webhook Events Reference
Complete reference of all webhook events BareCommerce sends to your endpoints.
Event Format
All webhook events follow this structure:
{
"type": "order.created",
"id": "evt_abc123",
"timestamp": "2024-01-15T10:30:00Z",
"storeId": "store_xyz",
"data": {
"id": "resource_id",
...resource fields...
}
}| Field | Type | Description |
|---|---|---|
type | string | Event type (e.g., "order.created") |
id | string | Unique event ID - use for deduplication |
timestamp | datetime | When event occurred (ISO 8601) |
storeId | string | Store that triggered event |
data | object | The actual resource (order, product, etc.) |
Order Events
order.created
Fired when an order is created from a payment webhook.
{
"type": "order.created",
"id": "evt_123",
"timestamp": "2024-01-15T10:30:00Z",
"storeId": "store_123",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"customerId": "cust_xyz",
"total": "99.99",
"status": "paid",
"paymentStatus": "succeeded",
"paymentProvider": "stripe",
"items": [
{
"productId": "prod_1",
"titleSnapshot": "Product Title",
"quantity": 1,
"unitPrice": "99.99"
}
],
"shippingAddress": {...},
"createdAt": "2024-01-15T10:30:00Z"
}
}When: Immediately after payment succeeds (via webhook)
Use case: Send order confirmation email, notify warehouse, update inventory
order.updated
Fired when order data changes.
{
"type": "order.updated",
"id": "evt_456",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"status": "fulfilled",
"fulfilledAt": "2024-01-15T14:00:00Z"
}
}When: Order status or data changes
Use case: Update order tracking in your system
order.paid
Fired when payment is confirmed (may be same as order.created for instant payments).
{
"type": "order.paid",
"id": "evt_789",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"paymentStatus": "succeeded",
"paidAt": "2024-01-15T10:30:00Z"
}
}When: Payment confirmed
Use case: Trigger order fulfillment pipeline
order.fulfilled
Fired when order is shipped/completed.
{
"type": "order.fulfilled",
"id": "evt_101",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"status": "fulfilled",
"fulfilledAt": "2024-01-15T14:00:00Z"
}
}When: Order marked as fulfilled
Use case: Send shipping confirmation, generate tracking link
order.cancelled
Fired when order is cancelled.
{
"type": "order.cancelled",
"id": "evt_202",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"status": "cancelled",
"cancelledAt": "2024-01-15T11:00:00Z"
}
}When: Order cancelled
Use case: Send cancellation email, restore inventory
order.refunded
Fired when order is refunded.
{
"type": "order.refunded",
"id": "evt_303",
"data": {
"id": "order_abc",
"orderNumber": "ORD-000001",
"paymentStatus": "refunded",
"amount": "99.99",
"reason": "Customer requested"
}
}When: Payment is refunded
Use case: Send refund confirmation, update financial records
Product Events
product.created
Fired when a product is created.
{
"type": "product.created",
"id": "evt_404",
"data": {
"id": "prod_123",
"storeId": "store_xyz",
"title": "New Product",
"slug": "new-product",
"price": "29.99",
"status": "published",
"createdAt": "2024-01-15T10:00:00Z"
}
}When: Product created
Use case: Sync to external catalog, index for search
product.updated
Fired when product is updated.
{
"type": "product.updated",
"id": "evt_505",
"data": {
"id": "prod_123",
"title": "Updated Product",
"price": "34.99",
"stock": 50,
"updatedAt": "2024-01-15T11:00:00Z"
}
}When: Product data changes
Use case: Update external systems, clear cache
product.deleted
Fired when product is deleted.
{
"type": "product.deleted",
"id": "evt_606",
"data": {
"id": "prod_123",
"title": "Deleted Product"
}
}When: Product deleted (soft-delete)
Use case: Remove from external catalog
Customer Events
customer.created
Fired when a customer is created.
{
"type": "customer.created",
"id": "evt_707",
"data": {
"id": "cust_123",
"email": "customer@example.com",
"name": "John Doe",
"phone": "+1-555-0123",
"createdAt": "2024-01-15T10:00:00Z"
}
}When: Customer created
Use case: Add to email list, create account in external system
customer.updated
Fired when customer is updated.
{
"type": "customer.updated",
"id": "evt_808",
"data": {
"id": "cust_123",
"email": "newemail@example.com",
"updatedAt": "2024-01-15T11:00:00Z"
}
}When: Customer data changes
Use case: Update external CRM, sync email changes
customer.deleted
Fired when customer is deleted.
{
"type": "customer.deleted",
"id": "evt_909",
"data": {
"id": "cust_123",
"email": "customer@example.com"
}
}When: Customer deleted
Use case: Cleanup in external systems
Category Events
category.created
{
"type": "category.created",
"id": "evt_010",
"data": {
"id": "cat_123",
"name": "Summer Collection",
"slug": "summer-collection"
}
}category.updated
{
"type": "category.updated",
"id": "evt_011",
"data": {
"id": "cat_123",
"name": "Updated Category Name"
}
}category.deleted
{
"type": "category.deleted",
"id": "evt_012",
"data": {
"id": "cat_123",
"name": "Summer Collection"
}
}Page Events
page.created, page.updated, page.deleted
Similar structure to products and categories.
{
"type": "page.created",
"id": "evt_013",
"data": {
"id": "page_123",
"title": "About Us",
"slug": "about-us",
"body": "Page content here..."
}
}Media Events
media.created, media.updated, media.deleted
{
"type": "media.created",
"id": "evt_014",
"data": {
"id": "media_123",
"url": "https://cdn.example.com/image.jpg",
"mimeType": "image/jpeg",
"width": 1200,
"height": 800,
"fileSize": 256000
}
}Event Processing Examples
Send Order Confirmation Email
if (event.type === 'order.created') {
const { data: order } = event;
await sendEmail({
to: order.customerId,
subject: `Order ${order.orderNumber} Confirmation`,
template: 'order-confirmation',
data: {
orderNumber: order.orderNumber,
total: order.total,
items: order.items
}
});
}Sync Products to Search Index
if (event.type === 'product.created' || event.type === 'product.updated') {
const { data: product } = event;
await searchIndex.index({
id: product.id,
title: product.title,
description: product.description,
price: product.price
});
}Update Inventory on Order
if (event.type === 'order.created') {
const { data: order } = event;
for (const item of order.items) {
await inventory.decreaseStock(
item.productId,
item.quantity
);
}
}Sync Customer to CRM
if (event.type === 'customer.created') {
const { data: customer } = event;
await crm.createContact({
email: customer.email,
name: customer.name,
phone: customer.phone,
source: 'barecommerce'
});
}Webhook Retry Logic
If your endpoint returns an error or doesn't respond with 200, BareCommerce retries:
| Attempt | Delay |
|---|---|
| 1 | Immediately |
| 2 | 5 seconds |
| 3 | 25 seconds |
| 4 | 2 minutes |
| 5 | 10 minutes |
Always return 200 OK to confirm delivery, even if processing fails (process async).
Best Practices
✅ DO:
- Verify webhook signatures
- Return 200 immediately
- Process asynchronously
- Implement idempotency (handle duplicates)
- Log all webhook events
- Handle missing fields gracefully
❌ DON'T:
- Keep BareCommerce waiting (return 200 immediately)
- Process webhooks synchronously
- Trust unsigned webhooks
- Assume field presence
- Send webhooks to non-HTTPS endpoints
Deduplication
Use the id field to detect duplicate webhooks:
async function processWebhook(event) {
// Check if already processed
const existing = await db.webhookEvents.findOne({
eventId: event.id
});
if (existing) {
return; // Already processed
}
// Process...
// Mark as processed
await db.webhookEvents.create({
eventId: event.id,
type: event.type,
processedAt: new Date()
});
}