sgeraDocs
Core concepts

Custom store webhook

Send orders from any store for WhatsApp order confirmation and receive the customer's decision.

For stores without a built-in connector. Your store sends each new order to Msgera, Msgera asks the customer on WhatsApp to confirm or cancel, and (optionally) tells your store the answer.

Connect

In the dashboard, open Integrations and connect Custom store (webhook). You can give an optional callback URL (a public https:// address) to receive decisions. You get a webhook URL and a secret.

The secret is shown once

Copy it and store it on your side. Disconnect and connect again to get a new one.

Send orders

POST each order to your webhook URL as JSON:

{
  "event": "order.created",
  "order": {
    "id": "A-1001",
    "number": "1001",
    "total": "149.50",
    "currency": "EGP",
    "customer": { "name": "Omar", "phone": "+201000000001" },
    "items": [{ "name": "Cotton T-shirt", "quantity": 2 }],
    "status": "pending"
  }
}
FieldTypeDescription
eventrequiredstringorder.created asks the customer. order.updated tells Msgera the order moved on (shipped, delivered, completed, cancelled, refunded, failed), so it stops waiting for the customer.
order.idrequiredstringYour order ID, up to 100 characters.
order.totalrequirednumber | stringOrder total.
order.numberstringOrder number, shown to the customer only when no items are sent.
order.itemsarrayOrdered items: [{ name, quantity }]. The WhatsApp message lists up to 5.
order.currencystringCurrency code, e.g. EGP or SAR.
order.customer.phonestringCustomer phone with country code, e.g. +201000000001.
order.customer.namestringCustomer name.

Sign the request

Send the header X-Msgera-Signature: sha256=<hex>, where <hex> is the HMAC-SHA256 of the exact raw request body, keyed with your secret.

const body = JSON.stringify(payload);
const signature =
  "sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex");
await fetch(webhookUrl, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-Msgera-Signature": signature },
  body,
});

Msgera answers 200 (accepted, duplicate or ignored event), 400 (invalid body) or 401 (bad signature). The same body sent twice is processed once, so retrying is safe.

Customer decisions (callback)

When a callback URL is set, Msgera posts each decision to it:

{ "orderId": "A-1001", "decision": "confirm" }

decision is confirm, cancel (auto-cancel on) or cancel_request (auto-cancel off: the customer asked to cancel and you decide). The request is signed the same way (X-Msgera-Signature, same secret) and carries X-Msgera-Event: order.decision. Answer with any 2xx. A 4xx marks the update as failed; a 5xx or timeout is retried a few times.

Without a callback URL, the decision is only recorded in Msgera (the Orders list on the Integrations page).