Amazon's Selling Partner API is powerful and it hands you duplicate, out-of-order, and late notifications. If your handler assumes one event per change, in order, it will corrupt your data.
The pattern that survives: treat every notification as a signal to re-fetch authoritative state, and make processing idempotent.
async function handleFulfillmentEvent(msg) {
const key = msg.NotificationId;
// 1. Dedupe on NotificationId
if (await seen.has(key)) return;
await seen.add(key, { ttl: '7d' });
// 2. Do NOT trust the payload as truth. Re-fetch.
const order = await spapi.getOrder(msg.AmazonOrderId);
// 3. Process against current state, not the event snapshot.
await syncOrderState(order);
}
Why re-fetch instead of using the payload:
- Notifications arrive out of order. The one you process second may describe an earlier state.
- Payloads can be stale by the time you read them.
- Amazon can resend the same notification.
Guard with a version timestamp:
if (order.LastUpdateDate <= storedLastUpdate) return; // older, skip
This is not Amazon-specific. Any webhook system with at-least-once delivery needs the same three defenses: dedupe on ID, re-fetch state, guard with a version timestamp. Get these right and fulfillment sync stops being a source of bugs and starts being boring, which is exactly what you want.
Top comments (0)