英文:
Stripe webhook doesn't execute callback. Or am I missing something?
问题
以下是您要翻译的部分:
我在Next.js中有一个与Strapi和Stripe一起的项目。在成功付款后会执行一个Webhook,之后应该运行markProductAsSold
回调函数,它确实运行了,但仅在本地主机上。而且,如果我只运行回调函数(不知道在页面上的某个按钮点击上运行),它在stage和localhost上都能正常工作!
Webhook 代码:
export const config = {
api: {
bodyParser: false,
},
};
export default async function webhookHandler(req, res) {
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET, {
apiVersion: '2022-11-15',
});
if (req.method === 'POST') {
const buf = await buffer(req);
const sig = req.headers['stripe-signature'];
const webhookSecret = process.env.NEXT_PUBLIC_STRAPI_WEBHOOK_KEY;
let event;
try {
if (!sig || !webhookSecret) return;
event = stripe.webhooks.constructEvent(buf, sig, webhookSecret);
} catch (error) {
return res.status(400).send(`Webhook error: ${error.message}`);
}
if (event.data.object.status === 'succeeded') {
await markProductAsSold(event.data.object.metadata.MarkAsSold);
}
}
res.status(200).send();
}
回调函数代码
const markProductAsSold = async (slug: string) => {
const findProduct = await fetch(
`${process.env.NEXT_PUBLIC_DATABASE_URL}/api/products?filters[slug][$eq]=${slug}`
);
const data = await findProduct.json();
const isSold = data.data[0].attributes.isSold;
const productData = {
...data.data[0]
};
productData.attributes.isSold = !isSold;
await fetch(
`${process.env.NEXT_PUBLIC_DATABASE_URL}/api/products/${productData.id}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_STRAPI_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: productData.attributes,
}),
}
);
return productData;
};
export default markProductAsSold;
所有数据,如metadata.MarkAsSold
或环境变量都是100%有效且经过三次检查。我只是不知道问题可能出在哪里,因为回调函数仅在Stripe Webhook在stage上触发后不起作用。
问题已解决
原来我的回调函数在Stripe触发后并没有运行。不知道为什么,但当我将markProductAsSold
函数直接移到if (event.data.object.status === 'succeeded')
中时,它开始正常工作。
英文:
I have a project in Next.js with Strapi & Stripe. There is a webhook that is executed after successful payment and after that, it should run markProductAsSold
callback, and it does but only at localhost. Also if I run only a callback (idk. on button click somewhere on a page) it's working on stage and localhost!
Webhook code:
export const config = {
api: {
bodyParser: false,
},
};
export default async function webhookHandler(req, res) {
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET, {
apiVersion: '2022-11-15',
});
if (req.method === 'POST') {
const buf = await buffer(req);
const sig = req.headers['stripe-signature'];
const webhookSecret = process.env.NEXT_PUBLIC_STRAPI_WEBHOOK_KEY;
let event;
try {
if (!sig || !webhookSecret) return;
event = stripe.webhooks.constructEvent(buf, sig, webhookSecret);
} catch (error) {
return res.status(400).send(`Webhook error: ${error.message}`);
}
if (event.data.object.status === 'succeeded') {
await markProductAsSold(event.data.object.metadata.MarkAsSold);
}
}
res.status(200).send();
}
Callback code
const markProductAsSold = async (slug: string) => {
const findProduct = await fetch(
`${process.env.NEXT_PUBLIC_DATABASE_URL}/api/products?filters[slug][$eq]=${slug}`
);
const data = await findProduct.json();
const isSold = data.data[0].attributes.isSold;
const productData = {
...data.data[0]
};
productData.attributes.isSold = !isSold;
await fetch(
`${process.env.NEXT_PUBLIC_DATABASE_URL}/api/products/${productData.id}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_STRAPI_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: productData.attributes,
}),
}
);
return productData;
};
export default markProductAsSold;
All data like metadata.MarkAsSold
or env's are 100% valid and triple checked. I just don't know where could be a problem cause callback doesn't work only after being fired on stage by Stripe webhook.
Solved
It turns out that my callback wasn't running after everything was triggered by Stripe. Idk. why but when I moved markProductAsSold
function directly into if (event.data.object.status === 'succeeded')
it started to working.
答案1
得分: 1
你需要在生产环境中注册您的应用程序。您应该已经在开发环境中运行了此命令。
// 安装 Stripe CLI
// API/Webhook 您的端点
stripe listen --events checkout.session.completed --forward-to localhost:3000/api/webhook
同样,您应该注册您的生产端点。
您可以参考 webhooks/go-live 文档
英文:
you had to register your app in production. you should already have run this commmand for development.
// installed stripe cli
// api/webhook your enpoint
stripe listen --events checkout.session.completed --forward-to localhost:3000/api/webhook
similarly you should register your production endpoint.
you can follow webhooks/go-live docs
答案2
得分: 0
Verify you webhook secret key, remember there is two keys for webhook one that work on in localhost and second for production in stripe developer signing secret.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论