The key takeaway

Verify incoming events according to the sender’s documented protocol, persist accepted work before acknowledging it, and process repeated deliveries safely. Define how out-of-order events affect state and provide a replay procedure that respects the same business rules as normal processing.

Separate receipt from business processing

Keep the receiving endpoint focused on validation and durable acceptance. Acknowledge according to the provider's protocol after the accepted event is stored or queued durably. If persistence fails, returning success can lose the only copy your system would have processed.

Move slower business work into a worker. Preserve enough metadata to investigate a delivery, including the provider, event identifier, receipt time and processing state. Set a retention policy for stored payloads because events may contain customer information.

Verify before trusting the payload

Follow the sender's documented verification scheme, including its requirements for raw request bytes, timestamps and key rotation. Parsing and reserializing a body can change the bytes used for verification. Keep secrets out of logs and reject events that fail the required checks.

Verification establishes that a message meets the provider's authenticity checks. It does not establish that its business action is valid for every account in your system. Resolve the correct tenant and apply your own domain rules before changing state.

Deduplicate at the processing boundary

Store the provider's event identifier under a uniqueness constraint scoped to the provider or account as appropriate. Concurrent deliveries must converge on the same recorded event. An in-memory set disappears on restart and cannot coordinate multiple receivers.

Event deduplication and business idempotency solve different problems. Two distinct events can still refer to the same invoice or operation. Make the underlying state transition safe as well as preventing repeated processing of one event.

Decide how ordering works

Do not assume receipt time represents business order. Where the provider supplies resource versions, compare them using its documented rules. In other integrations, fetching the current remote resource may be safer than applying every event as a complete state snapshot.

Document which transitions are allowed. An old event should not silently move a completed operation back into a pending state. When the correct outcome cannot be determined, surface the conflict for reconciliation.

Make replay part of the integration

Provide a controlled way to retry failed processing without bypassing verification records, tenant boundaries or idempotency checks. Record who initiated the replay and what happened.

Use the same recovery principles as background jobs. For the broader contract between systems, see API design practices and the guide to payment integrations.

All insightsDiscuss your project