ElysiaJS Bun - Stripe Webhooks

37 views Asked by At

How i can handle the stripe webhook with ElysiaJS?

i have been trying for a long time and dont get results

im here, the body is parsed and i received an string from the reqText

the contructEvent returns this error Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object instead. Signature verification is impossible without access to the original signed material.

Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing

import { Elysia, ParseError, t } from 'elysia'
import { env } from '@/config/env.config'
import { stripeClient } from '@/lib/stripe.lib'

export const stripeWebhook = new Elysia().post(
  '/integrations/stripe/webhook',
  async () => {},
  {
    headers: t.Object({
      'stripe-signature': t.String(),
      'content-type': t.String(),
    }),
    async parse({ headers, request }) {
      if (headers['content-type'] === 'application/json; charset=utf-8') {
        const reqText = await request.text()
        return webhookHandler(reqText, request)
      } else {
        throw new ParseError('Invalid content type')
      }
    },
    body: t.Not(t.Undefined()),
  },
)

const webhookHandler = async (reqText: string, request: Request) => {
  const endpointSecret = env.STRIPE_WEBHOOK_SECRET
  const signature = request.headers.get('stripe-signature')

  if (!signature) {
    console.error('Stripe signature is missing')
    return {
      statusCode: 400,
      body: JSON.stringify({ error: 'Stripe signature is missing' }),
    }
  }

  if (!stripeClient) {
    console.error('Stripe client is not initialized')
    return {
      statusCode: 500,
      body: JSON.stringify({ error: 'Stripe client is not initialized' }),
    }
  }

  try {
    const event = await stripeClient.webhooks.constructEventAsync(
      reqText,
      signature,
      endpointSecret,
    )

    if (event.type === 'payment_intent.succeeded') {
      console.log(event.object)
      console.log('PaymentIntent was successful!')
    }

    return {
      statusCode: 200,
      body: JSON.stringify({ received: true }),
    }
  } catch (error) {
    console.error(error)
    return {
      statusCode: 400,
      body: `Webhook Error: ${error}`,
    }
  }
}

i want make it works properly

1

There are 1 answers

0
qichuan On

The important thing here is pass the raw request body to the constructEventAsync function. Therefore, I'd suggest changing request.text() to request.body. You can find the full example here