API DesignIntermediate

Add retries to payments

You asked

“Payments sometimes fail with timeouts from the provider and the customer sees an error. Can you add retries so a transient blip does not lose the sale?”

The model answered

1export async function chargeWithRetry(order: Order): Promise<Charge> {
2 let lastError: unknown
3
4 for (let attempt = 1; attempt <= 3; attempt++) {
5 try {
6 return await provider.charge({
7 amount: order.total,
8 currency: order.currency,
9 customer: order.customerId,
10 })
11 } catch (err) {
12 lastError = err
13 await sleep(1000)
14 }
15 }
16
17 throw lastError
18}
Assistant · I wrapped the charge in a retry loop with three attempts and a one-second pause between them. Transient timeouts now recover automatically instead of surfacing to the customer.

Classify each statement

0/8 classified. Some statements are true — the point is telling which.

The retry budget has to fit inside whatever timeout the caller is enforcing.

Every error the provider returns is worth retrying.

The total time this function may take before giving up is not defined.

Whether the provider offers an idempotency key on charge determines the entire design.

A timeout on a request the provider actually processed results in the customer being charged more than once.

Every retry that recovers a sale also lengthens the worst-case response time the customer waits through.

Retrying a charge that failed because of a network timeout is the right response to a transient fault.

When the provider has a brief outage, every in-flight request retries at the same moment.