OptionaljitterAdds 0–25% random jitter to each delay (default true) to avoid thundering herds.
OptionalmaxBackoff ceiling in ms (default 5000) — a hard cap, jitter included.
OptionalminFirst backoff delay in ms (default 200). Doubles per attempt.
OptionalonObservability: called before each backoff sleep.
OptionalrandomTest seam for jitter; defaults to Math.random.
OptionalretriesAdditional attempts after the first (default 2 → at most 3 calls).
OptionalshouldWhich errors to retry. Default: isPayFanoutError(err) && err.retryable.
OptionalsignalCancels waiting: an aborted signal stops before the next attempt and rejects with the signal's reason (the in-flight attempt itself is the caller's to abort — thread the same signal into it).
OptionalsleepTest seam; defaults to a real setTimeout sleep.
Backoff machinery for the
PayFanoutError.retryableflag. Every mutating PayFanout call requires an idempotency key, so retrying a transient failure (PSP down, rate limited, network timeout) can never double-charge — this helper is the missing piece that turns the flag into behavior:const info = await withRetry(() => payments.capturePayment("stripe", id, amt, key));
Retries only errors the default predicate accepts (PayFanoutError with retryable: true). Anything else — business rejections, declines, bugs — rethrows immediately.