Webhooks

Receive real-time notifications whenever an order status changes, signed with HMAC-SHA256 and delivered through a durable outbox.

Event: order.status_changed

Revolix sends a POST to your endpoint whenever an order status changes. The request carries a JSON payload with these headers:

Headers
X-RX-Signature: <hex hmac-sha256>
X-RX-Timestamp: <unix seconds>
Content-Type: application/json
Payload
{
  "event": "order.status_changed",
  "order_id": "ord_01JABCDEFGH",
  "status": "delivered",
  "previous_status": "processing",
  "amount": 1990,
  "currency": "MYR",
  "timestamp": "2026-08-28T12:34:56Z"
}

Verify signature

The signature is an HMAC-SHA256 of timestamp.body using your webhook signing secret. Reject any timestamp older than five minutes to prevent replay attacks.

javascript
import crypto from "node:crypto";

export async function POST(req) {
  const secret = process.env.RX_WEBHOOK_SECRET;
  const payload = await req.text(); // raw body · JANGAN parse dahulu
  const sig = req.headers.get("x-rx-signature") ?? "";
  const ts = req.headers.get("x-rx-timestamp") ?? "";

  // 1. Reject stale timestamps (replay protection: 5-minute window)
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
    return new Response(null, { status: 400 });
  }

  // 2. Verify signature
  const expected = crypto
    .createHmac("sha256", secret)
    .update(ts + "." + payload)
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
    return new Response(null, { status: 401 });
  }

  // 3. Process · return 2xx cepat
  const event = JSON.parse(payload);
  // ... sync ke sistem anda
  return new Response(null, { status: 204 });
}

Delivery schedule

Delivery attempts seven times in total (initial attempt plus six retries). A delivery counts as successful when your endpoint returns a 2xx status within 10 seconds.

PercubaanSelepas
Initial·
Retry 11 minit
Retry 25 minit
Retry 330 minit
Retry 42 jam
Retry 56 jam
Retry 624 jam

Best practices

  • Return a 2xx status immediately and process the event asynchronously in a queue.
  • Verify the signature on every request and never act on an unverified payload.
  • Design handlers to be idempotent: the same event may be delivered more than once.
  • Use HTTPS only: plain HTTP endpoints are rejected at registration.