如何在本地主机上接收 Stripe Webhooks(免去麻烦)

发布: (2026年2月23日 GMT+8 04:41)
12 分钟阅读
原文: Dev.to

Source: Dev.to

如何在本地(localhost)接收 Stripe Webhook 而不头疼

在开发 Stripe 集成时,最常见的痛点之一就是 如何在本地机器上接收并调试 webhook。传统做法是使用 ngrok 或类似的隧道服务,但这会带来额外的步骤、费用或不稳定性。下面介绍一种更简洁、免费且可靠的方式——使用 Stripe CLI


目录

  1. 前置条件
  2. 安装 Stripe CLI
  3. 登录并获取 API 密钥
  4. 启动本地 webhook 监听
  5. 在代码中验证签名
  6. 发送测试事件
  7. 常见问题与故障排除

前置条件

  • 已有 Stripe 账户(如果没有,请先注册)。
  • 本地已经有一个运行中的 web 服务器,能够接受 POST 请求(例如 http://localhost:4242/webhook)。
  • 熟悉基本的 Node.js / Express(或你使用的其他语言/框架)代码结构。

安装 Stripe CLI

注意:下面的命令适用于 macOS 与 Linux。Windows 用户可以使用 PowerShellWSL,或直接下载可执行文件。

# macOS (Homebrew)
brew install stripe/stripe-cli/stripe

# Linux (apt)
curl -L https://stripe.com/files/stripe-cli-0.215.0-linux-amd64.tar.gz | tar xz
sudo mv stripe /usr/local/bin/

# Windows (PowerShell)
iwr https://stripe.com/files/stripe-cli-0.215.0-windows-x86_64.zip -OutFile stripe.zip
Expand-Archive .\stripe.zip -DestinationPath $env:USERPROFILE\stripe-cli

安装完成后,运行 stripe version 以确认安装成功。


登录并获取 API 密钥

stripe login

此命令会在浏览器中打开 Stripe 登录页面,完成后 CLI 会自动保存 access token。随后,你可以在本地的 ~/.config/stripe/config.toml(或 Windows 的相应位置)中看到已配置的 API 密钥


启动本地 webhook 监听

使用 stripe listen 命令可以让 Stripe 将所有 webhook 事件转发到你的本地端点,而不需要任何第三方隧道服务。

stripe listen --forward-to localhost:4242/webhook

运行后,你会看到类似下面的输出:

> Ready! Your webhook endpoint secret is whsec_XXXXXXXXXXXXXXXXXXXXXXXX
> Forwarding events to http://localhost:4242/webhook
  • whsec_...:这是 Stripe 为本次会话生成的 签名密钥,稍后需要在代码中使用它来验证事件的真实性。
  • --forward-to:指定本地接收 webhook 的完整 URL(包括端口和路径)。

小技巧:如果你的本地服务器运行在不同的端口或路径,只需相应修改 --forward-to 参数即可。


在代码中验证签名

下面以 Node.js + Express 为例,演示如何使用官方提供的 stripe 包来验证 webhook 签名。

const express = require('express');
const app = express();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET; // 上一步得到的 whsec_...

// Stripe 要求原始请求体(raw body)用于签名校验
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const sig = req.headers['stripe-signature'];

  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
  } catch (err) {
    console.error(`⚠️  Webhook signature verification failed.`, err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // 处理不同类型的事件
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log(`💰 PaymentIntent succeeded: ${paymentIntent.id}`);
      // TODO: 业务逻辑(如更新订单状态)
      break;
    // 其他事件...
    default:
      console.log(`🔔 Received unhandled event type: ${event.type}`);
  }

  res.json({received: true});
});

app.listen(4242, () => console.log('🚀 Server listening on port 4242'));

关键点

  1. express.raw({type: 'application/json'}):确保 Express 不会先对请求体进行 JSON 解析,从而保留原始字节用于签名校验。
  2. stripe.webhooks.constructEvent:官方提供的安全校验方法。若校验失败,务必返回 400,防止伪造请求。

发送测试事件

Stripe CLI 允许你直接触发各种事件,无需实际进行支付流程。

# 触发一次成功的支付意图(payment_intent.succeeded)
stripe trigger payment_intent.succeeded

CLI 会在后台创建一个模拟的 PaymentIntent,并将对应的 webhook 发送到你本地的 /webhook 端点。终端会显示类似:

> Triggered event payment_intent.succeeded
> Sent event to http://localhost:4242/webhook (status: 200)

如果你的代码返回 200,则表示 webhook 已成功接收并处理。


常见问题与故障排除

场景可能原因解决方案
收到 404本地服务器未在指定端口运行或路径不匹配确认 stripe listen --forward-to 中的 URL 与服务器路由一致
签名校验失败 (Invalid signature header)使用了错误的 whsec_ 密钥或请求体被中间件修改重新复制 stripe listen 输出的密钥,确保 express.raw 未被其他中间件覆盖
CLI 报错 “Unable to connect to Stripe”本地网络受限或未登录再次运行 stripe login,或检查防火墙/代理设置
本地服务器卡死express.json()express.raw() 同时使用导致冲突只在 webhook 路由使用 express.raw,其他路由可以继续使用 express.json
想在生产环境使用相同代码生产环境不需要 stripe listen,而是直接使用 Stripe Dashboard 配置的 webhook URLendpointSecret 设置为 Dashboard 中对应的 Signing secret,并移除 stripe listen 相关步骤

小结

