我是第一次尝试使用 Stripe webhooks。以下是调用“/webhook”端点时返回的响应👇🏻
{
"type": "StripeSignatureVerificationError",
"raw": {
"message": "No stripe-signature header value was provided."
},
"payload": {}
}
我已阅读并遵循 Stripe 官方文档中概述的步骤,但是,它似乎无法正常工作,而且我不明白我所缺少的内容。
// stripe.service.ts
import config from 'config';
import Stripe from 'stripe';
const stripeSecretKey = config.get<string>('stripeSecretKey');
export const stripe = new Stripe(stripeSecretKey, {
apiVersion: '2023-10-16',
typescript: true,
});
// webhook.controller.ts
import config from 'config';
import { Request, Response, NextFunction } from 'express';
import { stripe } from '@/services/stripe.service';
const stripeWebhookSigningSecret = config.get<string>('stripeWebhookSigningSecret');
export const webhookController = async (
req: Request,
res: Response,
next: NextFunction
) => {
const payload = req.body;
const sig = req.headers['stripe-signature'] as string;
let event;
try {
event = stripe.webhooks.constructEvent(
payload,
sig,
stripeWebhookSigningSecret
);
} catch (error) {
return res.status(400).send(error);
}
console.log(event.type);
console.log(event.data.object);
return res.json({ received: true });
};
// routes.ts
app.post(
'/webhook',
bodyParser.raw({ type: 'application/json' }),
webhookController
);
以下是我在 CLI 中遵循的流程👇🏻
- npm run dev
> API is running on http://localhost:3000.
- stripe login
- stripe listen --forward-to localhost:3000/webhook
> Ready! You are using Stripe API Version [2022-11-15]. Your webhook signing secret is whsec_xxx
2023-10-26 23:43:26 --> charge.succeeded [evt_xxx]
2023-10-26 23:43:26 <-- [400] POST http://localhost:3000/webhook [evt_xxx]
2023-10-26 23:43:26 --> payment_intent.succeeded [evt_xxx]
2023-10-26 23:43:26 <-- [400] POST http://localhost:3000/webhook [evt_xxx]
2023-10-26 23:43:26 --> payment_intent.created [evt_xxx]
2023-10-26 23:43:26 <-- [400] POST http://localhost:3000/webhook [evt_xxx]
- stripe trigger payment_intent.succeeded
> Setting up fixture for: payment_intent
Running fixture for: payment_intent
Trigger succeeded! Check dashboard for event details.
我没有从 Stripe webhooks 收到任何数据。我缺少什么?非常感谢!
我终于在这里找到了问题的解决方案:Stripe - Webhook 负载必须以字符串或缓冲区的形式提供
实际上,中间件
app.use(express.json());
必须放在端点之后。事实上,Express 将 Stripe 的签名解释为一个对象。我在我的createServer.ts
👇🏻设定了一个条件
// Body parser.
app.use((req, res, next) => {
req.path !== '/webhook' ? express.json()(req, res, next) : next();
});
这样它不适用于
/webhook
端点。