Cancel Stripe billing when deleting an account - #1093
Conversation
📝 WalkthroughWalkthroughAccount deletion now inventories Stripe customer IDs, cancels active or trialing subscriptions, deletes Stripe customers, and then removes database data. Stripe failures generate warnings and structured logs without blocking database deletion. Stripe APIs validate DELETE responses and redact resource IDs in logs. ChangesStripe account deletion
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant AccountDeletion
participant StripeClient
participant StripeAPI
participant D1
AccountDeletion->>StripeClient: List customer subscriptions
StripeClient->>StripeAPI: GET subscriptions
StripeAPI-->>StripeClient: Return subscriptions
AccountDeletion->>StripeClient: Cancel active or trialing subscriptions
StripeClient->>StripeAPI: DELETE subscriptions
AccountDeletion->>StripeClient: Delete Stripe customer
StripeClient->>StripeAPI: DELETE customer
AccountDeletion->>D1: Delete account data
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
|
🔎 Preview deployed: https://kody-pr-1093.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/worker/src/billing/stripe-client.ts (1)
141-146: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAdd error-path test coverage for subscription/customer id redaction.
The redaction regex now also covers
customers/...andsubscriptions/...paths, not justcheckout/sessions/.... The added test (stripe-client.node.test.tslines 208-234) only covers the success path. Add a test that forces a non-2xx or invalid-JSON response forcancelSubscriptionordeleteCustomerand asserts thatconsole.errorreceives the redacted path, not the raw subscription or customer id.🤖 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 `@packages/worker/src/billing/stripe-client.ts` around lines 141 - 146, Add error-path coverage in stripe-client.node.test.ts for cancelSubscription or deleteCustomer by forcing a non-2xx or invalid-JSON response, spy on console.error, and assert the logged endpoint contains the redacted customers/subscriptions path while excluding the raw identifier.
🤖 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 `@packages/worker/src/billing/stripe-client.ts`:
- Around line 141-146: Add error-path coverage in stripe-client.node.test.ts for
cancelSubscription or deleteCustomer by forcing a non-2xx or invalid-JSON
response, spy on console.error, and assert the logged endpoint contains the
redacted customers/subscriptions path while excluding the raw identifier.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: cb53e22e-c6d1-4c7d-982c-e1401496fdfc
📒 Files selected for processing (4)
packages/worker/src/app/account-deletion.node.test.tspackages/worker/src/app/account-deletion.tspackages/worker/src/billing/stripe-client.node.test.tspackages/worker/src/billing/stripe-client.ts
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a604b6c. Configure here.
| }) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Stripe runs before D1 commit
High Severity
cancelSubscriptionsAndDeleteStripeCustomer runs before deleteUserScopedRowsAndUser. If Stripe customer deletion succeeds but the atomic D1 batch fails, the Kody user row (and stripe_customer_id) remain while the Stripe customer is already gone—billing is torn down but the account is not, often still marked deleting.
Reviewed by Cursor Bugbot for commit a604b6c. Configure here.
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
a604b6c to
81ed1c4
Compare


Part of #1069
Summary
Verification
npm run validategreen locally (1,712 unit tests and 19 Playwright tests passed)System recap — extends existing primitives (medium risk)
Mode: recap · Base:
main@ffc26e41· Head:81ed1c4bClassification: extends — account deletion now coordinates immediate Stripe subscription and customer cleanup while preserving deletion availability.
Primitives touched
app-uibillingSystem map
Account deletion flows from the authenticated app deletion orchestrator through Stripe billing cleanup before the user row is removed.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
Invariants
Conductor report
bfe039aaand successfully deployed to production.Summary by CodeRabbit