Skip to content

fix(billing): acknowledge Stripe webhooks whose subscription references a missing organization - #8809

Merged
waleedlatif1 merged 3 commits into
stagingfrom
fix/enterprise-webhook-missing-org
Oct 8, 2026
Merged

waleedlatif1 merged 3 commits into
stagingfrom
fix/enterprise-webhook-missing-org

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • An Enterprise subscription whose referenced organization no longer exists made every customer.subscription.updated/created webhook return 400: the Enterprise reconcile threw "Enterprise organization not found", and the usage-limit step after it threw for the same reference. Stripe retried for ~3 days and then dropped the event; a retry can never succeed because a deleted organization does not come back
  • The Enterprise reconcile now returns an organization-missing outcome from its locked transaction (before any write) and the handler logs it at error level with the Stripe subscription, customer, reference, event type and status, then acknowledges. Every transient case — issuance not yet matching Stripe, lease/lock, DB errors, seat/entitlement conflicts — still throws so Stripe retries. Organizations are always committed before their Stripe subscription is created, so "missing" is never "not yet"
  • New typed SubscriptionReferenceNotFoundError (reference is neither an organization nor a user): syncSubscriptionUsageLimits throws it and handleSubscriptionUsageUpdate acknowledges only that type; other errors still fail the webhook
  • ensureOrganizationForTeamSubscription treated a reference that is not an organization as a user id, so a dangling organization id tried to create a new organization owned by that id (failing on the member foreign key every time). It now checks the user exists first and throws the typed error; onSubscriptionUpdate logs it and returns

Type of Change

  • Bug fix

Testing

  • New lib/billing/webhooks/enterprise-missing-organization.integration.ts (real Postgres, the real Better Auth Stripe plugin over HTTP, in-memory Stripe): renewal for a row with a missing organization returns 200 and still records the Stripe period; no organization/member is created for the dangling reference; a dashboard-created subscription naming a missing organization is acknowledged and records nothing; an issuance Stripe hasn't caught up with still fails the webhook (guard against over-acknowledging). The first three fail on the previous code; each fix reverted alone turns its test red
  • All lib/billing integration suites, root bun run test, bun run lint, bun run type-check, bun run check:audits, bun run docs-manifest:check, block-registry check

Checklist

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

…es a missing organization instead of retrying for days
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 8, 2026 8:18pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/lib/auth/auth.ts Outdated
Comment thread apps/sim/lib/billing/webhooks/enterprise.ts
Comment thread apps/sim/lib/billing/webhooks/enterprise-missing-organization.integration.ts Outdated
@greptile-apps

greptile-apps Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Critical impact] The PR appears safe to merge; no new actionable issue was found.

Summary

This PR acknowledges Stripe subscription events that reference a missing organization instead of retrying them indefinitely.

  • Enterprise reconciliation logs the missing organization and skips its writes.
  • Usage-limit sync skips only SubscriptionReferenceNotFoundError; other errors still escape.
  • Organization creation rejects references that match neither an organization nor a user.
  • Integration tests cover missing references and retrying an unfinished Enterprise issuance.
  • The latest change clears the mock’s old price amount when its price ID changes.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Stripe subscription event] --> B[Enterprise reconciliation]
  B --> C{Organization exists?}
  C -->|No| D[Log and skip Enterprise writes]
  C -->|Yes| E[Reconcile subscription]
  D --> F[Continue remaining event steps]
  E --> F
  F --> G{Usage reference exists?}
  G -->|No| H[Log and skip usage sync]
  G -->|Yes| I[Sync usage limits]
  H --> J[Acknowledge event]
  I --> J
  B -->|Other error| K[Fail event for retry]
  F -->|Other error| K
Loading

Reviews (3) · Last reviewed commit: "test(testing): a swapped price in the St..." · Reviewed by Greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread packages/testing/src/mocks/stripe.mock.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit 325ab96 into staging Oct 8, 2026
37 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/enterprise-webhook-missing-org branch October 8, 2026 20:24

This branch was previously deployed

1 inactive deployment
Preview — bc666fe6 Deployed Oct 8, 2026 by vercel[bot]
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