Stripe Integration
Overview
Stripe provides a complete payments platform with server-side SDKs (Node.js) and client-side libraries (Stripe.js, React Stripe.js). The Node.js SDK handles server operations like creating Payment Intents, managing Subscriptions, and verifying webhooks. The React Stripe.js library provides pre-built UI components (PaymentElement, Elements provider) for secure client-side payment collection.
When to use: One-time payments, recurring subscriptions, usage-based billing, marketplace payouts, hosted checkout pages, custom payment forms, webhook-driven fulfillment.
When NOT to use: Cryptocurrency payments (not supported), regions where Stripe is unavailable, simple static product sales without payment processing (use a hosted storefront).
Quick Reference
| Pattern |
API |
Key Points |
| Hosted checkout |
stripe.checkout.sessions.create() |
Stripe-hosted page, supports payment, subscription, setup modes |
| Payment Intent |
stripe.paymentIntents.create() |
Server-side, returns client_secret for client confirmation |
| Confirm payment |
stripe.confirmPayment({ elements, clientSecret }) |
Client-side, requires Elements instance |
| Create subscription |
stripe.subscriptions.create() |
Use payment_behavior: 'default_incomplete' for SCA |
| Update subscription |
stripe.subscriptions.update() |
Set proration_behavior explicitly |
| Cancel subscription |
stripe.subscriptions.cancel() |
Use prorate: true to credit unused time |
| Customer Portal |
stripe.billingPortal.sessions.create() |
Self-service billing management, returns short-lived URL |
| Webhook verify |
stripe.webhooks.constructEvent() |
Requires raw body, signature header, and endpoint secret |
| Elements provider |
<Elements stripe={stripePromise} options={options}> |
Wraps payment components, pass clientSecret or mode |
| PaymentElement |
<PaymentElement /> |
Renders all supported payment methods automatically |
| Retrieve + expand |
stripe.checkout.sessions.retrieve(id, { expand }) |
Expand nested objects to reduce API calls |
| Search |
stripe.paymentIntents.search({ query }) |
Stripe Query Language for filtering |
Common Mistakes
| Mistake |
Correct Pattern |
| Parsing webhook body as JSON before verification |
Use express.raw({ type: 'application/json' }) to pass raw body to constructEvent |
| Hardcoding payment method types |
Use automatic_payment_methods or let Checkout choose based on currency and region |
| Creating PaymentIntent client-side |
Create on server, pass only client_secret to client |
Not awaiting elements.submit() before confirm |
Call elements.submit() first to trigger validation, then confirmPayment |
Missing return_url in confirmPayment |
Always provide return_url for redirect-based payment methods |
| Using test keys in production |
Store keys in environment variables, validate STRIPE_SECRET_KEY prefix (sk_live_ vs sk_test_) |
Not handling requires_action status |
Check PaymentIntent status after confirmation, handle 3D Secure or other authentication |
| Creating Customer Portal session without settings |
Save portal settings in Dashboard first, otherwise API returns an error |
| Not expanding related objects |
Use expand parameter to include nested objects like latest_invoice.payment_intent |
| Ignoring webhook idempotency |
Use event.id to deduplicate, webhook events can be delivered more than once |
Delegation
- Payment flow architecture: Use
Explore agent to discover integration patterns
- Webhook debugging: Use
Task agent for end-to-end event tracing
- Code review: Delegate to
code-reviewer agent for security review of payment handlers
References
- Checkout Sessions, Payment Intents, and one-time payments
- Subscription lifecycle, pricing models, trials, and Customer Portal
- Webhook endpoints, signature verification, and event handling
- React Stripe.js, Elements provider, PaymentElement, and custom forms
1---
2name: stripe-integration
3description: |
4 Stripe payment integration with Node.js SDK. Covers Checkout Sessions, Payment Intents, Subscriptions, Customer Portal, webhooks, and Stripe Elements.
5
6 Use when implementing checkout flows, payment processing, subscription billing, webhook handlers, or payment forms with Stripe Elements.
7
8 Use for stripe, payments, checkout, subscriptions, billing, webhooks, payment intents, stripe elements.
9license: MIT
10metadata:
11 author: oakoss
12 version: '1.0'
13 source: https://docs.stripe.com
14user-invocable: false
15---
16
17# Stripe Integration
18
19## Overview
20
21Stripe provides a complete payments platform with server-side SDKs (Node.js) and client-side libraries (Stripe.js, React Stripe.js). The Node.js SDK handles server operations like creating Payment Intents, managing Subscriptions, and verifying webhooks. The React Stripe.js library provides pre-built UI components (PaymentElement, Elements provider) for secure client-side payment collection.
22
23**When to use:** One-time payments, recurring subscriptions, usage-based billing, marketplace payouts, hosted checkout pages, custom payment forms, webhook-driven fulfillment.
24
25**When NOT to use:** Cryptocurrency payments (not supported), regions where Stripe is unavailable, simple static product sales without payment processing (use a hosted storefront).
26
27## Quick Reference
28
29| Pattern | API | Key Points |
30| ------------------- | ----------------------------------------------------- | --------------------------------------------------------------------- |
31| Hosted checkout | `stripe.checkout.sessions.create()` | Stripe-hosted page, supports `payment`, `subscription`, `setup` modes |
32| Payment Intent | `stripe.paymentIntents.create()` | Server-side, returns `client_secret` for client confirmation |
33| Confirm payment | `stripe.confirmPayment({ elements, clientSecret })` | Client-side, requires Elements instance |
34| Create subscription | `stripe.subscriptions.create()` | Use `payment_behavior: 'default_incomplete'` for SCA |
35| Update subscription | `stripe.subscriptions.update()` | Set `proration_behavior` explicitly |
36| Cancel subscription | `stripe.subscriptions.cancel()` | Use `prorate: true` to credit unused time |
37| Customer Portal | `stripe.billingPortal.sessions.create()` | Self-service billing management, returns short-lived URL |
38| Webhook verify | `stripe.webhooks.constructEvent()` | Requires raw body, signature header, and endpoint secret |
39| Elements provider | `<Elements stripe={stripePromise} options={options}>` | Wraps payment components, pass `clientSecret` or `mode` |
40| PaymentElement | `<PaymentElement />` | Renders all supported payment methods automatically |
41| Retrieve + expand | `stripe.checkout.sessions.retrieve(id, { expand })` | Expand nested objects to reduce API calls |
42| Search | `stripe.paymentIntents.search({ query })` | Stripe Query Language for filtering |
43
44## Common Mistakes
45
46| Mistake | Correct Pattern |
47| ------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
48| Parsing webhook body as JSON before verification | Use `express.raw({ type: 'application/json' })` to pass raw body to `constructEvent` |
49| Hardcoding payment method types | Use `automatic_payment_methods` or let Checkout choose based on currency and region |
50| Creating PaymentIntent client-side | Create on server, pass only `client_secret` to client |
51| Not awaiting `elements.submit()` before confirm | Call `elements.submit()` first to trigger validation, then `confirmPayment` |
52| Missing `return_url` in `confirmPayment` | Always provide `return_url` for redirect-based payment methods |
53| Using test keys in production | Store keys in environment variables, validate `STRIPE_SECRET_KEY` prefix (`sk_live_` vs `sk_test_`) |
54| Not handling `requires_action` status | Check PaymentIntent status after confirmation, handle 3D Secure or other authentication |
55| Creating Customer Portal session without settings | Save portal settings in Dashboard first, otherwise API returns an error |
56| Not expanding related objects | Use `expand` parameter to include nested objects like `latest_invoice.payment_intent` |
57| Ignoring webhook idempotency | Use `event.id` to deduplicate, webhook events can be delivered more than once |
58
59## Delegation
60
61- **Payment flow architecture**: Use `Explore` agent to discover integration patterns
62- **Webhook debugging**: Use `Task` agent for end-to-end event tracing
63- **Code review**: Delegate to `code-reviewer` agent for security review of payment handlers
64
65## References
66
67- [Checkout Sessions, Payment Intents, and one-time payments](references/checkout-and-payments.md)
68- [Subscription lifecycle, pricing models, trials, and Customer Portal](references/subscriptions.md)
69- [Webhook endpoints, signature verification, and event handling](references/webhooks.md)
70- [React Stripe.js, Elements provider, PaymentElement, and custom forms](references/stripe-elements.md)