我正在尝试使用 Stripe 和 NextJS 13.2.3 设置 webhook

2023-12-20

我能够通过内置 Stripe 页面成功结帐我的购物车,并且我会被重定向到我的 successUrl 路线。我的本地测试 webhook 正在按预期被调用。但是,当我包含代码来验证请求是否来自 Stripe 时,我收到一些错误。

这是我在 NextJS 中的 webhook

import { stripe } from "@/lib/stripe"

export async function POST(req: Request){

    const payload = await req.json()
    
    const sig = req.headers.get('stripe-signature') as string
    console.log("sig: ", sig)

    let event;

    const endpointSecret = process.env.WEBHOOK_SECRET_LOCAL as string

    try {
        console.log("constructing event...")
        event = stripe.webhooks.constructEvent(payload, sig, endpointSecret)
    } catch (error) {
        console.error(error)
        return new Response(`Webhook error: ${error}`, {
            status: 400,
        })
    }
    
    return new Response("payment confirmation route received", {
        status: 200,
    })
}

我正在使用 Stripe CLI 监听成功事件stripe listen --forward-to localhost:3000/api/checkout/payment-confirmation

检查完我的购物车后,我发现...

2023-03-23 15:51:28 --> checkout.session.completed [evt_1MowyjE7TMviQOgJNbXch10w] 2023-03-23 15:51:28 --> charge.succeeded [evt_3MowyhE7TMviQOgJ09e3Q7Hu] 2023-03-23 15:51:29 --> payment_intent.succeeded [evt_3MowyhE7TMviQOgJ0OIjeNoH] 2023-03-23 15:51:29 --> payment_intent.created [evt_3MowyhE7TMviQOgJ0ovhouJM] 2023-03-23 15:51:32 <-- [400] POST http://localhost:3000/api/checkout/payment-confirmation [evt_3MowyhE7TMviQOgJ09e3Q7Hu] 2023-03-23 15:51:32 <-- [400] POST http://localhost:3000/api/checkout/payment-confirmation [evt_3MowyhE7TMviQOgJ0OIjeNoH] 2023-03-23 15:51:32 <-- [400] POST http://localhost:3000/api/checkout/payment-confirmation [evt_1MowyjE7TMviQOgJNbXch10w] 2023-03-23 15:51:32 <-- [400] POST http://localhost:3000/api/checkout/payment-confirmation [evt_3MowyhE7TMviQOgJ0ovhouJM]

从 NextJS 中我看到......

StripeSignatureVerificationError: 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

我认为这意味着我需要以某种方式修改有效负载参数。我试过payload.toString(), JSON.stringify(payload), using const buf = Buffer.from(payload)以及其他各种事情,认为我需要以某种方式将该对象转换为字符串或缓冲区,但我不理解这个问题。非常感谢帮助!

- 更新 -

现在我已经更新了代码,但我仍然收到一般错误......

No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

我对 Stripe 的回应:“我的意思是,我认为是这样?!?”

我还尝试导入“micro”或“raw-body”,正如我看到其他人使用的那样,但它们会给我带来各种错误,这就是为什么我使用来自 node.js 的错误。 req.body 是一个 ReadableStream,

类型为“ReadableStream |”的参数null' 不可分配给'string | 类型的参数缓冲'

???? 如果我尝试将其作为构造事件中的第一个参数传递。

import { stripe } from "@/lib/stripe"
import { NextRequest } from "next/server";
import { Buffer } from "node:buffer";

export async function POST(req: NextRequest){
    
    const buf = Buffer.from(req.toString())
// <Buffer 5b 6f 62 6a 65 63 74 20 52 65 71 75 65 73 74 5d>

    const headers = req.headers
    
    const sig = req.headers.get("stripe-signature") as string | string[]
// t=1679...,v1=888050e17...,v0=cc9b94a...
    let event;
    const endpointSecret = process.env.WEBHOOK_SECRET_LOCAL as string
// whsec_...
    

    try {
        console.log("constructing event...")
        event = stripe.webhooks.constructEvent(buf, sig, endpointSecret)
    } catch (error) {
        console.error(error)
        return new Response(`Webhook error: ${error}`, {
            status: 400,
        })
    }
    
    return new Response("payment confirmation route received", {
        status: 200,
    })
}

export const config = {
    api: {
      bodyParser: false,
    },
  };

而不是使用micro要缓冲身体,只需使用await req.text()将原始正文转换为字符串,然后将字符串传递给stripe.webhooks.constructEvent.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我正在尝试使用 Stripe 和 NextJS 13.2.3 设置 webhook 的相关文章

