Stripe Webhook没有执行回调。是我漏掉了什么吗?

huangapple go评论59阅读模式
英文:

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.

英文:

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 ,Stripe Webhook没有执行回调。是我漏掉了什么吗?

huangapple
  • 本文由 发表于 2023年5月15日 04:35:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定