You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ElysiaJS正确处理Stripe Webhook?解决签名验证报错问题

ElysiaJS 处理 Stripe Webhook 签名验证失败解决方案

问题描述

使用ElysiaJS处理Stripe Webhook时,已获取到请求体字符串reqText,但调用constructEventAsync时触发以下错误:

Webhook payload must be provided as a string or a Buffer 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.

问题根源

  1. 错误地将请求处理逻辑放在了Elysia的parse钩子中——该钩子仅用于解析请求体,而非直接返回响应,导致流程混乱。
  2. Elysia默认会自动将JSON请求体解析为JavaScript对象,破坏了Stripe签名验证必需的原始请求体内容。

修复后的代码

import { Elysia, 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 ({ body, headers }) => {
    return webhookHandler(body as string, headers['stripe-signature'])
  },
  {
    headers: t.Object({
      'stripe-signature': t.String(),
      'content-type': t.String(),
    }),
    // 手动接管请求体解析,获取原始文本
    async parse({ request }) {
      return await request.text()
    },
    body: t.String(),
  },
)

const webhookHandler = async (reqText: string, signature: string) => {
  const endpointSecret = env.STRIPE_WEBHOOK_SECRET

  if (!signature) {
    console.error('Stripe签名缺失')
    return new Response(JSON.stringify({ error: 'Stripe签名缺失' }), { status: 400 })
  }

  if (!stripeClient) {
    console.error('Stripe客户端未初始化')
    return new Response(JSON.stringify({ error: 'Stripe客户端未初始化' }), { status: 500 })
  }

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

    if (event.type === 'payment_intent.succeeded') {
      console.log(event.object)
      console.log('PaymentIntent支付成功!')
    }

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

关键修改点

  • 移除parse钩子中的请求处理逻辑,仅保留原始请求体的获取逻辑,确保传递给Stripe的是未被解析的原始字符串。
  • 将Webhook处理逻辑移至路由的handler函数中,遵循Elysia的正常请求处理流程。
  • 使用标准Response对象返回结果,符合HTTP响应格式规范。

内容的提问来源于stack exchange,提问作者Sandro Nolasco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 11:02:51