随机推荐

  • 从特定分支推送时触发 GitHub Action

    我们有一个分支模型 其中包含功能分支 开发分支 登台分支 用于测试 和主分支用于发布 现在我们有一个针对发行说明的操作 它在推送到暂存或主版本时使用实际发行说明创建拉取请求 但是 只有当我们将拉取请求从开发推送到暂存以及从暂存推送到主控时
  • C 编程 - 将整数转换为二进制

    我希望得到一些反对解决方案的建议 因为这是家庭作业 我想自己解决它 首先 我对 C 非常陌生 事实上 我以前从未做过任何事情 尽管我以前在大学的模块中拥有过 Java 经验 我正在尝试编写一个将单个整数转换为二进制的程序 我只允许使用按位运
  • 快速会话动态 cookie 域

    我有很多域 我正在尝试在快速会话中动态设置 cookie 域 下面的 example com 文本在域中工作正常 Sessions const RedisStore require connect redis session app use
  • 无法运行Java 17的Spring Boot应用程序

    就像一个健全性测试一样 我尝试编译然后运行默认的 Spring Boot 启动应用程序 我使用 Maven 将项目编译成 Jar 文件 但是当我厌倦运行该应用程序时 我收到了以下输出 YCApp61 WorkDir java jar MyS
  • 如何转义system.data.sqlite中的字符串?

    我正在执行 SQL 查询 system data SQLite 如下所示 var color red var command new SQLiteCommand SELECT something FROM tabletop WHERE co
  • 如何通过 zlib 和 compress2 用 C 语言编写 gz 文件

    我正在使用 zlib 编写一个在多个线程中压缩数据的程序 所以我不能使用gzwrite 我正在使用 compress2 dest len compressBound LOG BUFF SZ err compress2 Bytef compr
  • 访问:在 VBA 中使用查询来获取记录集

    我已经习惯用以下格式做记录集 Dim rs As DAO Recordset Dim strSQL As String strSQL Select field1 field2 from myTable where field1 gt 30
  • 符号解析和动态链接

    我一直在阅读有关重定位和符号解析过程的内容 并且对此有一些疑问 所以整个过程 加载执行程序 开始于exec BA OS 命令 期间exec BA OS 系统从PT INTERP分段并从解释器文件的分段创建初始过程映像 也就是说 系统不使用原
  • Android 上的 ThreeTen-Backport 错误 - ZoneRulesException:未注册时区数据文件

    我正在为我的 Android 项目使用 ThreeTen Backport 库 因为 java time 尚未在 Android 开发中实现 当我写作时LocalDate today LocalDate now or LocalTime t
  • Elasticsearch 术语和总和聚合

    我在 elasticsearch 1 5 中有如下文档 gender name unknown value 12 name male value 89 name female value 84 并非所有文档都包含三个选项 男 女 未知 我想
  • 如何使用 Entity Framework CF 在父实体之前删除子实体?

    我正在尝试使用 EF 代码优先删除数据库记录 deleteMe 和它的孩子们 deleteMe Prices foreach var deleteMe in deleteThese Delete validation if CanDelet
  • 在构造函数中访问容器子部件尺寸

    假设我的班级有两个人Gtk Containers像这样 class Example public Gtk VBox public Example virtual Example private Gtk HBox m c1 First con
  • Node/Express:会话过期事件?

    在 ASP NET 上 我们有一个会话过期事件 我将 node js 与express js 以及会话的默认内存存储一起使用 每次我重新启动节点时 会话都会丢失 理想情况下 我想将会话保存到数据库 不能使用 redis 是否有会话过期事件
  • ASP.NET:隐藏gridview中的列

    有没有办法可以通过代码控制列 我有一个下拉框 其中选择 每日和周末 网格视图列包含星期一 星期二 星期三 星期四 星期五 星期六 星期日 如果用户选择 每日 我只想显示周一到周五的列 可以通过代码进行控制 哦 我在我的网页中使用这个 gri
  • 如何获取缓存图像 SDWebImage 的数据

    我正在使用 SDWebImage 库在 UICollectionView 中缓存 Web 图像 cell packItemImage sd setImage with URL string smileImageUrl indexPath r
  • Meteor JS:如何为多个选择器创建事件处理程序?

    我试图为多个元素创建相同的事件处理程序 但在文档中找不到执行此操作的任何位置 在下面的示例中 我尝试为所有文本处理创建一个单击处理程序 这适用于h1 但不适用于其余的 Template page events click h1 h2 h3
  • 从正在运行的进程中分离

    我面临着一个有趣的情况 我正在开发一个手电筒 https github com w0lfschild Flashlight插件在将来的某个时刻触发警报 问题是 手电筒会在 30 秒后杀死脚本 因此 我既不能等待足够长的时间来激活闹钟 也不能
  • 休眠 ID 生成器

    有人知道一些关于如何为 hibernate 创建自定义 ID 生成器的好教程吗 在 Google 上粗略搜索 hibernate 自定义 id 生成器教程 发现了以下可能性 我排除了那些看起来没有用的内容 并总结了每个内容的内容 http
  • 将标签添加到反应选择

    I am new to the react js here what I am trying to do is that 现在我尝试过的是 const options value chocolate label Chocolate valu
  • 我正在尝试使用 Stripe 和 NextJS 13.2.3 设置 webhook

    我能够通过内置 Stripe 页面成功结帐我的购物车 并且我会被重定向到我的 successUrl 路线 我的本地测试 webhook 正在按预期被调用 但是 当我包含代码来验证请求是否来自 Stripe 时 我收到一些错误 这是我在 Ne