-
Notifications
You must be signed in to change notification settings - Fork 498
fix stripe failing webhook #1102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Older cmux preview screenshots (latest comment is below)Preview Screenshots⏳ Preview screenshots are being captured... Workspace and dev browser links will appear here once the preview environment is ready. Generated by cmux preview system |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Older cmux preview screenshots (latest comment is below)Preview ScreenshotsOpen Workspace (1 hr expiry) · Open Dev Browser (1 hr expiry) · Open Diff Heatmap Screenshot capture was skipped.
Generated by cmux preview system |
📝 WalkthroughWalkthroughThis change adds parsing of Stripe subscription metadata to support legacy subscriptions. It derives product data from either product or offer fields, validates presence, parses JSON, and adds error handling for missing or invalid metadata. The productId now includes a fallback to use offerId when undefined. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
Greptile SummaryFixed webhook failures for legacy Stripe subscriptions by adding backward compatibility with the old
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Stripe
participant Webhook as Webhook Handler
participant Sync as syncStripeSubscriptions
participant DB as Database
Stripe->>Webhook: POST /webhooks (subscription event)
Webhook->>Webhook: Verify signature
Webhook->>Webhook: Extract accountId & customerId
Webhook->>Sync: syncStripeSubscriptions(stripe, accountId, customerId)
Sync->>Stripe: Retrieve account metadata
Sync->>Stripe: List subscriptions for customer
loop For each subscription
Sync->>Sync: Try metadata.product
alt metadata.product exists
Sync->>Sync: Use metadata.product
else fallback to metadata.offer
Sync->>Sync: Use metadata.offer (legacy)
end
alt metadata missing
Sync-->>Webhook: Throw StackAssertionError
end
Sync->>Sync: JSON.parse(productString)
alt Invalid JSON
Sync-->>Webhook: Throw StackAssertionError
end
Sync->>Sync: Try metadata.productId ?? metadata.offerId
Sync->>DB: upsert subscription
DB-->>Sync: Success
end
Sync-->>Webhook: Success
Webhook-->>Stripe: 200 OK
|
Greptile's behavior is changing!From now on, if a review finishes with no comments, we will not post an additional "statistics" comment to confirm that our review found nothing to comment on. However, you can confirm that we reviewed your changes in the status check section. This feature can be toggled off in your Code Review Settings by deselecting "Create a status check for each PR". |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @apps/backend/src/lib/stripe.tsx:
- Around line 128-130: The productId assignment is using inconsistent casting
and lacks the same defensive validation as the product/offer handling; change
the fallback subscription.metadata.offerId to be cast as string | undefined
(matching product handling) and add a validation check that throws or returns an
error if both subscription.metadata.productId and subscription.metadata.offerId
are missing so productId never becomes null/undefined; update the productId
assignment (and any surrounding logic that uses productId) to use the validated,
cast value consistently.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/backend/src/lib/stripe.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: For blocking alerts and errors, never usetoast, as they are easily missed by the user. Instead, use alerts
Keep hover/click transitions snappy and fast without pre-transition delays (e.g., no fade-in when hovering a button). Apply transitions after the action, like smooth fade-out when hover ends
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error). Use loading indicators for async operations. UserunAsynchronouslyorrunAsynchronouslyWithAlertinstead of general try-catch error handling
When creating hover transitions, avoid hover-enter transitions and use only hover-exit transitions (e.g.,transition-colors hover:transition-none)
Don't useDate.now()for measuring elapsed (real) time; instead useperformance.now()
Use ES6 maps instead of records wherever possible
Files:
apps/backend/src/lib/stripe.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: NEVER use Next.js dynamic functions if you can avoid them. Prefer using client components to keep pages static (e.g., useusePathnameinstead ofawait params)
Code defensively using?? throwErr(...)instead of non-null assertions, with good error messages explicitly stating violated assumptions
Try to avoid theanytype. When usingany, leave a comment explaining why and how the type system fails or how errors would still be caught
Files:
apps/backend/src/lib/stripe.tsx
{.env*,**/*.{ts,tsx,js,jsx}}
📄 CodeRabbit inference engine (AGENTS.md)
All environment variables should be prefixed with
STACK_(orNEXT_PUBLIC_STACK_if public) to ensure Turborepo picks up changes and improve readability
Files:
apps/backend/src/lib/stripe.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-11T04:13:19.308Z
Learnt from: N2D4
Repo: stack-auth/stack-auth PR: 943
File: examples/convex/app/action/page.tsx:23-28
Timestamp: 2025-10-11T04:13:19.308Z
Learning: In the stack-auth codebase, use `runAsynchronouslyWithAlert` from `stackframe/stack-shared/dist/utils/promises` for async button click handlers and form submissions instead of manual try/catch blocks. This utility automatically handles errors and shows alerts to users.
Applied to files:
apps/backend/src/lib/stripe.tsx
🧬 Code graph analysis (1)
apps/backend/src/lib/stripe.tsx (2)
packages/stack-shared/src/utils/errors.tsx (1)
StackAssertionError(69-85)packages/stack-shared/src/utils/results.tsx (1)
error(36-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: all-good
- GitHub Check: Vercel Agent Review
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: lint_and_build (latest)
- GitHub Check: setup-tests
- GitHub Check: restart-dev-and-test
- GitHub Check: docker
- GitHub Check: build (22.x)
- GitHub Check: build (22.x)
- GitHub Check: setup-tests-with-custom-base-port
- GitHub Check: E2E Tests (Node 22.x, Freestyle prod)
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: E2E Tests (Node 22.x, Freestyle mock)
🔇 Additional comments (3)
apps/backend/src/lib/stripe.tsx (3)
9-9: LGTM!The
InputJsonValueimport is correctly added to properly type the parsed JSON metadata.
96-106: LGTM!Good backward-compatible handling for legacy subscriptions. The try-catch is appropriately scoped to JSON parsing (not a try-catch-all), and the
StackAssertionErrorincludes helpful context for debugging.
115-123: LGTM!The update path correctly uses the pre-validated
productJsonvalue.
Preview Screenshots⏳ Preview screenshots are being captured... Workspace and dev browser links will appear here once the preview environment is ready. Generated by cmux preview system |
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.