Skip to content

fix(billing-blocked): block platform usage if payment fails for regular subs as well#1541

Merged
icecrasher321 merged 1 commit intostagingfrom
fix/billing-blocked-fix
Oct 3, 2025
Merged

fix(billing-blocked): block platform usage if payment fails for regular subs as well#1541
icecrasher321 merged 1 commit intostagingfrom
fix/billing-blocked-fix

Conversation

@icecrasher321
Copy link
Collaborator

Summary

Regular subscription payment failures were not being handled. This fixes that.

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

vercel bot commented Oct 3, 2025

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

Project Deployment Preview Comments Updated (UTC)
sim Ready Ready Preview Comment Oct 3, 2025 7:11pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
docs Skipped Skipped Oct 3, 2025 7:11pm

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

This PR fixes a billing enforcement gap by extending invoice payment failure handling to include regular subscription renewals. Previously, the webhook handler in `apps/sim/lib/billing/webhooks/invoices.ts` only processed overage billing invoice failures, allowing users to continue using the platform when their base subscription payments failed.

The change modifies the invoice payment failure logic to handle both invoice types by:

  1. Removing the early return: The original code had an early return for non-overage invoices (invoice.metadata?.type !== 'overage_billing'), which prevented processing of regular subscription failures
  2. Adding invoice type detection: New logic differentiates between overage and regular subscription invoices
  3. Implementing flexible subscription ID extraction: Overage invoices store the subscription ID in metadata, while regular subscription invoices store it in parent.subscription_details
  4. Applying consistent blocking logic: The same user blocking mechanism (blocking after attemptCount >= 1) now applies to all invoice payment failures

This ensures that users are blocked from platform usage when any payment fails, whether it's a base subscription renewal or an overage charge, maintaining consistent billing enforcement across the application's subscription model.

Changed Files
Filename Score Overview
apps/sim/lib/billing/webhooks/invoices.ts 4/5 Extended invoice payment failure handling to process both regular subscription and overage billing invoice failures, ensuring consistent platform usage blocking

Confidence score: 4/5

  • This PR addresses a clear billing enforcement gap with focused changes that improve system consistency
  • Score reflects solid logic with proper type handling, though the manual testing approach and webhook complexity warrant careful review
  • Pay close attention to the subscription ID extraction logic for different invoice types and ensure Stripe webhook testing covers both scenarios

Sequence Diagram

sequenceDiagram
    participant Stripe
    participant WebhookHandler as "Invoice Webhook Handler"
    participant DB as "Database"
    participant Logger

    Note over Stripe,Logger: Invoice Payment Failed Flow

    Stripe->>WebhookHandler: "invoice.payment_failed event"
    WebhookHandler->>Logger: "Log payment failure details"
    
    alt Overage Invoice
        WebhookHandler->>WebhookHandler: "Extract subscription ID from metadata"
    else Regular Subscription Invoice
        WebhookHandler->>WebhookHandler: "Extract subscription ID from parent.subscription_details"
    end
    
    alt No subscription ID found
        WebhookHandler->>Logger: "Log: No subscription found, skipping"
        WebhookHandler-->>Stripe: "Return early"
    end
    
    WebhookHandler->>Logger: "Warn: Invoice payment failed with details"
    
    alt Attempt count >= 1
        WebhookHandler->>Logger: "Error: Payment failure - blocking users"
        WebhookHandler->>DB: "SELECT subscription by stripeSubscriptionId"
        
        alt Team/Enterprise Plan
            WebhookHandler->>DB: "SELECT members by organizationId"
            loop For each member
                WebhookHandler->>DB: "UPDATE userStats SET billingBlocked = true"
            end
            WebhookHandler->>Logger: "Info: Blocked team/enterprise members"
        else Individual Plan
            WebhookHandler->>DB: "UPDATE userStats SET billingBlocked = true"
            WebhookHandler->>Logger: "Info: Blocked user"
        end
        
        alt Subscription not found
            WebhookHandler->>Logger: "Warn: Subscription not found in database"
        end
    end
    
    Note over Stripe,Logger: Invoice Payment Succeeded Flow
    
    Stripe->>WebhookHandler: "invoice.payment_succeeded event"
    WebhookHandler->>DB: "SELECT subscription by stripeSubscriptionId"
    
    alt No subscription found
        WebhookHandler-->>Stripe: "Return early"
    end
    
    alt Team/Enterprise Plan
        WebhookHandler->>DB: "SELECT members by organizationId"
        loop Check if any member was blocked
            WebhookHandler->>DB: "SELECT billingBlocked from userStats"
        end
        loop For each member
            WebhookHandler->>DB: "UPDATE userStats SET billingBlocked = false"
        end
    else Individual Plan
        WebhookHandler->>DB: "SELECT billingBlocked from userStats"
        WebhookHandler->>DB: "UPDATE userStats SET billingBlocked = false"
    end
    
    alt Was previously blocked
        WebhookHandler->>WebhookHandler: "resetUsageForSubscription()"
        alt Team/Enterprise Plan
            WebhookHandler->>DB: "SELECT members by organizationId"
            loop For each member
                WebhookHandler->>DB: "UPDATE userStats reset usage counters"
            end
        else Pro Plan
            WebhookHandler->>DB: "UPDATE userStats reset usage counters with snapshot"
        end
    end
Loading

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@icecrasher321 icecrasher321 merged commit 4da355d into staging Oct 3, 2025
10 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/billing-blocked-fix branch October 7, 2025 23:22
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