Payment Integration Options
Important
One-Time Payment
This section covers the implementation of one-time payments using Stripe's Checkout Sessions API.
convex/stripe.ts
import Stripe from 'stripe';
import { action } from "./_generated/server";
const stripe = new Stripe(process.env.STRIPE_API_KEY, { apiVersion: "2024-09-30.acacia" });
export const createPaymentSession = action({
args: { amount: v.number(), productName: v.string() },
handler: async (ctx, { amount, productName }) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error('Not authenticated');
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{
price_data: {
currency: 'usd',
product_data: { name: productName },
unit_amount: amount * 100, // Convert to cents
},
quantity: 1,
}],
mode: 'payment',
success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/cancel`,
});
return { url: session.url };
},
});
Subscriptions Implementation
This section covers the implementation of subscriptions using Stripe's Checkout Sessions API.
convex/stripe.ts
export const createSubscription = action({
args: { priceId: v.string() },
handler: async (ctx, { priceId }) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error('Not authenticated');
const user = await ctx.db.get(userId);
if (!user?.email) throw new Error('User email required');
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'subscription',
customer_email: user.email,
line_items: [{ price: priceId, quantity: 1 }],
metadata: { userId },
success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
});
return { url: session.url };
},
});
Client Side Implementation
This section covers the client-side implementation of subscriptions using Stripe's Checkout Sessions API.
app/components/CheckoutButton.tsx
"use client";
import { useAction } from "convex/react";
import { api } from "@/convex/_generated/api";
export function CheckoutButton() {
const createCheckout = useAction(api.stripe.createPaymentSession);
const handleCheckout = async () => {
const { url } = await createCheckout({
amount: 10, // $10.00
productName: "Premium Package"
});
if (url) window.location.href = url;
};
return <button onClick={handleCheckout}>Checkout</button>;
}
Webhooks Implementation
Hint
Best Practices
- Always handle errors gracefully and provide clear feedback to users
- Use Stripe's test mode and test card numbers during development
- Implement proper error logging and monitoring
- Keep webhook endpoints secure and validate signatures
- Store important transaction details in your database
Congratulations! You've successfully learned how to integrate Stripe into your application. Now you can handle payments and subscriptions effectively! Let's dive in to the exciting part which is deploying your application. See you on the next one!
Next Steps
Guidance on deploying your application across different environments.
Deployment
Learn how to deploy your application across different environments.
- Stripe Testing Guide: Learn how to effectively test your Stripe integration using test cards and scenarios.
- Webhook Best Practices: Discover best practices for implementing and securing webhooks in your application.
- Error Handling Guide: Understand common Stripe API errors and how to handle them gracefully.