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: unknown3 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 = err13 await sleep(1000)14 }15 }16 17 throw lastError18}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.