使用 Stripe CLI,你可以:

  • 免除 ngrok/本地隧道 的额外配置。
  • 实时获取签名密钥,确保 webhook 的安全性。
  • 一键触发各种事件,快速验证业务逻辑。

只需几条命令,就能在本地完成完整的 webhook 开发与调试流程。祝你玩得开心,集成顺利! 🚀

如果你曾经集成过 Stripe 支付,你一定了解其中的流程:Stripe 会向一个 公共 URL 发送 webhook 事件,而你的开发服务器却运行在 localhost:3000。你需要这些事件实时到达本机,以便能够:

  • 测试支付流程
  • 处理订阅变更
  • 调试边缘案例的 payload

在本文中,我将演示如何使用 Hooklink——一种将 webhook 转发到本地的工具,帮助你实现:

  • 永久子域名
  • 签名验证
  • 事件过滤
  • 重放功能

为什么不使用常见的变通方案?

工具优点缺点
Stripe CLI开箱即用,适用于 Stripe仅适用于 Stripe——需要为 GitHub、Shopify、Slack 等使用其他工具
ngrok通用隧道免费套餐的 URL 每次重启都会更改,无法重放 webhook,且没有内置签名验证
Deploy to staging公开端点反馈循环慢,失去在本地设置断点的能力

步骤详解:从零开始在本机实时接收 Stripe 事件

  1. 前往 app.hooklink.net/register 并注册。
  2. 免费计划 包含 每周 2,500 次请求——足够用于开发。

2. 创建 Stripe 端点

  1. 在 Hooklink 仪表盘,进入 Endpoints → Create Endpoint

  2. 选择 Stripe 模板(最快路径):

    • Integrations → 找到 Stripe 卡片 → Use Template

    对话框会预填以下字段:

字段值(示例)
Keywordstripe(你的 URL 将变为 https://stripe‑yourname.hooklink.net
Local targethttp://localhost:3000/api/webhooks/stripe
Source allowlist所有 12 个官方 Stripe webhook IP 段(已预加载)
Event filter常用事件,如 payment_intent.succeededcheckout.session.completedinvoice.paid 等。
  1. Local target URL 调整为与你项目的 webhook 路径相匹配,然后点击 Create

你的端点现在已经在一个 永久且易记的 URL 上可用:

https://stripe-yourname.hooklink.net

注意: 此 URL 永不更改,因此无需在 Stripe 仪表盘中不断更新。

  1. 在 Stripe 仪表盘:Developers → WebhooksAdd endpoint
  2. 粘贴 Hooklink URL:https://stripe-yourname.hooklink.net
  3. 选择想要接收的事件(例如 payment_intent.succeededcheckout.session.completedcustomer.subscription.created)。
  4. 点击 Add endpoint

4. 启用签名验证

Stripe 会在 Stripe-Signature 头部使用 HMAC‑SHA256 对每个 webhook 进行签名。

  1. 在 Stripe 的 webhook 设置中,复制 Signing secret(以 whsec_ 开头)。

  2. 在 Hooklink 的端点设置中,启用 Signature Verification

    • Algorithm: HMAC‑SHA256
    • Header: Stripe-Signature
    • Signing secret: 粘贴从 Stripe 获得的值

Hooklink 能原生解析 Stripe 的签名格式 (t=timestamp,v1=signature),构造签名负载为 {timestamp}.{body},并进行恒定时间比较。它还会根据可配置的容差窗口(默认 5 分钟)检查时间戳,以防重放攻击。

# 全局安装
npm install -g @hooklink/cli

Dashboard → API Keys 生成 API 密钥,然后登录:

hooklink login --key hlk_your_api_key_here

6. 连接到你的 Stripe 端点

hooklink connect stripe

你会看到类似以下的输出:

$ hooklink connect stripe

  Connection Details:
    Version:      v1.2.0
    Endpoint:     stripe
    Webhook URL:  https://stripe-yourname.hooklink.net
    Target:       http://localhost:3000/api/webhooks/stripe

  Waiting for webhooks...

现在,每个 Stripe webhook 都会通过持久的 WebSocket 连接实时转发到你的本地服务器。

7. 测试整个流程

  1. 在 Stripe 的 webhook 设置中,点击 Send test webhook 并选择一个事件(例如 payment_intent.succeeded)。
  2. 在终端中你会看到:
stripe   POST --> payment_intent.succeeded
stripe   POST  payment_intent.succeeded
stripe   POST  push
github   POST <-- 200   8ms
preview  GET      /dashboard  200

安装

npm install -g @hooklink/cli

身份验证

hooklink login --key hlk_your_key

连接到端点

  • 单个端点(Stripe)

    hooklink connect stripe
  • 多个端点(Stripe、GitHub、Preview)

    hooklink connect stripe,github,preview

实用命令

  • 查看最近的 webhook 日志

    hooklink logs --endpoint stripe
  • 检查连接状态

    hooklink status

在本地测试 Stripe webhook 不必痛苦。使用 Hooklink,你可以获得:

  • 一个 永久 URL,即使重启也能保持
  • 内置的 Stripe 签名验证
  • 事件过滤来源 IP 白名单
  • 一键 webhook 重放
  • 免费的完整请求日志

免费套餐提供 每周 2,500 次请求,覆盖 3 个端点,并包含完整请求日志——足以满足大多数开发工作流的需求。

快速开始(无需注册)

npx @hooklink/cli listen 3000

30 秒内即可拥有一个公开的 webhook URL。

0 浏览
Back to Blog

相关文章

阅读更多 »