如何在生成 payment_intent 时获取元数据内 Stripe webhook 中 payment_link 生成过程中传递的自定义字段

问题描述 投票:0回答:1

我已经创建了一个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。

stripe-payments webhooks payment-gateway stripe-payment-intent
1个回答
0
投票

支付链接是一个可重复使用的支付URL,即客户可以在同一URL上多次支付,并且使用支付链接的所有支付的元数据都是相同的。

对于一次性付款 URL,我建议使用 Checkout Session。结账会话支持使用

price_data
的临时价格(您不需要先预先创建价格对象)。

Stripe 不会从一个对象填充到另一个对象,即支付链接创建请求中设置的

metadata
不会填充到支付意图对象。要在付款意图中显示元数据,我建议在创建一次性
结账会话
或可重复使用的付款链接时在请求中设置payment_intent_data.metadata

参考:https://docs.stripe.com/metadata#set-indirectly

© www.soinside.com 2019 - 2024. All rights reserved.