为什么 stripe 在结帐后创建连续付款?

Why does stripe create successive payments after checkout?

我是 stripe 的新手,我正在尝试将现有网站的结帐更新到新版本的 stripe。在经历了一些困难之后,我已经(几乎)成功了,但现在我看到我的代码中有一些东西在我结账后进行了多次订阅(比如每分钟几次)。我该如何阻止它?

我的代码:

app.post('/create-checkout-session', async (req, res) => {
    // let priceId = Object.keys(req.body);
    // let objId = new ObjectId(req.body.sub_id);
    // let norma = new ObjectId(req.body.norma);
    // let rsa = new ObjectId(req.body.rsa);

    // Subscription.find({_id : objId},{"_id": 0,"stripePlanId":1})
    //     .then((result) => {
    //         console.log(result);
    //     })
    //     .catch((err) =>
    //         console.log(err));

    userId = req.user._id;

    let planId;
    let planRenewal;
    let normPlanId, rsaPlanId;
    let planName;
    let cartElements = [];

    customer = await stripe.customers.create({
        description: req.user.name,
        address : {
            country: 'PT',
        }
    });
    
    await Subscription.find({_id: req.body.sub_id})
        .then((result) => {
            planId = result[0].stripePlanId;
            planRenewal = result[0].renewalPeriod;
            planName = result[0].name;
        })
        .catch((err) =>
            console.log(err));

    cartElements.push(planId);

  const session = await stripe.checkout.sessions.create({
    line_items: cartArray,
    mode: 'subscription',
    customer: customer.id,
    success_url: `${process.env.web_app_url}/subscricoes`,
    cancel_url: `${process.env.web_app_url}`,
    automatic_tax: {enabled: true},
  });

  res.redirect(303, session.url);
});

app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
    let event;

    // try {
        event = stripe.webhooks.constructEvent(req.body, req.header('stripe-signature'), endpointSecret);
    // } catch (err) {
    //     console.log(err);
    //     return res.sendStatus(400)
    // }

    if (event.type === 'payment_intent.succeeded') {
        const data = event.data.object;
        
        const paymentMethod = event.data.object.payment_method;
        // const customer = event.data.object.customer;

        // attach payment to customer
        const attachPaymentToCustomer = await stripe.paymentMethods.attach(
            paymentMethod,  // <-- your payment method ID collected via Stripe.js
        { customer: customer.id } // <-- your customer id from the request body  
        );

        //create subscription
        const subscription = await stripe.subscriptions.create({
            customer: customer.id,
            items: [{ plan: 'plan_DznNb3tPEEI0cj' }],
            default_payment_method: paymentMethod,
            expand: ['latest_invoice.payment_intent']
        });
       
        await User.updateOne(
            {_id: ObjectId(userId) },
            {$set: { "stripeCustomer": customer}},
        );

        await User.updateOne(
            {_id: ObjectId(userId) },
            {$set: { "stripeCustomer.subscriptions": subscription}},
        );
    }

    res.sendStatus(200);
});


在订阅模式下创建结帐会话时,付款方式将附加到客户并创建订阅。这就是为什么您不需要在 webhook 端点中处理任何这些的原因。

为了清楚起见,这里发生的是你的 webhook 端点代码正在侦听 payment_intent.succeeded 事件,这将在结账会话已支付时发生,然后你正在创建一个对同一客户的新订阅随后会导致另一个 payment_intent.succeeded 事件,依此类推。

我建议删除这部分 webhook 端点代码并按照本指南https://stripe.com/docs/payments/checkout/fulfill-orders#fulfill 处理结帐会话完成后的实现。