⚡ Nepal's #1 affiliate commerce network — earn up to 18% commission. Join free →
Influencemart
Become an Affiliate

Integrations

Webhooks

Push order and product events from your store into the platform. Webhooks use the same API key and HMAC signing as the rest of the API, and route into the same pipelines — so they obey identical dedup and commission rules.

A webhook is a signed POST from your systems to ours. Each endpoint maps an event in your store to a pipeline on the platform: order-created reports a conversion, the other order-* events drive the order-status lifecycle, and the product-* events upsert products and stock. Because they share those pipelines, the same attribution, dedup and commission behaviour you get from the direct API applies to webhooks too.

Endpoints

The eight webhook endpoints and what each one does:

EndpointPurpose
/api/v1/webhooks/order-createdA new order was created — reports a conversion (attribute via click_id).
/api/v1/webhooks/order-paidPayment captured — moves the order toward a payable commission.
/api/v1/webhooks/order-deliveredOrder delivered — starts the commission hold window.
/api/v1/webhooks/order-cancelledOrder cancelled — reverses (rejects) the commission unless already paid.
/api/v1/webhooks/order-returnedOrder returned — reverses (rejects) the commission unless already paid.
/api/v1/webhooks/order-refundedOrder refunded — reverses (rejects) the commission unless already paid.
/api/v1/webhooks/product-updatedProduct details changed — upserts the product.
/api/v1/webhooks/product-stock-updatedStock status changed — updates product availability.

Required headers

Every webhook is authenticated and signed exactly like any other API call: send your X-API-Key, a fresh X-Timestamp, and an X-Signature over `${timestamp}.${rawBody}`. See authentication for the headers and HMAC signing for the signing recipe.

On top of those, every webhook requires the X-External-Event-Id header. This is your unique id for the event and it is the dedup anchor: a webhook is stored exactly once per (merchant + X-External-Event-Id). Generate a stable, unique value per real-world event and reuse it if you retry — that is how the platform guarantees each event is processed exactly once.

X-External-Event-Id is required on every webhook. A request without it is rejected with 400 before any processing happens.

Signature verification

Sign the exact bytes you send. Serialize the JSON body once, compute HMAC-SHA256 of `${timestamp}.${rawBody}` as lowercase hex, then send that same string as the body. The platform recomputes the signature over the raw bytes it receives — if your framework re-encodes the body after signing, the bytes change and verification fails with 401. The X-External-Event-Id header is not part of the signing string; it travels alongside the signed request as the dedup key.

Example: order-created

The body is flexible JSON and accepts either snake_case or camelCase field names. Always include external_order_id; for order-created also send the click_id you captured plus order_amount and currency so the conversion attributes and prices correctly.

Signed request · cURL
TS=$(date +%s)
BODY='{"external_order_id":"ORD-1001","click_id":"CLK_example123","order_amount":"2999.00","currency":"NPR","external_product_id":"SKU-100","ordered_at":"2026-06-14T09:30:00Z"}'
SIG=$(printf '%s' "$TS.$BODY" | openssl dgst -sha256 -hmac "$AFF_API_SECRET" | sed 's/^.* //')

curl -X POST "$AFF_BASE_URL/v1/webhooks/order-created" \
  -H "X-API-Key: $AFF_API_KEY" \
  -H "X-Timestamp: $TS" \
  -H "X-Signature: $SIG" \
  -H "X-External-Event-Id: evt_8a1f2c3d" \
  -H "Content-Type: application/json" \
  --data "$BODY"

Response

A successfully accepted webhook returns 202 with the queued event id and status: "QUEUED". Processing then happens asynchronously through the shared pipelines.

Response · 202
{
  "webhookEventId": "wh_3f9c…",
  "status": "QUEUED",
  "duplicate": false
}

Retry behaviour

Acceptance (the 202) only means the event was stored and queued — it does not mean it has been fully processed. If processing later fails, the platform retries it automatically with exponential backoff. Persistent failures are surfaced in your dashboard, where you can inspect the error and trigger a manual retry. On your side, you should retry on network errors or non-2xx responses, reusing the same X-External-Event-Id so the retry is recognised as the same event rather than a new one.

Duplicate behaviour

Duplicates are treated as success, not as errors. If a webhook arrives with a (merchant + X-External-Event-Id) pair that was already received, the platform stores nothing new and responds 202 with status: "DUPLICATE". The event is processed exactly once, so resending after a timeout is always safe.

Response · 202 (duplicate)
{
  "webhookEventId": "wh_3f9c…",
  "status": "DUPLICATE",
  "duplicate": true
}

Troubleshooting

  • 401 — authentication or signature failure. Check the X-API-Key, X-Timestamp and X-Signature headers, that you signed `${timestamp}.${rawBody}` over the exact bytes you sent, and that your clock is within ±300s.
  • 400 — a missing or invalid X-External-Event-Id header, or a body that fails validation. Every webhook must carry the event id.
  • 202 with status: "DUPLICATE" — expected when you resend the same event id; no action needed.
  • • Accepted but no commission moved — check the dashboard. Processing is async; failures show there for manual retry, and order-status transitions still obey the commission rules.
Webhooks are a transport over the same logic as the direct API. For attribution and conversion details see conversions, and for the dedup and safe-retry model see idempotency.

Start earning from your audience

Join Nepal's affiliate network. Weekly payouts, real tracking, honest commissions.

Join as Affiliate →List Your Store