ENGINEERING NOTE 26 / 50 · CARD

Make a card load retry safe after a lost response

OPEN RAMBO ·

A timeout does not prove a card load failed. Reuse the original operation identity and reconcile its outcome before creating another debit.

Published by OPEN RAMBO. The engineering patterns and pseudocode illustrate designs, not a documented product API. Numerical examples are illustrative.

Bind identity to intent

Persist an operation key with owner, card reference, amount and currency. Reusing the key with different parameters should be rejected. A browser-generated random key per retry defeats idempotency because every retry looks like a new operation.

Represent the uncertain state

If the upstream response is lost, retain a pending or reconciliation state. Query the upstream reference or use a documented replay mechanism. Do not refund the wallet merely because the HTTP request timed out if the card may already have been loaded.

Commit once

Use a unique ledger reference and an atomic state transition for the final debit. Cache or reconstruct the same result for repeated client requests. The UI should show the original operation’s progress instead of inviting an immediate second top-up.

Illustrative implementation

key = (owner_id, client_operation_id)
assert_same_parameters(key, card_id, amount, currency)
return resume_or_create(key)

Acceptance check

Lose the response after upstream success, then retry concurrently. Verify one upstream load and one final wallet debit.

Further reading

Read next