Skip to main content

Overview

Satsuma uses webhooks to notify your application about important events in real-time. This enables you to provide immediate updates to users about their orders and respond to inventory changes as they happen.

Supported Events

Order Events

  • order.created - New order has been placed
  • order.confirmed - Merchant has confirmed the order
  • order.ready - Order is ready for pickup/delivery
  • order.completed - Order has been fulfilled
  • order.cancelled - Order has been cancelled
  • order.failed - Order processing failed

Inventory Events

  • inventory.updated - Product inventory levels changed
  • inventory.low_stock - Product inventory below threshold
  • inventory.out_of_stock - Product is now unavailable

Cart Events

  • cart.abandoned - Cart inactive for specified period
  • cart.expires_soon - Cart approaching expiration time

Setting Up Webhooks

Creating a Webhook Endpoint

1

Create Endpoint

Set up an HTTP endpoint in your application to receive webhook events
2

Configure in Dashboard

Add your endpoint URL and select events in the Satsuma Dashboard
3

Verify Signatures

Implement signature verification for security
4

Test Reception

Use our test events to verify your endpoint works correctly

Dashboard Configuration

  1. Navigate to Developer Settings > Webhooks
  2. Click Add Webhook Endpoint
  3. Configure your endpoint:
    • URL: Your HTTPS endpoint URL
    • Events: Select which events to receive
    • Secret: Optional signing secret for verification
Webhook URLs must use HTTPS and return a 2xx status code within 10 seconds to be considered successful.

Webhook Structure

All webhooks follow the same structure:
{
  "id": "evt_1234567890",
  "type": "order.confirmed",
  "created": "2024-01-15T10:30:00Z",
  "data": {
    "object": "order",
    "id": "ord_abcd1234",
    "status": "confirmed",
    "merchant_id": "merch_xyz789",
    "user_id": "user_123",
    "total": 24.99,
    "currency": "USD",
    "items": [
      {
        "product_id": "prod_456",
        "quantity": 2,
        "price": 12.49
      }
    ],
    "estimated_ready_time": "2024-01-15T11:00:00Z"
  }
}

Event Examples

Order Confirmed

{
  "id": "evt_order_confirmed_123",
  "type": "order.confirmed",
  "created": "2024-01-15T10:30:00Z",
  "data": {
    "object": "order",
    "id": "ord_abcd1234",
    "status": "confirmed",
    "merchant_id": "merch_xyz789",
    "estimated_ready_time": "2024-01-15T11:00:00Z",
    "fulfillment_method": "pickup",
    "special_instructions": "Extra hot, no foam"
  }
}

Inventory Updated

{
  "id": "evt_inventory_updated_456", 
  "type": "inventory.updated",
  "created": "2024-01-15T10:35:00Z",
  "data": {
    "object": "inventory",
    "product_id": "prod_789",
    "merchant_id": "merch_xyz789",
    "previous_quantity": 50,
    "current_quantity": 48,
    "location_id": "loc_abc123"
  }
}

Cart Abandoned

{
  "id": "evt_cart_abandoned_789",
  "type": "cart.abandoned", 
  "created": "2024-01-15T12:00:00Z",
  "data": {
    "object": "cart",
    "id": "cart_def456",
    "user_id": "user_123",
    "last_activity": "2024-01-15T10:00:00Z",
    "total_value": 42.50,
    "item_count": 3
  }
}

Implementing Webhook Handlers

# Test webhook endpoint with curl
curl -X POST https://your-app.com/webhooks/satsuma \
  -H 'Content-Type: application/json' \
  -H 'X-Signature: your-computed-hmac-signature' \
  -d '{
    "id": "evt_test_123",
    "type": "order.confirmed",
    "created": "2024-01-15T10:30:00Z",
    "data": {
      "object": "order",
      "id": "ord_test_123",
      "status": "confirmed",
      "user_id": "user_123"
    }
  }'

# Verify webhook endpoint health
curl -X GET https://your-app.com/webhooks/health

Signature Verification

