Setting up a Stripe webhook with Kaito
An advantage of Kaito moving to support Request/Response APIs in v3 is that it made it super easy to setup a Stripe webhook. You can read more at the bottom of this page about why that was the case.
Example
context.ts
export const {router} = createUtilities(async (req, res) => {
return {
bodyAsText: async () => await req.text(),
};
});
stripe.ts
import {router} from './context.ts';
import stripe from '@stripe/stripe-js';
// Create a crypto provider for stripe to use, required in some runtimes that don't define `crypto.subtle` globally.
// If you're unsure, try without, and then bring it back if you get an error.
const webCrypto = stripe.createSubtleCryptoProvider();
// Notice how we don't define a body schema, we're using stripe's webhook logic to parse the body for us
// which requires the raw body as a string.
export const stripe = router().post('/webhook', async ({ctx}) => {
const body = await ctx.bodyAsText();
const sig = ctx.req.headers.get('stripe-signature');
if (!sig) {
throw new KaitoError(400, 'No signature provided');
}
const event = await stripe.webhooks.constructEventAsync(
body,
sig,
process.env.STRIPE_ENDPOINT_SECRET!, // You should validate this exists, and not use the `!` operator
undefined,
webCrypto,
);
console.log('Stripe event:', event);
});