refactor(billing): unify add-credits and coupon on the shared tabbed sheet - #3412
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe billing flow replaces ChangesCredits purchase flow
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
32aa590 to
b28e26c
Compare
5349bca to
eb3535a
Compare
…sheet Billing's AccountOverview now opens the shared AddCreditsSheet (Buy Credit + Apply Coupon tabs) instead of the legacy PaymentPopup modal, which is deleted along with its duplicated charge/coupon logic. - AddCreditsForm offers saved payment methods (default pre-selected) with new-card entry as fallback or explicit choice; the SetupIntent is created lazily only in new-card mode; the first-purchase match banner is gated on isTrialing - AddCreditsSheet header description is now a prop (defaults to the free-plan copy) so billing can show neutral copy - The billing Add Funds button no longer requires a saved payment method; the ?openPayment=true deep link and the purchase confetti are preserved - E2E BillingPage.submitPayment drives the sheet via the custom amount field Refs CON-639
b28e26c to
075df0b
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3412 +/- ##
==========================================
+ Coverage 72.20% 72.27% +0.07%
==========================================
Files 1158 1157 -1
Lines 29367 29299 -68
Branches 7253 7245 -8
==========================================
- Hits 21205 21177 -28
+ Misses 7172 7134 -38
+ Partials 990 988 -2
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx (1)
93-93: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winNo error state for the payment-methods query.
Only
data/isLoadingare destructured fromusePaymentMethodsQuery(); a fetch failure silently falls back to the new-card flow with no indication to the user that their saved cards failed to load. Consider surfacingisErrorso users understand why their saved methods vanished rather than assuming they have none.As per path instructions, "Focus on: ... missing loading/error states in data fetching" for
apps/{deploy-web,stats-web,provider-console}/**/*.{ts,tsx}.Also applies to: 267-288
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx` at line 93, Update AddCreditsForm’s usePaymentMethodsQuery handling to include its error state and surface a clear user-facing indication when saved payment methods fail to load, rather than silently using the new-card flow. Preserve the existing loading and successful payment-method rendering behavior.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx`:
- Line 93: Update AddCreditsForm’s usePaymentMethodsQuery handling to include
its error state and surface a clear user-facing indication when saved payment
methods fail to load, rather than silently using the new-card flow. Preserve the
existing loading and successful payment-method rendering behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 309ecc10-9604-4785-9b07-926858fee1f5
📒 Files selected for processing (9)
apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsxapps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsxapps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.spec.tsxapps/deploy-web/src/components/billing-usage/AccountOverview/AccountOverview.tsxapps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsxapps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsxapps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsxapps/deploy-web/tests/ui/pages/BillingPage.ts
💤 Files with no reviewable changes (2)
- apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.spec.tsx
- apps/deploy-web/src/components/billing-usage/PaymentPopup/PaymentPopup.tsx
… card on retry - lower the trial top-up minimum default to $20 (free trial changed) - drive the add-credits minimum from the wallet's topUpMinAmountUsd instead of a hardcoded 20 and show an inline error below the amount field - confirm a new card's SetupIntent only once: retries after a failed charge reuse the saved payment method instead of re-confirming the consumed intent (Stripe 400), surface the saved card in the methods list, and mint a fresh SetupIntent when a different new card is requested Fixes CON-654
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx`:
- Around line 76-80: Update the number input in AddCreditsAmountFields to define
an explicit fractional-compatible step, such as 0.01, alongside min={minAmount},
so values at or above fractional MANAGED_WALLET_TRIAL_MIN_TOP_UP_AMOUNT pass
native validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ab44f130-1235-4906-81c4-4a12060cb4f7
📒 Files selected for processing (5)
apps/api/src/billing/config/env.config.tsapps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsxapps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsxapps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsxapps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx
- apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
…s load failure - set step=0.01 on the custom-amount input so a fractional wallet minimum does not fail native step validation - show a notice when the saved payment methods query errors instead of silently falling back to new-card entry
Why
Closes CON-639
CON-368 introduced the redesigned tabbed "Add credits" sheet (Buy Credit + Apply Coupon) but only wired it into onboarding and the hackathon sidebar. The billing section still opened the legacy
PaymentPopupmodal with its own parallel purchase and coupon-redemption logic: two implementations of the same behavior that drift and double maintenance cost.What
The sheet itself landed in #3403 and its onboarding/hackathon entry points in #3404 (both merged). This PR completes the migration by moving billing onto the shared sheet and deleting the legacy popup.
AccountOverviewnow renders the sharedAddCreditsSheetinstead ofPaymentPopup. The?openPayment=truedeep link and the purchase confetti (PaymentSuccessAnimation) are preserved. The "Add Funds" button no longer requires a saved payment method (the sheet's new-card entry handles that case in place).AddCreditsFormgains always-on saved-payment-method support: saved methods are offered in a select (default card pre-selected) with "Add new payment method" as an explicit choice; the Stripe SetupIntent is created lazily only in new-card mode; the "First-purchase match" banner is gated onisTrialing. Onboarding is unchanged, since a trialing user has no saved methods and falls through to the exact current new-card path.AddCreditsSheetheader description is now a prop (defaults to the free-plan copy) so billing shows neutral copy instead of "You're on the free plan…".PaymentPopup.tsx(+ spec, ~1500 lines), removing the duplicated charge/coupon logic. Coupon redemption now uses the shared tab's inline feedback (no confetti on coupon, an intentional change from legacy).BillingPage.submitPaymentdrives the sheet via the custom-amount field, covering both callers ("100"credits spec,"20"deposit flow). The"Payment Successful!"assertion still holds since purchase confetti is retained.Billing stays gated behind
auto_credit_reload; onboarding's coupon entry stays behindhackathons(unchanged).Note: the deploy-web E2E suite (
managed-wallet-credits) requires deployed-env credentials (env/.env.test) not available locally; needs a CI/release run to confirm.Also in this PR: minimum-amount validation + new-card retry fix
Fixes CON-654
MANAGED_WALLET_TRIAL_MIN_TOP_UP_AMOUNT, was $100): the free trial changed and the higher first-purchase minimum no longer applies. Ops note: any environment that sets this variable explicitly in Doppler overrides the code default; update/remove it there for the $20 minimum to take effect.topUpMinAmountUsdinstead of a hardcoded 20, and a below-minimum amount shows an inline "Minimum amount is $X" error under the amount field instead of only silently disabling the purchase button.confirmSetup; if the charge then fails (decline, 402), resubmitting re-confirmed the consumed intent. The form now confirms a new card once and reuses the saved payment method on retry, surfaces the saved card in the methods select after a failure, and creates a fresh SetupIntent when "Add new payment method" is picked again.Summary by CodeRabbit