-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation
Description
Overview
This issue documents comprehensive research on Stripe payment integration, covering SDK usage, API integration patterns, and best practices.
Current State
The vm0-2 project currently does not have Stripe integrated. No Stripe-related dependencies exist in the codebase.
Key Findings
Two Integration Approaches
| Approach | Description | Complexity |
|---|---|---|
| Stripe Checkout | Pre-built, hosted payment page. Stripe handles the entire UI. | Simple (2/5) |
| Payment Elements | Customizable, embeddable React components. More control over UI/UX. | Moderate (3/5) |
Both approaches are PCI compliant.
Core APIs
1. Checkout Sessions API
Creates redirect-based payment flows:
const session = await stripe.checkout.sessions.create({
mode: 'payment', // or 'subscription', 'setup'
line_items: [{
price: 'price_xxx',
quantity: 1
}],
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
metadata: { order_id: '12345' }
});2. Payment Intents API
Tracks payments through their lifecycle:
const paymentIntent = await stripe.paymentIntents.create({
amount: 1099, // Amount in cents
currency: 'usd',
metadata: { order_id: '6735' },
setup_future_usage: 'off_session',
});Lifecycle States: requires_payment_method → requires_confirmation → requires_action → processing → succeeded
3. Subscriptions API
For recurring payments:
// Create Product & Price
const product = await stripe.products.create({ name: 'Premium Plan' });
const price = await stripe.prices.create({
product: product.id,
unit_amount: 1500,
currency: 'usd',
recurring: { interval: 'month' },
});
// Create Subscription Checkout
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{ price: price.id, quantity: 1 }],
success_url: 'https://example.com/success',
});React/TypeScript Integration
Installation
npm install stripe @stripe/react-stripe-js @stripe/stripe-jsFrontend Setup
import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe('pk_test_...');
export default function App() {
return (
<Elements stripe={stripePromise} options={{ clientSecret: '...' }}>
<CheckoutForm />
</Elements>
);
}PaymentElement Component
import { useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js';
function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!stripe || !elements) return;
const { error } = await stripe.confirmPayment({
elements,
confirmParams: { return_url: window.location.origin + '/success' },
});
if (error) console.log(error.message);
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
<button disabled={!stripe}>Pay</button>
</form>
);
}Webhook Setup
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['stripe-signature'] as string;
const event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
switch (event.type) {
case 'payment_intent.succeeded':
// Handle successful payment
break;
case 'invoice.paid':
// Subscription payment succeeded
break;
case 'invoice.payment_failed':
// Handle failed payment
break;
}
res.json({ received: true });
});Key Events:
payment_intent.succeeded/payment_intent.payment_failedcheckout.session.completed/checkout.session.expiredinvoice.paid/invoice.payment_failedcustomer.subscription.created/deleted
Error Handling
| Error Type | Description |
|---|---|
StripeCardError |
Payment declined or card issue |
StripeInvalidRequestError |
Invalid API parameters |
StripeAPIConnectionError |
Network connectivity issue |
StripeAuthenticationError |
Invalid API key |
StripeRateLimitError |
Too many requests |
Common Decline Codes: insufficient_funds, card_declined, expired_card, incorrect_cvc, generic_decline
Testing
Test Cards
| Card Number | Behavior |
|---|---|
4242 4242 4242 4242 |
Successful payment |
4000 0000 0000 9995 |
Decline (insufficient funds) |
4000 0025 0000 3155 |
Requires 3D Secure |
CLI Testing
stripe listen --forward-to localhost:3000/webhook
stripe trigger payment_intent.succeededSecurity & Compliance
- Use Stripe.js or Elements (handles card data in iframes)
- Never handle raw card numbers on your server
- Always load Stripe.js from
js.stripe.com - Store API keys in environment variables
- Stripe handles 3D Secure (SCA) automatically for EU payments
Pricing
| Feature | Cost |
|---|---|
| Standard payments | 2.9% + $0.30 per transaction (US) |
| Recurring billing | +0.5% per recurring transaction |
| International cards | +1% |
Key Resources
- stripe-node GitHub
- Payment Intents API
- Checkout Sessions API
- React Stripe.js Reference
- Webhooks Documentation
- Subscriptions Guide
- Test Cards
🤖 Generated with Claude Code from conversation research
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation