【发布时间】:2021-09-30 16:37:30
【问题描述】:
我创建了一个 Stripe webhook,我想在购买 Stripe 时将数据写入 Firebase,但它无法正常工作,尽管付款总是成功,但数据并未发送到 Firebase 数据库。
在 Stripe 控制台中,我收到以下错误:
Webhook 错误:未找到与有效负载的预期签名匹配的签名。您是否传递了从 Stripe 收到的原始请求正文? https://github.com/stripe/stripe-node#webhook-signing
以下是我的 webhook 的代码:
import { buffer } from "micro";
import * as admin from "firebase-admin";
// Secure a connection to firebase
const serviceAccount = require("../../../permession.json");
const app = !admin.apps.length
? admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
})
: admin.app();
// Stripe
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const endpointSecurit = process.env.STRIPE_SIGNING_SECRET;
const fullfillOrder = async (session) => {
console.log("Fullfilling Order!!!");
return app
.firestore()
.collection("users")
.doc(session.metadata.email)
.collection("orders")
.doc(session.id)
.set({
amount: session.amount_total / 100,
amount_shipping: session.total_details_amount_shipping / 100,
images: JSON.parse(session.metadata.images),
title: JSON.parse(session.metadata.titles),
timestamp: admin.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log(`SUCCESS: Order ${session.id} has been added to DB!`);
});
};
export default async (req, res) => {
if (req.method === "POST") {
const requestBuffer = await buffer(req);
const payload = requestBuffer.toString();
const sig = req.headers["stripe-signature"];
let event;
// Verify (came from stripe)
try {
event = await stripe.webhooks.constructEvent(
payload,
sig,
endpointSecurit
);
} catch (e) {
console.log("ERROR", e.message);
return res.status(400).send({ message: "Webhook error: " + e.message });
}
if (event.type === "checkout.session.completed") {
const session = event.data.object;
// Fullfill the order
return fullfillOrder(session)
.then(() => res.status(200))
.catch((e) =>
res.status(400).send({ message: "WEBHOOK_ERROR: " + e.message })
);
}
}
};
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
感谢您的帮助。
【问题讨论】:
-
你可以试试
const payload = req.rawBody吗? -
@Dharmaraj 我试过了,但它给出了同样的错误。
-
你能与 req.rawBody 分享更新的代码吗?
-
const event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret);这应该可以。 -
在 Node 中获取实际的原始主体非常困难,因为主体很容易在您获得它之前进行修改。如果上面提出的解决方案不起作用,这里有很多不同的可能解决方案来解决这个问题:github.com/stripe/stripe-node/issues/341
标签: firebase google-cloud-firestore next.js stripe-payments webhooks