DEV Community

Apollo
Apollo

Posted on

How I built a Stripe Webhook in Node.js (Full Guide)

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:

  1. Node.js and npm installed.
  2. A Stripe account with access to the Stripe Dashboard.
  3. Stripe CLI (optional but recommended for local testing).
  4. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

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 });
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Test Locally with Stripe CLI

Use the Stripe CLI to test your webhook locally:

  1. Install Stripe CLI: Stripe CLI Installation Guide.
  2. Authenticate the CLI:
stripe login
Enter fullscreen mode Exit fullscreen mode
  1. Forward Stripe events to your local server:
stripe listen --forward-to localhost:3000/webhook
Enter fullscreen mode Exit fullscreen mode
  1. Trigger test events:
stripe trigger payment_intent.succeeded
Enter fullscreen mode Exit fullscreen mode

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:

  1. Go to the Stripe Dashboard.
  2. Navigate to Developers > Webhooks.
  3. Add your production endpoint URL (e.g., https://yourdomain.com/webhook).
  4. 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:

  1. Verify the Webhook Signature: Always verify the signature using stripe.webhooks.constructEvent.
  2. Use HTTPS: Ensure your webhook endpoint uses HTTPS for secure communication.
  3. Rate Limiting: Implement rate limiting to prevent abuse.
  4. Log Events: Log events for debugging and auditing purposes.

Step 7: Handle Scalability

As your application grows, consider these scalability tips:

  1. Queue Processing: Use a queue system like RabbitMQ or AWS SQS to handle large volumes of events asynchronously.
  2. Database Optimization: Optimize your database queries to handle high traffic.
  3. 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)