Teaching scenario: A refund service and its amounts are hypothetical. This is an architecture exercise about uncertain outcomes, not a description of a payment provider incident.
A timeout is an observationAn assistant submits a refund request. The provider completes the refund, but the response is lost. Your application sees a timeout. It knows that it did not receive a usable response; it does not yet know whether the refund happened.
That distinction should appear in the state model. If every timeout becomes “failed,” a user or agent may try again as though nothing happened. If every timeout becomes “succeeded,” the interface may report a result it has not verified. Keep an explicit unknown state and give it a recovery path.
Preserve the identity of the intended actionSuppose the intended action is one approved refund for one order. Create an operation record before dispatch, with a stable operation identifier, the approved request parameters, and the state of the attempt. A second network attempt for that same intended action should preserve the identity that the provider's contract expects.
AWS's discussion of idempotent APIs explains why caller-supplied request identifiers help services distinguish a retried request from a new intent. The provider's actual semantics still matter. Primary reference: Amazon Builders' Library.
Do not generate a new idempotency key simply because the first request timed out. That can turn a retry into a new operation. Also do not reuse a key for a different amount or recipient. Bind your internal operation to the intended action, and check how the receiving API treats matching keys with changed parameters.
Write the recovery statesState
What the application knows
Appropriate next step
Prepared
The action is recorded but not dispatched
Validate current authority and parameters
Attempted
The request was dispatched
Await a result or reconciliation evidence
Unknown
The application cannot establish the outcome
Check provider status or use a contract-supported retry
Confirmed completed
Authoritative evidence identifies the completed action
Report the result and stop duplicate execution
Confirmed not completed
Evidence establishes that no effect occurred
Apply the approved retry or cancellation policy
These are suggested application states. Map them to the provider's available status, lookup, and retry mechanisms. If no reliable lookup exists, the recovery process may require an operator rather than another autonomous attempt.
Check the limits of the contractIdempotency is not a universal promise that every request can be repeated forever. Scope, retention time, validation behavior, and partial execution rules can differ. Stripe's documentation, for example, distinguishes API versions and describes retention and parameter checks for its idempotency behavior. Read the contract for the exact endpoint and API version you use. Primary reference: Stripe idempotent requests.
Your application should retain enough information to avoid accidentally creating a second business action after the provider's deduplication window has passed. Decide how long an unresolved operation can remain unknown, who investigates it, and what evidence closes it. Keep sensitive payloads out of routine logs while preserving the identifiers needed for reconciliation.
Test the failure that mattersIn a controlled test, let the provider simulator commit the operation and then discard its response. The application should preserve the unknown outcome, recover evidence of the existing operation, and avoid a second effect. Inspect the simulator's operation count as well as the user interface. A screenshot of an error message cannot show whether money moved twice.
Then test a timeout before the simulator accepts the request, a repeated request with altered parameters, and a retry after the configured retention window. These cases challenge different assumptions.
For an interview: Explain what a timeout does and does not tell you, then trace one recovery path. For a team: Write the state transitions, responsible owner, and reconciliation evidence before enabling autonomous retries. The goal is a truthful outcome and a controlled recovery, including when the system must wait.
Teaching scenario: A refund service and its amounts are hypothetical. This is an architecture exercise about uncertain outcomes, not a description of a payment provider incident.
A timeout is an observationAn assistant submits a refund request. The provider completes the refund, but the response is lost. Your application sees a timeout. It knows that it did not receive a usable response; it does not yet know whether the refund happened.
That distinction should appear in the state model. If every timeout becomes “failed,” a user or agent may try again as though nothing happened. If every timeout becomes “succeeded,” the interface may report a result it has not verified. Keep an explicit unknown state and give it a recovery path.
Preserve the identity of the intended actionSuppose the intended action is one approved refund for one order. Create an operation record before dispatch, with a stable operation identifier, the approved request parameters, and the state of the attempt. A second network attempt for that same intended action should preserve the identity that the provider's contract expects.
AWS's discussion of idempotent APIs explains why caller-supplied request identifiers help services distinguish a retried request from a new intent. The provider's actual semantics still matter. Primary reference: Amazon Builders' Library.
Do not generate a new idempotency key simply because the first request timed out. That can turn a retry into a new operation. Also do not reuse a key for a different amount or recipient. Bind your internal operation to the intended action, and check how the receiving API treats matching keys with changed parameters.
Write the recovery statesState
What the application knows
Appropriate next step
Prepared
The action is recorded but not dispatched
Validate current authority and parameters
Attempted
The request was dispatched
Await a result or reconciliation evidence
Unknown
The application cannot establish the outcome
Check provider status or use a contract-supported retry
Confirmed completed
Authoritative evidence identifies the completed action
Report the result and stop duplicate execution
Confirmed not completed
Evidence establishes that no effect occurred
Apply the approved retry or cancellation policy
These are suggested application states. Map them to the provider's available status, lookup, and retry mechanisms. If no reliable lookup exists, the recovery process may require an operator rather than another autonomous attempt.
Check the limits of the contractIdempotency is not a universal promise that every request can be repeated forever. Scope, retention time, validation behavior, and partial execution rules can differ. Stripe's documentation, for example, distinguishes API versions and describes retention and parameter checks for its idempotency behavior. Read the contract for the exact endpoint and API version you use. Primary reference: Stripe idempotent requests.
Your application should retain enough information to avoid accidentally creating a second business action after the provider's deduplication window has passed. Decide how long an unresolved operation can remain unknown, who investigates it, and what evidence closes it. Keep sensitive payloads out of routine logs while preserving the identifiers needed for reconciliation.
Test the failure that mattersIn a controlled test, let the provider simulator commit the operation and then discard its response. The application should preserve the unknown outcome, recover evidence of the existing operation, and avoid a second effect. Inspect the simulator's operation count as well as the user interface. A screenshot of an error message cannot show whether money moved twice.
Then test a timeout before the simulator accepts the request, a repeated request with altered parameters, and a retry after the configured retention window. These cases challenge different assumptions.
For an interview: Explain what a timeout does and does not tell you, then trace one recovery path. For a team: Write the state transitions, responsible owner, and reconciliation evidence before enabling autonomous retries. The goal is a truthful outcome and a controlled recovery, including when the system must wait.