Skip to main content

Webhooks

Receive real-time notifications for appointment lifecycle events and availability rule changes.

Topics & Resources

Resources: appointment, availability
Topics: appointment.created, appointment.updated, appointment.deleted, appointment.trashed, appointment.rescheduled, appointment.cancelled, availability.created, availability.updated, availability.deleted

Admin Setup

  1. Go to WooCommerce → Settings → Advanced → Webhooks.
  2. Click Add Webhook.
  3. Set Status to Active.
  4. Choose a Topic.
  5. Enter a Delivery URL (HTTPS endpoint).
  6. Set a Secret to sign payloads.
  7. Save.

Create via REST

curl -X POST "https://yourstore.example/wp-json/wc/v3/webhooks" \
-u ck_yourkey:cs_yoursecret \
-H "Content-Type: application/json" \
-d '{
"name": "Appointments Updated",
"topic": "appointment.updated",
"delivery_url": "https://yourapp.example/webhooks/woocommerce",
"secret": "your-shared-secret",
"status": "active"
}'

Payloads

Example appointment.updated:

{
"id": 12345,
"status": "confirmed",
"customer_status": "expected",
"product_id": 987,
"order_id": 456,
"order_item_id": 78910,
"customer_id": 321,
"qty": 1,
"cost": 0,
"all_day": false,
"start": 1732140000,
"end": 1732143600,
"timezone": "UTC",
"local_timezone": "America/New_York",
"staff_ids": [55],
"google_calendar_event_id": "evt_abc",
"google_calendar_staff_event_ids": [],
"date_created": "2025-11-21 15:05:00",
"date_modified": "2025-11-21 15:10:00"
}

Deleted events deliver minimal bodies:

{ "id": 12345 }

Signature Verification

  • Header: X-WC-Webhook-Signature (base64 HMAC-SHA256 of raw body using your secret).

Node.js

app.post('/webhooks/woocommerce', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.header('X-WC-Webhook-Signature') || '';
const secret = process.env.WC_WEBHOOK_SECRET;
const crypto = require('crypto');
const digest = crypto.createHmac('sha256', secret).update(req.body).digest('base64');
if (Buffer.from(signature).equals(Buffer.from(digest))) { res.sendStatus(200); return; }
res.sendStatus(400);
});

PHP

$secret = getenv('WC_WEBHOOK_SECRET');
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '';
$digest = base64_encode( hash_hmac( 'sha256', $raw, $secret, true ) );
if ( hash_equals( $signature, $digest ) ) { http_response_code(200); exit; }
http_response_code(400);

References

  • includes/class-wc-appointments-webhooks.php:104 registers resources and topics.
  • includes/class-wc-appointments-webhooks.php:167 maps topics to lifecycle hooks.
  • includes/class-wc-appointments-webhooks.php:189 builds payloads.