我已经创建了一个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',
},
});
}
}
现在已成功使用我传递的元数据在 Stripe 连接帐户中创建付款,
之后为了捕获付款状态,我在主 Stripe 帐户中创建了一个 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,
});
}
现在 paymentIntent 元数据里面是空的 “元数据”:{ },
我希望元数据中的发票 ID 能够更新我从系统创建的发票的付款状态
请帮我解决这个问题
我检查了 Stripe 主帐户中 webhook 的请求正文,我还发现该元数据为空。
我还检查了 /v1/ payment_links API 路由,因为 API 请求和响应主体元数据存在发票 ID 字段
我需要其他开发人员的帮助,了解如何将元数据从 Stripe 连接帐户上的 payment_link 传递到主 Stripe 帐户上的 Webhook。
支付链接是一个可重复使用的支付URL,即客户可以在同一URL上多次支付,并且使用支付链接的所有支付的元数据都是相同的。
对于一次性付款 URL,我建议使用 Checkout Session。结账会话支持使用
price_data
的临时价格(您不需要先预先创建价格对象)。
Stripe 不会从一个对象填充到另一个对象,即支付链接创建请求中设置的
metadata
不会填充到支付意图对象。要在付款意图中显示元数据,我建议在创建一次性结账会话或可重复使用的付款链接时在请求中设置
payment_intent_data.metadata
。