Skip to main content

Order Webhook Events

Receive notifications for order and booking lifecycle events.

Available Events

EventTrigger
order.createdNew order/booking created
order.updatedOrder details updated
order.confirmedOrder confirmed
order.completedOrder/service completed
order.cancelledOrder cancelled

order.created

Triggered when a new order or booking is created.

Payload

{
  "id": "evt_abc123",
  "type": "order.created",
  "created": "2024-01-20T14:30:00Z",
  "data": {
    "id": "ord_xyz789",
    "type": "booking",
    "status": "pending",
    "customerId": "cust_123",
    "customerEmail": "[email protected]",
    "customerName": "John Doe",
    "locationId": "loc_456",
    "locationName": "Downtown Branch",
    "scheduledAt": "2024-01-25T10:00:00Z",
    "duration": 60,
    "services": [
      {
        "id": "svc_789",
        "name": "Consultation",
        "price": 75.00,
        "quantity": 1
      }
    ],
    "subtotal": 75.00,
    "tax": 6.56,
    "total": 81.56,
    "paymentStatus": "pending",
    "source": "booking_portal",
    "createdAt": "2024-01-20T14:30:00Z"
  }
}

Data Fields

id
string
Order ID
type
string
Order type: booking, sale, enquiry
status
string
Current status
customerId
string
Customer ID
locationId
string
Location ID
scheduledAt
string
Scheduled date/time (ISO 8601)
services
array
Services/products in order
total
number
Total order amount
source
string
Where order originated: web_app, api, booking_portal, pos

Example Handler

case 'order.created':
  const order = event.data;
  
  // Notify staff
  await slack.send(`New booking: ${order.customerName} at ${order.scheduledAt}`);
  
  // Add to calendar
  await calendar.createEvent({
    title: `${order.services[0].name} - ${order.customerName}`,
    start: order.scheduledAt,
    duration: order.duration
  });
  break;

order.confirmed

Triggered when an order is confirmed.

Payload

{
  "id": "evt_def456",
  "type": "order.confirmed",
  "created": "2024-01-20T15:00:00Z",
  "data": {
    "id": "ord_xyz789",
    "type": "booking",
    "status": "confirmed",
    "customerId": "cust_123",
    "scheduledAt": "2024-01-25T10:00:00Z",
    "confirmedAt": "2024-01-20T15:00:00Z",
    "confirmedBy": "staff_abc"
  },
  "previousStatus": "pending"
}

Example Handler

case 'order.confirmed':
  // Send SMS reminder
  await sms.send(order.customerPhone, 
    `Your appointment on ${formatDate(order.scheduledAt)} is confirmed!`
  );
  
  // Update calendar
  await calendar.confirmEvent(order.id);
  break;

order.completed

Triggered when order/service is completed.

Payload

{
  "id": "evt_ghi789",
  "type": "order.completed",
  "created": "2024-01-25T11:00:00Z",
  "data": {
    "id": "ord_xyz789",
    "type": "booking",
    "status": "completed",
    "customerId": "cust_123",
    "total": 81.56,
    "paymentStatus": "paid",
    "completedAt": "2024-01-25T11:00:00Z",
    "loyaltyPointsEarned": 82
  }
}

Example Handler

case 'order.completed':
  // Send follow-up email
  await sendFollowUpEmail(order.customerEmail, {
    serviceName: order.services[0].name,
    reviewLink: `https://example.com/review/${order.id}`
  });
  
  // Update analytics
  analytics.track('Order Completed', {
    orderId: order.id,
    revenue: order.total,
    customerId: order.customerId
  });
  break;

order.cancelled

Triggered when order is cancelled.

Payload

{
  "id": "evt_jkl012",
  "type": "order.cancelled",
  "created": "2024-01-22T09:00:00Z",
  "data": {
    "id": "ord_xyz789",
    "type": "booking",
    "status": "cancelled",
    "customerId": "cust_123",
    "cancelledAt": "2024-01-22T09:00:00Z",
    "cancelledBy": "customer",
    "cancellationReason": "Schedule conflict",
    "refundAmount": 81.56,
    "refundStatus": "processed"
  }
}

Additional Fields

cancelledBy
string
Who cancelled: customer, staff, system
cancellationReason
string
Reason for cancellation
refundAmount
number
Amount refunded

Example Handler

case 'order.cancelled':
  // Free up the time slot
  await calendar.deleteEvent(order.id);
  
  // Notify staff
  await slack.send(`Booking cancelled: ${order.customerName} - ${order.cancellationReason}`);
  
  // Track cancellation
  analytics.track('Order Cancelled', {
    orderId: order.id,
    reason: order.cancellationReason,
    cancelledBy: order.cancelledBy
  });
  break;

Use Cases

Calendar Integration

Keep external calendars in sync:
app.post('/webhooks/tiquo', async (req, res) => {
  res.status(200).send('OK');
  
  const event = req.body;
  
  switch (event.type) {
    case 'order.created':
    case 'order.confirmed':
      await googleCalendar.upsertEvent(event.data);
      break;
    case 'order.cancelled':
      await googleCalendar.deleteEvent(event.data.id);
      break;
  }
});

Staff Notifications

Alert staff of changes:
const notifyStaff = async (event) => {
  const messages = {
    'order.created': `📅 New booking: ${event.data.customerName}`,
    'order.confirmed': `✅ Confirmed: ${event.data.customerName}`,
    'order.cancelled': `❌ Cancelled: ${event.data.customerName}`
  };
  
  await slack.send(messages[event.type]);
};

Workflow Automation

Trigger automated workflows:
case 'order.completed':
  // Start post-service workflow
  await zapier.trigger('order_completed', {
    customerId: order.customerId,
    orderId: order.id,
    services: order.services
  });
  break;