Verify webhook authenticity using HMAC-SHA256 signatures:
# Test signature verification endpoint
curl -X POST https://your-app.com/webhooks/verify \
  -H 'Content-Type: application/json' \
  -H 'X-Signature: computed-hmac-signature' \
  -d '{"test": "payload"}'

# Generate HMAC signature for testing (requires openssl)
echo -n '{"test": "payload"}' | \
  openssl dgst -sha256 -hmac "your-webhook-secret" -binary | \
  xxd -p -c 256

Error Handling & Retries

Delivery Guarantees

Satsuma guarantees webhook delivery through:
  • Automatic Retries: Failed webhooks are retried with exponential backoff
  • Retry Schedule: Immediate, 5min, 15min, 1hr, 6hr, 24hr
  • Manual Retry: Retry failed deliveries from the dashboard
  • Dead Letter Queue: Webhooks that fail all retries are stored for investigation

Handling Failures

Implement robust error handling:
# Test error scenarios
curl -X POST https://your-app.com/webhooks/satsuma \
  -H 'Content-Type: application/json' \
  -H 'X-Signature: invalid-signature' \
  -d '{"test": "invalid payload"}' \
  -w "HTTP Status: %{http_code}\n"

# Test timeout scenario
curl -X POST https://your-app.com/webhooks/satsuma \
  --max-time 5 \
  -H 'Content-Type: application/json' \
  -d '{"type": "slow.event"}'

Testing Webhooks

Local Testing with ngrok

# Install ngrok
npm install -g ngrok

# Start your local server
node server.js

# Expose local server
ngrok http 3000

# Use the ngrok URL in your webhook configuration
# https://abc123.ngrok.io/webhooks/satsuma

Test Events

Send test events from the dashboard to verify your endpoint:
# Test order confirmation webhook
curl -X POST https://your-app.com/webhooks/satsuma \
  -H 'Content-Type: application/json' \
  -H 'X-Signature: your-computed-hmac-signature' \
  -d '{
    "id": "evt_test_123",
    "type": "order.confirmed",
    "created": "2024-01-15T10:30:00Z",
    "data": {
      "object": "order",
      "id": "ord_test_123",
      "status": "confirmed",
      "user_id": "user_123"
    }
  }'

# Test inventory update webhook
curl -X POST https://your-app.com/webhooks/satsuma \
  -H 'Content-Type: application/json' \
  -H 'X-Signature: your-computed-hmac-signature' \
  -d '{
    "id": "evt_inventory_test_456",
    "type": "inventory.updated",
    "created": "2024-01-15T10:35:00Z",
    "data": {
      "object": "inventory",
      "product_id": "prod_789",
      "current_quantity": 48
    }
  }'

# Test webhook endpoint health
curl -X GET https://your-app.com/webhooks/health \
  -H 'Accept: application/json'

Monitoring & Debugging

Webhook Logs

View delivery logs in your dashboard:
  • Status: Success, failure, or pending retry
  • Response: HTTP status and response body from your endpoint
  • Timing: Request duration and retry attempts
  • Payload: Full webhook payload for debugging

Health Monitoring

Monitor your webhook endpoint health:
# Check webhook endpoint health
curl -X GET https://your-app.com/webhooks/health \
  -H 'Accept: application/json' \
  -w "Status: %{http_code}, Time: %{time_total}s\n"

# Monitor webhook processing metrics
curl -X GET https://your-app.com/webhooks/metrics \
  -H 'Accept: application/json'

# Test webhook endpoint availability
curl -X OPTIONS https://your-app.com/webhooks/satsuma \
  -H 'Access-Control-Request-Method: POST'

Best Practices

Performance

  • Return HTTP 200 within 10 seconds
  • Process webhooks asynchronously when possible
  • Implement idempotency using the event ID
  • Use database transactions for data consistency

Security

  • Always verify webhook signatures
  • Use HTTPS endpoints only
  • Whitelist Satsuma IP addresses if needed
  • Implement rate limiting on your webhook endpoint

Reliability

  • Handle duplicate events gracefully (idempotency)
  • Implement exponential backoff for downstream failures
  • Log all webhook events for debugging
  • Monitor webhook processing metrics

Need Help?

I