How I Built a Stripe Webhook in Node.js (Full Guide)
In this guide, I’ll walk you through building a Stripe webhook in Node.js. Webhooks are essential for handling asynchronous events from Stripe, such as payment success, subscription cancellations, or failed charges. We’ll use Express.js for the server, Stripe’s Node.js SDK, and best practices for security and scalability.
Prerequisites
Before we begin, ensure you have the following:
- Node.js and npm installed.
- A Stripe account with access to the Stripe Dashboard.
- Stripe CLI (optional but recommended for local testing).
- Basic knowledge of JavaScript and Express.js.
Step 1: Set Up Your Project
Create a new Node.js project and install the required dependencies:
mkdir stripe-webhook
cd stripe-webhook
npm init -y
npm install express stripe body-parser dotenv
Create a .env file to store your Stripe secret key and webhook signing secret:
STRIPE_SECRET_KEY=sk_test_XXXXXXXXXXXXXXXXXXXXXXXX
STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXX
Step 2: Create the Express Server
Set up a basic Express server to handle incoming webhook requests:
const express = require('express');
const bodyParser = require('body-parser');
const Stripe = require('stripe');
const dotenv = require('dotenv');
dotenv.config();
const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
const app = express();
// Middleware to parse raw JSON
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf.toString();
}
}));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Step 3: Implement the Webhook Endpoint
Create a /webhook endpoint to handle Stripe events. Use the stripe.webhooks.constructEvent method to verify the webhook signature:
app.post('/webhook', async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(
req.rawBody,
sig,
process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
console.error(`Webhook Error: ${err.message}`);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('PaymentIntent succeeded:', paymentIntent.id);
// Handle payment success logic here
break;
case 'payment_intent.payment_failed':
const failedIntent = event.data.object;
console.log('PaymentIntent failed:', failedIntent.id);
// Handle payment failure logic here
break;
case 'customer.subscription.created':
const subscription = event.data.object;
console.log('Subscription created:', subscription.id);
// Handle subscription creation logic here
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
res.json({ received: true });
});
Step 4: Test Locally with Stripe CLI
Use the Stripe CLI to test your webhook locally:
- Install Stripe CLI: Stripe CLI Installation Guide.
- Authenticate the CLI:
stripe login
- Forward Stripe events to your local server:
stripe listen --forward-to localhost:3000/webhook
- Trigger test events:
stripe trigger payment_intent.succeeded
Step 5: Deploy and Configure Webhook Endpoint
Once your webhook is tested locally, deploy your server (e.g., using Heroku, AWS, or Docker). Update your Stripe Dashboard with your production webhook URL:
- Go to the Stripe Dashboard.
- Navigate to Developers > Webhooks.
- Add your production endpoint URL (e.g.,
https://yourdomain.com/webhook). - Select the events you want to listen to (e.g.,
payment_intent.succeeded,customer.subscription.created).
Step 6: Secure Your Webhook Endpoint
Security is critical when handling Stripe webhooks. Follow these best practices:
-
Verify the Webhook Signature: Always verify the signature using
stripe.webhooks.constructEvent. - Use HTTPS: Ensure your webhook endpoint uses HTTPS for secure communication.
- Rate Limiting: Implement rate limiting to prevent abuse.
- Log Events: Log events for debugging and auditing purposes.
Step 7: Handle Scalability
As your application grows, consider these scalability tips:
- Queue Processing: Use a queue system like RabbitMQ or AWS SQS to handle large volumes of events asynchronously.
- Database Optimization: Optimize your database queries to handle high traffic.
- Monitoring: Use tools like Datadog or New Relic to monitor your webhook performance.
Conclusion
You’ve now built a fully functional Stripe webhook in Node.js! This setup allows you to handle Stripe events securely and efficiently. Remember to test thoroughly, secure your endpoint, and plan for scalability as your application grows.
🚀 Stop Writing Boilerplate Prompts
If you want to skip the setup and code 10x faster with complete AI architecture patterns, grab my Senior React Developer AI Cookbook ($19). It includes Server Action prompt libraries, UI component generation loops, and hydration debugging strategies.
Browse all 10+ developer products at the Apollo AI Store | Or snipe Solana tokens free via @ApolloSniper_Bot.
Top comments (0)