Schedule stablecoin payouts after Stripe available_on#3564
Schedule stablecoin payouts after Stripe available_on#3564
available_on#3564Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughIntroduces conditional stablecoin payout scheduling: a new utility inspects Stripe balance transactions and either executes funding immediately or schedules a delayed retry via Qstash; a skip flag is threaded into payout queuing to optionally exclude stablecoin payouts, and Qstash flowControl is added to webhook publishing. Changes
Sequence Diagram(s)sequenceDiagram
participant Route as Route<br/>(charge-succeeded)
participant Utils as scheduleDelayed<br/>StablecoinPayouts
participant Stripe as Stripe API
participant Qstash as Qstash
participant Queue as queueStripePayouts
Route->>Utils: check invoice.stripeChargeMetadata
Utils->>Stripe: fetch balance transactions by charge
Stripe-->>Utils: balance transaction(s)
alt available_on <= now
Utils-->>Route: nextAction: "executeNow"
Route->>Stripe: fund financial account
Stripe-->>Route: funding result
Route->>Queue: queueStripePayouts(invoice, skip=false)
else available_on > now
Utils->>Qstash: schedule callback (15 min after available_on)
Qstash-->>Utils: messageId
Utils-->>Route: nextAction: "skip"
Route->>Queue: queueStripePayouts(invoice, skip=true)
else no transaction
Utils-->>Route: nextAction: "skip"
Route->>Queue: queueStripePayouts(invoice, skip=true)
end
Queue->>Queue: filter payout methods (exclude stablecoin if skip=true)
Queue-->>Route: queued partner payouts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/app/`(ee)/api/cron/payouts/charge-succeeded/route.ts:
- Around line 90-106: When nextAction === "executeNow" and the call to
fundFinancialAccount({ amount: stablecoinFundingAmount, idempotencyKey:
invoiceId }) fails, the catch only logs the error but does not prevent
subsequent stablecoin payout queuing; update the catch block to also set
skipStablecoinPayouts = true (in addition to calling log) so that downstream
logic that uses skipStablecoinPayouts will skip enqueuing stablecoin payouts
when fundFinancialAccount throws.
In `@apps/web/app/`(ee)/api/cron/payouts/charge-succeeded/utils.ts:
- Around line 14-16: Update the mismatched comment so it reflects the
implemented 15-minute delay for stablecoin payouts: change the text that
currently reads "`available_on + 10 minutes`" to "`available_on + 15 minutes`"
to match the calculation using `15 * 60 * 1000` (used for stablecoin payouts /
cron scheduling).
- Around line 72-85: The function currently returns { nextAction: "skip" }
silently when qstashResponse.messageId is falsy; update it to log an error that
includes qstashResponse and scheduleTimeMs for debugging. Specifically, where
qstashResponse is checked, add a console.error or processLogger.error call when
qstashResponse.messageId is falsy that includes a clear message ("Qstash
scheduling failed"), the entire qstashResponse object and scheduleTimeMs (or its
derived scheduledAt ISO string), then still return { nextAction: "skip" } so
callers behave the same but failures are visible.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 11c4f841-664c-48f8-a2be-07802c78b27d
📒 Files selected for processing (4)
apps/web/app/(ee)/api/cron/payouts/charge-succeeded/queue-stripe-payouts.tsapps/web/app/(ee)/api/cron/payouts/charge-succeeded/route.tsapps/web/app/(ee)/api/cron/payouts/charge-succeeded/utils.tsapps/web/app/(ee)/api/stripe/webhook/charge-succeeded.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/app/`(ee)/api/cron/payouts/charge-succeeded/route.ts:
- Around line 91-103: The catch block around the fundFinancialAccount call
swallows errors and sets skipStablecoinPayouts, preventing QStash from retrying;
update the catch in the route handling the charge-succeeded cron (the try/catch
that calls fundFinancialAccount with idempotencyKey: invoiceId) to log the error
via log(...) and then rethrow the original error (or explicitly enqueue a QStash
retry) instead of setting skipStablecoinPayouts to true so QStash's native retry
mechanism can handle the failure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 973d9116-9e1b-4c39-8c05-cf64e8f08a0f
📒 Files selected for processing (2)
apps/web/app/(ee)/api/cron/payouts/charge-succeeded/route.tsapps/web/app/(ee)/api/cron/payouts/charge-succeeded/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/app/(ee)/api/cron/payouts/charge-succeeded/utils.ts
| try { | ||
| await fundFinancialAccount({ | ||
| amount: stablecoinFundingAmount, | ||
| idempotencyKey: invoiceId, | ||
| }); | ||
| } catch (error) { | ||
| await log({ | ||
| message: `Failed to fund Dub's financial account for stablecoin payouts: ${error.message}`, | ||
| type: "errors", | ||
| }); | ||
|
|
||
| skipStablecoinPayouts = true; | ||
| } |
There was a problem hiding this comment.
Preserve QStash retries when funding fails.
This catch turns an executeNow funding failure into a successful cron run, so the stablecoin payouts stay in processing with no retry path. Either rethrow after logging or explicitly enqueue a retry before continuing.
🐛 Minimal fix
if (nextAction === "executeNow") {
try {
await fundFinancialAccount({
amount: stablecoinFundingAmount,
idempotencyKey: invoiceId,
});
} catch (error) {
await log({
message: `Failed to fund Dub's financial account for stablecoin payouts: ${error.message}`,
type: "errors",
});
-
- skipStablecoinPayouts = true;
+ throw error;
}
}Based on learnings, cron endpoints under apps/web/app/(ee)/api/cron should allow QStash to retry cron errors via its native retry mechanism rather than swallowing them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/app/`(ee)/api/cron/payouts/charge-succeeded/route.ts around lines 91
- 103, The catch block around the fundFinancialAccount call swallows errors and
sets skipStablecoinPayouts, preventing QStash from retrying; update the catch in
the route handling the charge-succeeded cron (the try/catch that calls
fundFinancialAccount with idempotencyKey: invoiceId) to log the error via
log(...) and then rethrow the original error (or explicitly enqueue a QStash
retry) instead of setting skipStablecoinPayouts to true so QStash's native retry
mechanism can handle the failure.
Summary by CodeRabbit