Skip to content

fix(subscription): make billing account teardown retryable - #1844

Open
whoAbhishekSah wants to merge 1 commit into
fix/kyc-delete-methodfrom
fix/subscription-teardown-retry
Open

fix(subscription): make billing account teardown retryable#1844
whoAbhishekSah wants to merge 1 commit into
fix/kyc-delete-methodfrom
fix/subscription-teardown-retry

Conversation

@whoAbhishekSah

Copy link
Copy Markdown
Member

Part of #1835. Stacked on the kyc delete PR.

DeleteByCustomer failed and could not be run again when the provider side was already gone. That mattered for org delete: after a halfway failure, the Stripe customer was deleted but local rows remained, and every retry died on the first provider call.

Changes

  • A subscription already canceled on the provider now just syncs the local state instead of failing the cancel call.
  • A subscription missing on the provider counts as canceled.
  • Offline accounts skip the provider entirely; only local records are removed.
  • Dropped the SyncWithProvider call, which failed outright when the provider customer was already deleted.

🤖 Generated with Claude Code

DeleteByCustomer failed and could not be run again when the provider
side was already gone:

- a subscription already canceled on the provider now just syncs the
  local state instead of failing the cancel call
- a subscription missing on the provider counts as canceled
- offline accounts skip the provider entirely; only local records go
- drop the SyncWithProvider call, which failed outright when the
  provider customer was already deleted

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview Aug 4, 2026 7:29am

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7fb076a5-c4bb-4402-863d-e8b51fb4b619

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rohilsurana rohilsurana left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The teardown logic checks out: the early return syncs local state when the provider already canceled, and dropping SyncWithProvider is safe because deleting the Stripe customer later cancels anything still live on the provider. One edge case inline.

Also, no tests cover the new Cancel branch, which is the one piece of real logic in this stack. The concrete Stripe client makes unit tests hard here, so a short note in the PR on how this was verified against Stripe test mode would help.

return sub, err
}

if stripeSubscription != nil && stripeSubscription.Status == stripe.SubscriptionStatusCanceled {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createOrGetSchedule also returns a nil schedule for incomplete and incomplete_expired statuses. Those fall through to Subscriptions.Cancel below. Stripe rejects a cancel of an incomplete_expired subscription, and that error is not ErrSubscriptionOnProviderNotFound, so DeleteByCustomer would stop there. It needs local state to say active while the provider says expired, so it is rare, but treating those statuses like canceled here would close the gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants