Idempotent Courier Webhooks: Handling Real-Time Logistics Reconciliation on Cloudflare Workers
In last-mile e-commerce, third-party logistics (3PL) webhooks are notorious for network instability. Couriers routinely retry event notifications upon receiving minor delays, send status updates out of chronological sequence, or dispatch duplicate payloads during network failover events.
If a webhook handler blindly applies state updates without idempotency controls, an order might transition from "DELIVERED" back to "IN_TRANSIT", triggering incorrect inventory adjustments or customer alert notifications.
To resolve this on Iseul Glow, we built an idempotent state machine inside a Cloudflare Worker that coordinates real-time logistics events for the Real-Time Order Tracking portal.
The Webhook Ingestion Problem
When integrating with local couriers (such as Pathao Logistics or RedX), the API layer must process incoming POST events with three hard constraints:
- Process requests within 300ms to avoid courier timeout retries.
- Prevent duplicate execution when identical payload signatures arrive.
- Reject illegal state transitions (for example, transitioning from final delivery to pending pickup).
[ 3PL Courier System ]
|
| POST /api/webhook/courier
v
[ Cloudflare Worker Handler ]
|
+---> Check Payload SHA-256 Hash in D1 (Idempotency Check)
| |
| +--- If already processed: return HTTP 200 OK immediately
|
+---> Evaluate Order State Transition Matrix
| |
| +--- Valid: Execute atomic UPDATE in D1
| +--- Invalid: Log anomaly & return HTTP 200 OK
|
+---> Broadcast Update to Live Customer Tracking Route
1. Idempotency Key Verification
Every incoming webhook event generates a deterministic idempotency signature derived from the consignment identifier, event type, and timestamp:
// worker/src/routes/webhook.ts
import { d1run, d1get, now } from "../db";
export async function handleCourierWebhook(request: Request, env: Env): Promise<Response> {
const payload = await request.json();
const { consignment_id, order_number, event_status, event_time } = payload;
// Create deterministic hash
const rawKey = `${consignment_id}:${event_status}:${event_time}`;
const encoder = new TextEncoder();
const hashBuffer = await crypto.subtle.digest("SHA-256", encoder.encode(rawKey));
const idempotencyKey = Array.from(new Uint8Array(hashBuffer))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
// Check if event already executed
const existing = await d1get(env, "SELECT id FROM webhook_events WHERE idempotency_key = ?", [idempotencyKey]);
if (existing) {
return new Response(JSON.stringify({ ok: true, note: "duplicate ignored" }), { status: 200 });
}
// Record idempotency token before applying state
await d1run(
env,
"INSERT INTO webhook_events (idempotency_key, consignment_id, status, created_at) VALUES (?, ?, ?, ?)",
[idempotencyKey, consignment_id, event_status, now()]
);
await reconcileOrderStatus(env, order_number, event_status);
return new Response(JSON.stringify({ ok: true }), { status: 200 });
}
2. Enforcing the Finite State Machine
To prevent out-of-order execution, valid order state transitions are declared explicitly:
const ALLOWED_TRANSITIONS: Record<string, string[]> = {
"pending": ["confirmed", "cancelled"],
"confirmed": ["processing", "cancelled"],
"processing": ["shipped", "cancelled"],
"shipped": ["in_transit", "failed_delivery"],
"in_transit": ["delivered", "returned", "failed_delivery"],
"delivered": [], // Terminal state: no transitions allowed
"cancelled": [], // Terminal state
"returned": [] // Terminal state
};
async function reconcileOrderStatus(env: Env, orderNo: string, newStatus: string) {
const order = await d1get(env, "SELECT status FROM orders WHERE order_number = ?", [orderNo]);
if (!order) return;
const currentStatus = order.status.toLowerCase();
const allowed = ALLOWED_TRANSITIONS[currentStatus] || [];
if (!allowed.includes(newStatus.toLowerCase())) {
console.warn(`Rejected illegal transition from ${currentStatus} to ${newStatus} for order ${orderNo}`);
return;
}
await d1run(
env,
"UPDATE orders SET status = ?, updated_at = ? WHERE order_number = ?",
[newStatus.toLowerCase(), now(), orderNo]
);
}
3. Real-Time Customer Experience
When end-users enter their consignment number on the Order Tracking Portal, the client queries the edge endpoint directly. Because status updates reconcile atomically into Cloudflare D1, customers receive exact delivery updates without latency or status flickering.
Engineering resilient webhook infrastructure requires defensive idempotency filtering and strict state machine rules. The production application can be tested directly on Iseul Glow.
Top comments (0)