Skip to content

Stripe Webhooks

This guide walks through setting up Stripe webhooks with Kotodayori using the Stripe router and adapter of your choice.

For Hono (replace with your framework if needed):

Terminal window
pnpm add @kotodayori/stripe @kotodayori/hono stripe

In the Stripe Dashboard, create a webhook endpoint pointing to your route (e.g. https://your-app.com/webhook). Select the events you need. After creation, Stripe shows a Signing secret (starts with whsec_). Store it in your environment (e.g. STRIPE_WEBHOOK_SECRET).

import Stripe from 'stripe';
import { StripeWebhookRouter, createStripeVerifier } from '@kotodayori/stripe';
const stripe = new Stripe(process.env.STRIPE_API_KEY!);
const router = new StripeWebhookRouter();
router.on('payment_intent.succeeded', async (event) => {
const paymentIntent = event.data.object;
console.log('Payment succeeded:', paymentIntent.id, paymentIntent.amount);
});
router.on('customer.subscription.deleted', async (event) => {
const subscription = event.data.object;
console.log('Subscription canceled:', subscription.id);
});

Example with Hono:

import { Hono } from 'hono';
import { honoAdapter } from '@kotodayori/hono';
const app = new Hono();
app.post('/webhook', honoAdapter(router, {
verifier: createStripeVerifier(stripe, process.env.STRIPE_WEBHOOK_SECRET!),
}));
export default app;

For Express, use express.raw({ type: 'application/json' }) before the adapter. For Lambda, export the handler from lambdaAdapter(router, { verifier }).

  • Always verify signatures — Use createStripeVerifier; never trust the body without verification.
  • Use raw body — Adapters need the raw request body for verification. Do not parse JSON before the verifier.
  • Keep the secret safe — Do not log or expose STRIPE_WEBHOOK_SECRET.

Event names are autocompleted and handlers receive the correct Stripe event type (e.g. Stripe.PaymentIntentSucceededEvent). Use the Stripe Events API and your IDE to explore available events.