advanced 2 min answer

A payment integration retries on timeout. Finance reports occasional double charges. The provider supports idempotency keys and they are being used. Diagnose.

stripepaymentsidempotencyclient-bug
Show the full answer Hide the answer

What the interviewer is testing

Whether you know the client-side failure that defeats a correct server implementation.

The diagnosis

The key is being generated per attempt rather than per operation.

If the key is created inside the retry loop, or when the HTTP request object is constructed, each attempt carries a different value and the provider correctly treats them as distinct operations. The mechanism provides nothing.

This is the single most common idempotency defect. It is invisible in testing, because retries rarely occur there, and it only manifests under the network conditions that make retries necessary.

The variants worth checking

A new key on user-initiated retry. The customer presses "pay" again after a timeout and the client treats it as a fresh operation. The key should be tied to the checkout session or cart, not to the button press.

Key derived from a timestamp or random value at request time rather than at operation creation.

Multiple client instances — a web session and a mobile app for the same order — generating independent keys.

Key not persisted, so an application restart mid-retry produces a new one.

The fix

Generate the key when the operation is created — when the user commits to paying — and persist it with the order locally. Every attempt, including after a restart, uses that value.

Better still: derive it deterministically from a stable business identifier, such as a hash of the order id and the payment attempt sequence. That survives losing local state entirely, which is the robust version.

What a strong answer adds

The reconciliation control that catches whatever remains: a daily comparison between orders and charges, alerting on any order with more than one successful charge. Idempotency reduces the incidence; reconciliation detects the residue, and financial systems need both.

And the note that the same defect shape defeats deduplication in messaging consumers — a producer that generates a fresh message id on each retry has defeated the consumer's dedup logic identically.

Common weak answers

Removing the retry, which loses genuine transient recovery. Blaming the payment provider.