Skip to content

fix(billing): checkout guard, admin panel case - #6641

Merged
icecrasher321 merged 3 commits into
stagingfrom
fix/billing-checkout-guard
Aug 12, 2026
Merged

fix(billing): checkout guard, admin panel case#6641
icecrasher321 merged 3 commits into
stagingfrom
fix/billing-checkout-guard

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

Prevent Stripe webhooks from rebinding an existing local row to a different Stripe subscription.
Block duplicate checkouts while a bound incomplete payment is pending, while keeping abandoned checkouts retryable.
Sweep an Enterprise owner’s eligible personal workspaces into the new organization, including free users.
Improve subscription/reference mismatch errors for easier diagnosis.

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 12, 2026 10:12pm

Request Review

@cursor

cursor Bot commented Aug 12, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes touch billing checkout, authorization, Stripe webhook adapter writes, and enterprise org provisioning—areas where races or incorrect guards can block revenue or corrupt subscription binding.

Overview
Checkout admission adds a short-lived database lease per billing reference on /subscription/upgrade, claimed in auth before hooks and released in after, so overlapping checkouts cannot race past read-only checks. Personal and org flows still run existing coverage rules; failures release the claim and surface user-facing errors (including in the upgrade UI toast test).

Pending payment guard blocks a new checkout when the reference already has an incomplete subscription bound to a Stripe subscription ID, while leaving unbound abandoned placeholders retryable. This applies to personal checkouts and org upgrade-subscription authorization.

Stripe adapter guard now refuses updates that rebind an existing local subscription row to a different stripeSubscriptionId (webhook path), while still allowing first-time binding and same-ID status updates.

Enterprise provisioning on correlated issuance sweeps the owner’s attachable personal workspaces into the new org (with locks, identity lock, stable workspace-set check, cache invalidation), and retries if the workspace set changes mid-reconciliation.

Diagnostics: subscription/reference mismatch errors mention the bound reference explicitly.

Reviewed by Cursor Bugbot for commit 89877b4. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds database-backed checkout admission fencing and bound-incomplete-subscription checks, while tightening Stripe subscription binding and Enterprise workspace reconciliation.

  • Serializes overlapping checkout creation by resolved billing reference and releases claims using ownership tokens.
  • Keeps abandoned, unbound checkout placeholders retryable while blocking checkouts whose Stripe payment remains incomplete.
  • Prevents webhook updates from rebinding an existing local row to another Stripe subscription.
  • Moves eligible Enterprise-owner workspaces into the newly provisioned organization under transactional locks.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported concurrent checkout race is addressed by an atomic database claim keyed by billing reference, with claim-token-fenced release preventing stale requests from releasing newer claims.

Important Files Changed

Filename Overview
apps/sim/lib/auth/auth.ts Wraps subscription upgrades in a database-backed checkout-admission claim spanning authorization and Stripe Checkout creation.
apps/sim/lib/billing/checkout-admission.ts Adds reference resolution and short-lived, token-fenced database leases that serialize checkout creation.
apps/sim/lib/billing/authorization.ts Rejects personal and organization checkouts while a bound incomplete Stripe subscription remains pending.
apps/sim/lib/auth/stripe-adapter-guard.ts Prevents existing local subscription rows from being rebound to a different Stripe subscription ID.
apps/sim/lib/billing/webhooks/enterprise.ts Reconciles eligible Enterprise-owner workspaces into the organization under workspace, organization, and billing-identity locks.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Auth as Better Auth hooks
  participant Lease as Checkout admission DB
  participant Stripe as Stripe plugin
  participant DB as Subscription DB

  Client->>Auth: POST /subscription/upgrade
  Auth->>Lease: Atomically claim billing reference
  alt Claim already held
    Lease-->>Auth: Conflict
    Auth-->>Client: Checkout already starting
  else Claim acquired
    Auth->>DB: Check bound incomplete subscription
    Auth->>Stripe: Prepare local row and create Checkout
    Stripe-->>Auth: Checkout result
    Auth->>Lease: Release with fencing token
    Auth-->>Client: Checkout response
  end
Loading

Reviews (3): Last reviewed commit: "fix(billing): release checkout admission..." | Re-trigger Greptile

Comment thread apps/sim/lib/billing/authorization.ts
Comment thread apps/sim/lib/auth/stripe-adapter-guard.ts
@icecrasher321
icecrasher321 force-pushed the fix/billing-checkout-guard branch from cad7f04 to 485d1ab Compare August 12, 2026 21:17
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/auth/auth.ts
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 89877b4. Configure here.

@icecrasher321
icecrasher321 merged commit 9f8d4d1 into staging Aug 12, 2026
30 checks passed
@icecrasher321
icecrasher321 deleted the fix/billing-checkout-guard branch August 12, 2026 22:33
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.

1 participant