Skip to main content
Webhooks let your systems react to events in a Take App store in real time — no polling required. When an order is created or updated, Take App sends an HTTP POST request to the endpoint(s) you configure. The event payload reuses the same Order object returned by the Merchant API V2 Get order endpoint, so you only need to model the order shape once.

Configuring endpoints

Add and manage endpoints in your admin dashboard under Settings → Apps → Webhooks. For each endpoint you choose:
  • Endpoint URL — an https:// URL that accepts POST requests.
  • Events — which events this endpoint subscribes to.
Each endpoint has a signing secret used to verify incoming requests. Copy it anytime from the endpoint’s ⋯ → Copy signing secret menu. You can rotate the secret at any time; the old secret stops working immediately.

Events

EventWhen it fires
order.createdA new order is placed, or a draft order is activated for the first time.
order.updatedAn existing order changes — status, payment, fulfillment, or line items.

Payload

Every delivery has the same envelope. data is the V2 Order object.
{
  "type": "order.updated",
  "created_at": "2026-06-05T08:30:00.000Z",
  "data": {
    "id": "ord_123",
    "object": "order",
    "number": "1042",
    "order_status": "confirmed",
    "payment_status": "paid",
    "fulfillment_status": "unfulfilled",
    "customer": {
      "id": "cus_123",
      "object": "customer",
      "name": "Jane Doe",
      "phone": "6591234567"
    },
    "line_items": [
      {
        "id": "oli_1",
        "object": "order_line_item",
        "product_id": "prod_1",
        "name": "Nasi Lemak",
        "quantity": 2,
        "price": 650,
        "total_amount": 1300
      }
    ],
    "items_amount": 1300,
    "total_amount": 1300,
    "currency": "SGD",
    "created_at": "2026-06-05T08:00:00.000Z",
    "updated_at": "2026-06-05T08:30:00.000Z"
  }
}
See Get order for the full Order schema.

Headers

HeaderDescription
X-Take-EventThe event type, e.g. order.created.
X-Take-Delivery-IdUnique ID for this delivery attempt. Use for dedupe.
X-Take-SignatureSignature used to verify authenticity (see below).

Verifying signatures

Each request is signed with your endpoint’s signing secret using HMAC-SHA256. The X-Take-Signature header looks like:
t=1717574400,v1=5257a869e7ec...
  • t — the Unix timestamp (seconds) when the request was signed.
  • v1 — the HMAC-SHA256 of {t}.{raw_request_body}, hex-encoded.
To verify, recompute v1 with your secret over {t}.{raw_body} and compare using a constant-time comparison. Reject requests whose timestamp is too old (e.g. older than 5 minutes) to defend against replays.
import crypto from "crypto";

function verifyTakeSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((kv) => kv.split("="))
  );
  const timestamp = parts.t;
  const received = parts.v1;

  // Reject old timestamps (replay protection)
  const age = Math.floor(Date.now() / 1000) - Number(timestamp);
  if (Number.isNaN(age) || age > 300) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(received)
  );
}
Verify the signature against the raw request body bytes, before any JSON parsing or re-serialization. Reformatting the body changes the signature.

Responding

Return a 2xx status as soon as you’ve received the event. Do any heavy processing asynchronously so you can respond quickly.

Retries

If your endpoint returns a non-2xx status or times out, delivery is retried with exponential backoff. A 4xx response (other than 408 and 429) is treated as a permanent rejection and is not retried. Because retries and at-least-once delivery are possible, treat webhooks as idempotent: use X-Take-Delivery-Id to ignore duplicates.

Ordering

Events are not guaranteed to arrive in order. Use the order’s updated_at field to discard stale updates if you persist order state.
The legacy Svix-based webhook portal is being phased out. New integrations should use the endpoints configured in Settings → Apps → Webhooks.