-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Skip the invoice failure fee for failed ACH payments that are blocked #2976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughModifies payout invoice failure processing to skip charging failure fees and recording card details when a direct_debit charge outcome type is "blocked"; retains existing fee charging flow for non-blocked direct_debit charges. Changes
Sequence Diagram(s)sequenceDiagram
participant Webhook as Stripe Webhook
participant Processor as processPayoutInvoiceFailure
participant Stripe as Stripe API
participant DB as Database/Logger
Webhook->>Processor: payload (payout invoice failure)
Processor->>Processor: extract charge, paymentMethod
alt charge.outcome.type == "blocked"
Processor->>DB: log "skipped fee for blocked charge"
else not blocked
Processor->>Stripe: create PaymentIntent (failure fee)
Stripe-->>Processor: PaymentIntent result
alt success
Processor->>DB: set chargedFailureFee = true
Processor->>DB: record cardLast4 (if present)
Processor->>DB: log "charged failure fee"
else failure
Processor->>DB: log "failure charging fee"
end
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (1)
88-106: LGTM! Logic correctly skips failure fee for blocked charges.The conditional block correctly implements the PR objective by preventing failure fee charges for blocked direct debit payments. The placement of
cardLast4andchargedFailureFeeassignments maintains consistency with the email data structure.Consider adding a log statement when skipping the fee for better observability:
if (!isBlocked) { const { paymentIntent, paymentMethod } = await createPaymentIntent({ stripeId: workspace.stripeId, amount: PAYOUT_FAILURE_FEE_CENTS, description: `Dub Partners payout failure fee for invoice ${invoice.id}`, statementDescriptor: "Dub Partners", }); if (paymentIntent) { chargedFailureFee = true; console.log( `Charged a failure fee of $${PAYOUT_FAILURE_FEE_CENTS / 100} to ${workspace.slug}.`, ); } if (paymentMethod?.card) { cardLast4 = paymentMethod.card.last4; } + } else { + console.log( + `Skipped charging failure fee for blocked direct debit charge on invoice ${invoice.id}.`, + ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (2)
apps/web/lib/stripe/create-payment-intent.ts (1)
createPaymentIntent(4-76)apps/web/lib/partners/constants.ts (1)
PAYOUT_FAILURE_FEE_CENTS(9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (1)
84-86: LGTM! Safe handling of blocked charges.The optional chaining correctly handles cases where
chargeoroutcomemight be undefined, and "blocked" is a valid Stripe charge outcome type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (1)
106-110: Consider using thelog()utility for consistency.The
console.loghere is informational and appropriate, but for consistency with line 21 and better observability across the system, consider using thelog()utility:- } else { - console.log( - `Skipped charging failure fee for blocked direct debit charge on invoice ${invoice.id}.`, - ); - } + } else { + await log({ + message: `Skipped charging failure fee for blocked direct debit charge on invoice ${invoice.id}.`, + type: "info", + }); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (2)
apps/web/lib/stripe/create-payment-intent.ts (1)
createPaymentIntent(4-76)apps/web/lib/partners/constants.ts (1)
PAYOUT_FAILURE_FEE_CENTS(9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts (2)
88-105: LGTM! Fee charging logic is correct.The conditional charging of the failure fee when
!isBlockedis appropriate, and the error handling correctly leaveschargedFailureFeeasfalseif the payment intent creation fails. ThecardLast4assignment captures the backup payment method used for the fee, not the original direct debit method.
84-86: Verify that charging fees whencharge.outcomeis undefined is intentional.Stripe's charge.outcome field is not guaranteed to be present — it's nullable or omitted for non-card payments, older charges, or when risk evaluation doesn't apply. When
charge.outcomeisundefined, the lineconst isBlocked = charge?.outcome?.type === "blocked"evaluates tofalse, and the failure fee is charged. Confirm this is the intended behavior or add explicit handling (e.g., skip fee or log warning) for missing outcome data.
…m failure fee
Summary by CodeRabbit