First contribution
Recommended for a stated reason, with the context needed to ship it. Onboard never opens a pull request on your behalf.
OrbitPay demo data. Connect your sources to generate this from your own repositories, Slack, and Linear.
scheduleRetry can enqueue the same (intentId, attemptCount) pair twice when two workers pick up the same attempt. Add a dedupe guard in the scheduler and log the scheduling decision so reconciliation can see it.
Why this issue
Duplicate retry scheduling is invisible until the ledger drifts the next morning, and reconciling drift is manual work for the one engineer who understands it. Closing this removes a recurring source of both duplicate processor fees and single-owner toil.
Architecture recap
scheduleRetry writes (intentId, attemptCount) into a Redis sorted set keyed by due time. Workers poll for due members. Because the poll and the write are not atomic, two workers can pick up the same attempt and each schedule the next one.
src/retry/retryQueue.ts
scheduleRetry is where the dedupe guard belongs. Note the existing NOTE comment pointing at PAY-247.
src/ledger/reconcile.ts
Add the scheduling decision to the reconciliation log so a duplicate is visible in the trail, not just in the ledger.
Known edge cases
The closest precedent in this repository, and a good model for how the reviewer expects this kind of change to be tested.
The PAY-184 fix. Same file, same review path, and a good model for how Dev expects retry changes to be tested.
Related discussion
#payments · Why the worker owns retries
Dev Shah: We deliberately kept retries out of checkout-api. If the API retried inline, a degraded processor would eat our request pool and take the whole storefront down with it. The worker can back off for minutes without anyone noticing.
#payments · Reconciliation logs are unreadable
Lucas Moreau: Every reconciliation run logs one line per attempt with no scheduling context. When a retry gets scheduled twice you cannot tell from the logs, only from the ledger drift the next morning.
A manager can replace the recommendation with one of these.
Add unique constraint on payment_attempts
Settlement table pagination in merchant-dashboard