Webhooks

Order Webhooks

Receive order result callbacks and verify the webhook signature.

Modified at Apr 28, 2026, 05:38 AM UTC

Cek Ceir sends order webhooks when an order is created through an API key that has a webhook URL configured.

Destination Rules

Webhook URLs must use HTTPS and be publicly reachable. Localhost, private IP ranges, loopback addresses, and URLs with embedded username or password are rejected.

POSTyour webhook URL

Cek Ceir sends a POST request with a JSON body to your configured webhook URL.

Content-Type: application/jsonAccept: application/json, text/plain, */*X-Webhook-Event: dispatch.webhook.orderX-Signature: <hex hmac sha256>

Request Fields

FieldTypeRequiredDescription
Content-Typeheader stringYesAlways application/json.
Acceptheader stringYesAccepted response formats sent by the webhook sender.
X-Webhook-Eventheader stringYesWebhook event name, currently dispatch.webhook.order.
X-Signatureheader stringYesHMAC SHA-256 signature for the order payload.
statusbody stringYesOrder processing result.
order_idbody numberYesOrder ID.
transaction_idbody numberYesWallet transaction ID.
service_codebody stringYesService code.
charged_amountbody numberYesAmount captured from the wallet.
total_pricebody numberYesTotal order price before capture/refund adjustment.

The body is the order placement payload:

Payload Example

{  "status": "success",  "reference_id": "provider-reference-123",  "message": "Pesanan-mu telah berhasil kami proses.",  "processed": 1,  "processed_success": 1,  "processed_error": 0,  "remaining_balance": 98500,  "result": {    "status": "registered"  },  "error_message": null,  "order_id": 321,  "transaction_id": 654,  "service_code": "cek_imei",  "total": 1,  "price": 1500,  "total_price": 1500,  "charged_amount": 1500,  "refunded_amount": 0,  "balance_before": 100000,  "created_at": "2026-04-26T00:00:00.000Z"}

Response

Return any 2xx response to acknowledge delivery.

{  "ok": true}

Response Fields

FieldTypeRequiredDescription
okbooleanNoOptional acknowledgement flag from your webhook handler.

Verify Signature

The signature is:

HMAC_SHA256(JSON.stringify({ orderId, amount }), api_key_secret)

Use only the secret part of the API key as the HMAC key. amount is signed as a string. Do not convert it to a floating point number.

The signed amount follows the webhook event generated by the application:

Payload statusSigned amount
pendingString(total_price)
failed or cancelled"0"
success, partial, or completedString(charged_amount)
import crypto from "node:crypto";import express from "express";const app = express();app.use(express.json());app.post("/webhooks/order", (req, res) => {  const secret = process.env.API_KEY_SECRET ?? "";  const signature = req.header("X-Signature") ?? "";  const payload = req.body as {    order_id: number;    charged_amount?: number;    total_price?: number;    status?: string;  };  const amount =    payload.status === "pending"      ? String(payload.total_price ?? 0)      : payload.status === "failed" || payload.status === "cancelled"        ? "0"        : String(payload.charged_amount ?? 0);  const signed = JSON.stringify({ orderId: payload.order_id, amount });  const expected = crypto.createHmac("sha256", secret).update(signed).digest("hex");  const valid =    signature.length === expected.length &&    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));  if (!valid) {    return res.status(401).json({ ok: false });  }  return res.json({ ok: true });});