Stripe 事件:`checkout.session.async_ payment_succeeded` 与 `checkout.session.completed`。使用哪一款才能成功付款?

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

我对这两个事件有点困惑:

checkout.session.async_payment_succeeded
&
checkout.session.completed

我目前正在使用

checkout.session.completed
,所以我很好奇
checkout.session.async_payment_succeeded
是否发送
checkout.session.completed
未处理的任何事件。

我当前的代码如下所示:

const session = event.data.object as Stripe.Checkout.Session
// Handle the event
switch (event.type) {
    case "checkout.session.completed":
        // add user email with 'paid' status to database
    case "checkout.session.async_payment_failed":
        // send error to user that payment failed
    default:
        // Unexpected event type
        console.warn(event.type, `🤷‍♀️ Unhandled event type`)
}

我有3个问题:

  1. checkout.session.completed
    可以囊括所有成功付款吗?

  2. 这段代码有什么问题吗?还是这样就可以了?

  3. 除了

    checkout.session.async_payment_succeeded
    之外,我还需要使用
    checkout.session.completed
    吗?

编辑:

我仍然很困惑,当

checkout.session.async_payment_succeeded
被调用时,如何获得
id
fulfillOrder
?目前,
session.customer_details.id
给出红色波浪线。

有没有办法测试这些付款方式:

仅当您计划使用以下任何付款方式时才需要执行此步骤:Bacs 直接借记、银行转账、Boleto、加拿大预授权借记、Konbini、OXXO、SEPA 直接借记、SOFORT 或 ACH 直接借记。

import { createId } from "@paralleldrive/cuid2"
import { error } from "next/dist/build/output/log"
import { NextRequest, NextResponse } from "next/server"
import type Stripe from "stripe"

import { createUser, updateUser } from "@/app/db/users"
import { STRIPE_WEBHOOK_SECRET } from "@/app/lib/env/server"
import { isAdmin } from "@/app/lib/isAdmin"
import { getLogger } from "@/app/lib/logger"
import { obfuscateEmail } from "@/app/lib/obfuscateEmail"
import { stripe } from "@/app/lib/stripe/server"

import { auth } from "@/app/auth/lucia"

const createOrder = async (session: any, logger: any) => {
    const email = String(session.customer_details?.email)
    const user_id = createId()
    try {
        const customer = await stripe.customers.create({
            email,
        })

        await auth.createUser({
            key: {
                providerId: "email",
                providerUserId: email.toLowerCase(),
                password: null,
            },
            attributes: {
                email: email.toLowerCase(),
                user_id,
            },
        })

        await createUser({
            id: user_id,
            stripePaymentStatus: "unpaid",
            stripeCustomerId: customer.id,
            isAdmin: isAdmin(email),
        })
    } catch (error) {
        logger.error(error, `[Stripe] Error in createOrder!`)
    }

    return user_id
}

const fulfillOrder = async (id: string, session: any, logger: any) => {
    await updateUser(id, {
        stripePaymentStatus: "paid",
    })
}

export const POST = async (req: NextRequest, res: NextResponse) => {
    const logger = getLogger()
    const body = await req.text()
    const sig = req.headers.get("stripe-signature")

    let event: Stripe.Event

    logger.info("[Stripe] Processing webhook")

    try {
        event = stripe.webhooks.constructEvent(body, sig as string, STRIPE_WEBHOOK_SECRET)

        logger.info({ type: event.type }, `[Stripe] Listening to Webhook Event!`)
    } catch (err) {
        error(err as string)
        return new Response(`Webhook Error: ${(err as Error).message}`, {
            status: 400,
        })
    }

    try {
        // Handle the event
        switch (event.type) {
            case "checkout.session.completed": {
                const session = event.data.object as Stripe.Checkout.Session

                const id = await createOrder(session, logger)

                if (session.payment_status === "paid") {
                    await fulfillOrder(id, session, logger)

                    const email = String(session.customer_details?.email)
                    logger.info({ email: obfuscateEmail(email) }, `[Stripe] 💰 Successfully charged`)
                }
            }
            case "checkout.session.async_payment_succeeded": {
                const session = event.data.object as Stripe.Checkout.Session

                await fulfillOrder(session.customer_details.id, session, logger)

                return NextResponse.json({ success: true })
            }
            case "checkout.session.async_payment_failed": {
                const session = event.data.object as Stripe.Checkout.Session

                logger.error(session, `[Stripe] Payment failed`)

                return NextResponse.json({ success: false })
            }
            default: {
                // Unexpected event type
                logger.warn(event.type, `🤷‍♀️ Unhandled event type`)
                return NextResponse.json({ success: false })
            }
        }
    } catch (err) {
        logger.error({ err }, `[Stripe] Webhook Error`)
        return NextResponse.json(
            { error: "Webhook handler failed. View logs." },
            {
                status: 400,
            }
        )
    }
}

PS:我在互联网上看到的例子只是使用

checkout.session.completed
并收工。我搜索了 Github 并使用了 Sourcegraph,但找不到有关这两个事件的更多示例。

javascript node.js next.js stripe-payments
1个回答
0
投票

这一切都在 Stripe Doc 中进行了解释。您希望 (1) 聆听所有内容,(2) 将您的代码修改为文档中的示例代码,并且 (3) 是。

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