Skip to content

fix(billing): unblock on payment success for overage retries#4121

Merged
icecrasher321 merged 1 commit intostagingfrom
fix/billing-unblock
Apr 12, 2026
Merged

fix(billing): unblock on payment success for overage retries#4121
icecrasher321 merged 1 commit intostagingfrom
fix/billing-unblock

Conversation

@icecrasher321
Copy link
Copy Markdown
Collaborator

Summary

Divergence in block path (which works correctly) and unblock on payment success in the way they resolve subscription id. Unblock did not work on overage invoice retries success.

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
Copy link
Copy Markdown

vercel bot commented Apr 12, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 12, 2026 7:06pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 12, 2026

PR Summary

Medium Risk
Touches billing enforcement/unblocking logic triggered by Stripe webhooks; incorrect subscription resolution could leave users blocked/unblocked incorrectly, though changes are localized and now covered by tests.

Overview
Ensures invoice.payment_succeeded and invoice.payment_failed webhooks use a shared subscription-resolution path that can fall back to invoice.metadata.subscriptionId for metadata-backed overage/threshold invoices, with additional logging for missing/mismatched identifiers.

Adds targeted Vitest coverage verifying org member blocking on metadata-backed payment failures and unblocking on subsequent payment success.

Reviewed by Cursor Bugbot for commit 5aea045. Configure here.

@icecrasher321 icecrasher321 changed the title fix(billing): unblock on payment success fix(billing): unblock on payment success for overage retries Apr 12, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 12, 2026

Greptile Summary

This PR fixes a bug where handleInvoicePaymentSucceeded only resolved the Stripe subscription ID via parent.subscription_details.subscription, causing it to silently skip the unblock step for retried overage invoices (which store the subscription ID in metadata.subscriptionId instead). The fix extracts a shared resolveInvoiceSubscription helper that prefers the parent-link path and falls back to metadata for known overage invoice types, making both the block and unblock handlers consistent.

Confidence Score: 5/5

Safe to merge — the logic fix is correct and all remaining findings are P2 style/coverage suggestions.

The core bug fix is sound: resolveInvoiceSubscription correctly prefers the parent-subscription link and falls back to metadata for overage invoice types, making both handlers consistent. The only findings are a relative import in the test file (trivial style violation) and a missing test for the wasBlocked=true scenario. Neither affects runtime correctness.

apps/sim/lib/billing/webhooks/invoices.test.ts — relative import and limited coverage of the wasBlocked=true branch.

Important Files Changed

Filename Overview
apps/sim/lib/billing/webhooks/invoices.ts Introduces resolveInvoiceSubscription helper that unifies subscription-ID resolution (parent link first, metadata fallback for known overage types) across both payment-failed and payment-succeeded handlers, fixing the unblock regression on overage invoice retries.
apps/sim/lib/billing/webhooks/invoices.test.ts New test file covering overage invoice payment-failed and payment-succeeded flows; uses a relative import (rule violation) and the success-path test only exercises the wasBlocked=false branch, leaving the primary bug-fix scenario untested.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Stripe Invoice Event] --> B{invoice.metadata.type}
    B -->|credit_purchase| C[handleCreditPurchaseSuccess]
    B -->|other / overage types| D[resolveInvoiceSubscriptionContext]

    D --> E{parent.subscription_details.subscription present?}
    E -->|Yes| F[resolutionSource: parent link]
    E -->|No| G{metadata.type in METADATA_SUBSCRIPTION_INVOICE_TYPES?}
    G -->|Yes + metadata.subscriptionId set| H[resolutionSource: metadata]
    G -->|No| I[resolutionSource: none → skip]

    F --> J[DB lookup by stripeSubscriptionId]
    H --> J
    J -->|not found| K[log warn → skip]
    J -->|found| L[ResolvedInvoiceSubscription]

    L --> M{Event type}
    M -->|payment_succeeded| N[Check wasBlocked / Unblock if shouldUnblock / Reset usage if wasBlocked]
    M -->|payment_failed| O[Block org members or user / Send email on attempt 1]
Loading

Reviews (1): Last reviewed commit: "fix(billing): unblock on payment success" | Re-trigger Greptile

@icecrasher321 icecrasher321 merged commit 10341ae into staging Apr 12, 2026
12 checks passed
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