Start with data ownership, not endpoints
For each domain—products, prices, stock, customers, orders and invoices—decide which system is authoritative. Two-way synchronization without ownership rules creates loops and conflicts. A practical design often uses different owners for different fields rather than declaring one system the master of everything.
Separate commands from facts
“Create shipment” is a command. “Shipment created” is a fact. Treating both as the same kind of message makes recovery difficult. The integration should know whether it is asking another system to do work or recording something that already happened.
Design for duplicated and delayed events
Webhooks can be delivered more than once and networks can reorder events. Important operations need idempotency: processing the same business event twice should not create two invoices, two shipments or two ERP orders.
Reconciliation closes the gap
Even a well-designed event flow benefits from a periodic reconciliation job. Compare counts, identifiers or timestamps so a silent failure cannot live for weeks. Reconciliation is especially useful after deployments and external API incidents.
- Define the source of truth per field
- Store external identifiers explicitly
- Use queues for operations that can be retried
- Log request/response context without leaking secrets
- Provide a way to replay failed jobs
- Add reconciliation after cutover
