Idempotent Financial Workflows
Workflow
- Classify: API command (client retries), webhook (duplicate/out-of-order), worker job (queue redelivers), batch import (file/row reprocessed), external call (provider succeeds while local times out).
- Define idempotency: key source (client key, event id, transfer id, row/business key); scope (tenant/account/provider/endpoint); stored result (pending/succeeded/failed/payload/ref); conflict: same key+payload returns prior result, different payload rejected; prefer durable DB constraints over in-memory dedupe.
- Order side effects: validate first; persist intent before external calls; wrap co-committing state in a transaction; use an outbox for post-commit effects; store provider ids; expose completion only once records exist.
- Test: duplicate same key/payload; duplicate same key/diff payload; retry after timeout/exception; webhook delivered twice; worker crash after partial writes; out-of-order events.
- Implement: reuse existing transaction helpers, repositories, job frameworks, provider adapters; keep handlers thin, idempotency decisions in a service layer.
Guardrails
- Do not rely on frontend disabling, memory, or queue visibility timeouts alone.
- Do not call a money-moving provider before recording local intent to recover.
- Do not mark an operation permanently failed if the side effect may have succeeded.
- Do not hide duplicate/conflict behavior; log it in metrics or stored state.