我正在按照这个指南设置Stripe订阅付款。
在第4步(提供和监控订阅)中,Stripe告诉我们设置一个Webhook来处理订阅事件。
当收到webhook事件时,可以对其签名进行身份验证,以确保它是由Stripe发送的,而不是恶意的第三方。
但是在他们的代码示例中,在验证签名之后,他们包含了一个else
块,用于直接从请求体中检索未签名事件的事件数据。
我不明白他们为什么要把它包括进去。难道不应该是一个或另一个,而不是两个都允许吗?
我的理解是两者都否定了webhook认证的意义,因为现在允许签名和非签名事件。
如果我有webhook签名设置,我应该删除else
块吗?
您可以在下面的第28-33行看到示例代码。
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = require('stripe')('API_KEY_GOES_HERE');
app.post("/webhook", async (req, res) => {
let data;
let eventType;
// Check if webhook signing is configured.
const webhookSecret = {{'STRIPE_WEBHOOK_SECRET'}}
if (webhookSecret) {
// Retrieve the event by verifying the signature using the raw body and secret.
let event;
let signature = req.headers["stripe-signature"];
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
webhookSecret
);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`);
return res.sendStatus(400);
}
// Extract the object from the event.
data = event.data;
eventType = event.type;
} else {
// Webhook signing is recommended, but if the secret is not configured in `config.js`,
// retrieve the event data directly from the request body.
data = req.body.data;
eventType = req.body.type;
}
switch (eventType) {
case 'checkout.session.completed':
// Payment is successful and the subscription is created.
// You should provision the subscription and save the customer ID to your database.
break;
case 'invoice.paid':
// Continue to provision the subscription as payments continue to be made.
// Store the status in your database and check when a user accesses your service.
// This approach helps you avoid hitting rate limits.
break;
case 'invoice.payment_failed':
// The payment failed or the customer does not have a valid payment method.
// The subscription becomes past_due. Notify your customer and send them to the
// customer portal to update their payment information.
break;
default:
// Unhandled event type
}
res.sendStatus(200);
});
我直接联系了Stripe,他们建议"应该是其中之一,而不是两者兼而有之"。
因此,如果您有Webhook签名设置,那么您应该将签名身份验证从if/else
块中取出,从而使if/else
无用,因此也将其删除。
以下是更新后的版本:
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = require('stripe')('API_KEY_GOES_HERE');
app.post("/webhook", async (req, res) => {
// Check if webhook signing is configured.
const webhookSecret = {{'STRIPE_WEBHOOK_SECRET'}}
// Retrieve the event by verifying the signature using the raw body and secret.
let event;
let signature = req.headers["stripe-signature"];
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
webhookSecret
);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`);
return res.sendStatus(400);
}
// Extract the object from the event.
let data = event.data;
let eventType = event.type;
switch (eventType) {
case 'checkout.session.completed':
// Payment is successful and the subscription is created.
// You should provision the subscription and save the customer ID to your database.
break;
case 'invoice.paid':
// Continue to provision the subscription as payments continue to be made.
// Store the status in your database and check when a user accesses your service.
// This approach helps you avoid hitting rate limits.
break;
case 'invoice.payment_failed':
// The payment failed or the customer does not have a valid payment method.
// The subscription becomes past_due. Notify your customer and send them to the
// customer portal to update their payment information.
break;
default:
// Unhandled event type
}
res.sendStatus(200);
});