如何将Stripe关联账户支付链接Metadata传递至主账户Webhook
问题:支付链接元数据无法传递到PaymentIntent Webhook
已在关联账户的支付链接中添加invoiceId元数据,且支付链接API的请求和响应中该元数据存在,但主账户Webhook接收的PaymentIntent元数据为空,无法获取invoiceId来更新系统内发票的支付状态,已确认Webhook请求体中Metadata确实为空。
生成支付链接的API代码
import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); export async function POST(req) { try { const body = await req.json(); const { invoiceId, amount, currency, invoiceNumber, stripeAccountId } = body; const product = await stripe.products.create({ name: `Invoice #${invoiceNumber}` }, { stripeAccount: stripeAccountId }); const price = await stripe.prices.create({ product: product.id, unit_amount: currency === "JPY" ? amount : amount * 100, currency: currency }, { stripeAccount: stripeAccountId // Specify the connected account ID }); const paymentLink = await stripe.paymentLinks.create({ line_items: [ { price: price.id, quantity: 1, }, ], metadata: { invoiceId: invoiceId // Add the invoice number here } }, { stripeAccount: stripeAccountId // Specify the connected account ID }); return new Response(JSON.stringify({ success: true, message: "Payment link generated successfully", url: paymentLink.url }), { status: 200, headers: { 'Content-Type': 'application/json', }, }); } catch (error) { return new Response(JSON.stringify({ success: false, message: error.message }), { status: 500, headers: { 'Content-Type': 'application/json', }, }); } }
主账户Webhook的API代码
import { NextResponse } from 'next/server'; import { stripe } from '@/utils/stripeAuth'; export async function POST(req) { let rawBody; try { // Read raw body as a string rawBody = await req.text(); } catch (err) { console.error('Error reading raw body:', err); return NextResponse.json({ success: false, message: `Failed to read request body: ${err.message}`, }, { status: 400, }); } const sig = req.headers.get('stripe-signature'); if (!sig) { return NextResponse.json({ success: false, message: 'No stripe-signature header value was provided.', }, { status: 400, }); } let event; try { // Convert the raw body string to a buffer with the correct encoding const buf = Buffer.from(rawBody, 'utf8'); // Verify the event by constructing it using the raw body buffer and the signature event = stripe.webhooks.constructEvent(buf, sig, process.env.WEBHOOK_SECRET); } catch (err) { console.error('Webhook signature verification failed:', err); return NextResponse.json({ success: false, message: `Webhook Error: ${err.message}`, }, { status: 400, }); } let paymentIntent; // Handle the event switch (event.type) { case 'payment_intent.payment_failed': paymentIntent = event.data.object; // console.log(`PaymentIntent for ${paymentIntent.amount} failed.`); break; case 'payment_intent.succeeded': paymentIntent = event.data.object; const invoiceId = paymentIntent.metadata.invoiceId; // console.log(`PaymentIntent for ${paymentIntent.amount} succeeded.`); break; default: console.log(`Unhandled event type ${event.type}`); } return NextResponse.json({ success: true, message: paymentIntent, }, { status: 200, }); }
解决方案
Stripe支付链接的元数据不会自动传递到后续生成的PaymentIntent中,需要在创建PaymentLink时,显式通过payment_intent_data.metadata字段指定要传递的元数据。
修改生成支付链接的代码,在stripe.paymentLinks.create的参数中添加payment_intent_data配置:
const paymentLink = await stripe.paymentLinks.create({ line_items: [ { price: price.id, quantity: 1, }, ], metadata: { invoiceId: invoiceId // 保留原PaymentLink的元数据(可选) }, // 添加此配置,将元数据传递给PaymentIntent payment_intent_data: { metadata: { invoiceId: invoiceId } } }, { stripeAccount: stripeAccountId });
这样用户通过支付链接完成支付时,生成的PaymentIntent会携带invoiceId元数据,主账户Webhook就能正常获取该值更新发票状态。
内容的提问来源于stack exchange,提问作者Skb_Developer
相关产品推荐
相关产品推荐

