Skip to content

Credit top-ups from Stripe webhook#1483

Merged
riderx merged 5 commits into
mainfrom
Dalanir/stripe-credit-miss
Jan 21, 2026
Merged

Credit top-ups from Stripe webhook#1483
riderx merged 5 commits into
mainfrom
Dalanir/stripe-credit-miss

Conversation

@Dalanir
Copy link
Copy Markdown
Contributor

@Dalanir Dalanir commented Jan 21, 2026

Summary (AI generated)

  • Add Stripe checkout session webhook handling to grant usage credits server-side
  • Extract customer ID for checkout session events to resolve orgs reliably

Motivation (AI generated)

Top-up credits were only granted on client redirect, so missed redirects left paid sessions without grants.

Business Impact (AI generated)

Reduces paid-but-uncredited incidents and support overhead by crediting from Stripe webhooks.

Test Plan (AI generated)

  • Not run (requires prod webhook verification)

Generated with AI

Summary by CodeRabbit

  • New Features

    • Added comprehensive Stripe checkout session event handling to process successful payment transactions and asynchronous payment completions.
    • Implemented automatic credit top-up mechanism that activates upon successful checkout session completion.
  • Tests

    • Enhanced test framework with automatic retry capability for improved stability and reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 21, 2026

Warning

Rate limit exceeded

@Dalanir has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 47 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

The changes add support for Stripe checkout session completion events to the webhook handler. A new handler processes checkout.session.completed and checkout.session.async_payment_succeeded events, validates sessions, retrieves product and customer information, and invokes a Postgres RPC to credit usage. Additionally, test utilities add a retry-enabled fetch wrapper for API calls.

Changes

Cohort / File(s) Summary
Stripe Webhook Handlers
supabase/functions/_backend/triggers/stripe_event.ts
Adds handleCheckoutSessionCompleted to process checkout session events, getCreditTopUpProductIdFromCustomer to resolve product IDs, and new event type detection. Validates session mode/status, matches organization, aggregates line items, and calls top_up_usage_credits RPC. Early-return routing for checkout sessions before other event types.
Event Type Extension
supabase/functions/_backend/utils/stripe_event.ts
Extends extractDataEvent to handle checkout.session.completed and checkout.session.async_payment_succeeded, casting to Stripe.Checkout.Session and extracting customer_id and succeeded status.
Test Infrastructure
tests/test-utils.ts, tests/expose-metadata.test.ts
Introduces fetchWithRetry utility function for retry-enabled API calls. Replaces direct fetch calls in expose-metadata tests with fetchWithRetry wrapper for improved resilience.

Sequence Diagram

sequenceDiagram
    actor Stripe as Stripe Webhook
    participant Handler as Webhook Handler
    participant Utils as Utils/Stripe
    participant Stripe_API as Stripe API
    participant DB as PostgreSQL

    Stripe->>Handler: checkout.session.completed/async_payment_succeeded
    Handler->>Utils: extractDataEvent(event)
    Utils-->>Handler: {customer_id, status: 'succeeded'}
    Handler->>Handler: Validate session (mode, status)
    Handler->>Handler: Match to Organization
    Handler->>Stripe_API: getStripe().listLineItems(session_id)
    Stripe_API-->>Handler: Line items[]
    Handler->>Handler: getCreditTopUpProductIdFromCustomer(customer)
    Handler->>Handler: Aggregate creditQuantity from items
    Handler->>DB: RPC top_up_usage_credits(org_id, credits)
    DB-->>Handler: Success/Error
    Handler-->>Stripe: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Hark! A new checkout session dances
Through Stripe's webhook with graceful chances,
Line items bundle, credits flow free,
While retry-wrapped tests hop with glee!
One hop to verify, two hops to see,
Stripe webhooks now complete—yippee! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description lacks detail about changes to test coverage and whether existing tests pass. The test plan is marked as not run with a disclaimer, and several checklist items are incomplete or unaddressed. Clarify test coverage strategy, confirm linting passes, specify test results, and complete the provided description template sections fully.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Credit top-ups from Stripe webhook' clearly and concisely summarizes the main change: adding server-side credit top-up functionality triggered by Stripe webhooks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@Dalanir Dalanir self-assigned this Jan 21, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/expose-metadata.test.ts (1)

4-9: Fix named import order to satisfy ESLint.

Static analysis reports a perfectionist/sort-named-imports error for this import list.

🔧 Suggested reorder
 import {
   APP_NAME,
-  getBaseData,
-  getEndpointUrl,
   fetchWithRetry,
+  getBaseData,
+  getEndpointUrl,
   getSupabaseClient,
   headers,
   ORG_ID,
🤖 Fix all issues with AI agents
In `@supabase/functions/_backend/triggers/stripe_event.ts`:
- Around line 33-68: The getCreditTopUpProductIdFromCustomer function currently
uses supabaseAdmin to query stripe_info and plans; replace those calls with the
recommended DB client (either getPgClient() or getDrizzleClient()) and include
the proper schema when querying, i.e. perform the same two lookups (stripe_info
-> product_id by customer_id, then plans -> credit_id by stripe_id) using the
chosen client and schema-aware methods, preserve the same error logging via
cloudlog and same thrown simpleError messages, and return plan.credit_id; update
any variable names (stripeInfo, plan) as needed to match the new client APIs.

Comment thread supabase/functions/_backend/triggers/stripe_event.ts
@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 55fb8e5 into main Jan 21, 2026
11 checks passed
@riderx riderx deleted the Dalanir/stripe-credit-miss branch January 21, 2026 22:40
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