如何使用 paypal-checkout-server-sdk 处理 PayPal 交易成功后的操作

How to handle actions after a PayPal transaction succeded using paypal-checkout-server-sdk

我想为我的网站制作一个捐赠页面,这样人们就可以捐赠和接收捐赠礼物,我发现了 PayPal API 然后在客户端上出现了按钮,如果你点击它们就可以支付使用 PayPal 或信用卡,但我的问题是我还没有弄清楚如何在服务器上处理成功的付款。

在客户端上,我可以通过在 return actions.order.capture() 之后添加 .then(details) 来处理成功的付款,但是在客户端上处理这些东西对我来说太不安全了。

客户代码:

paypal.Buttons({
    createOrder: function () {
        return fetch('/create-order', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                items: [{
                    id: 2,
                    quantity: 1
                }],
            })
        }).then((res) => {
            if (res.ok) return res.json()
            return res.json().then(json => Promise.reject(json))
        }).then(({ id }) => {
            return id
        }).catch((err) => {
            console.error(err)
        })
    },
    onApprove: function (data, actions) {
        return actions.order.capture().then((details) => {
            alert('Transaction completed by ' + details.payer.name.given_name)
            console.log(details)
        })
    },
}).render("#paypal")

服务器代码:

// Add a little percentage for the USD to EUR conversition rate
const storeItems = new Map([
    [1, { price: Math.round(50 * 1.1), name: '50€ Donation', }],
    [2, { price: Math.round(25 * 1.1), name: '25€ Donation' }],
    [3, { price: Math.round(10 * 1.1), name: '10€ Donation' }],
    [4, { price: Math.round(5 * 1.1),  name: '5€ Donation' }],
])

app.get('/', (req, res) => {
    res.render('index', { clientId: process.env.PAYPAL_CLIENT_ID })
})

app.post('/create-order', async (req, res) => {
    const request = new paypal.orders.OrdersCreateRequest()
    const total = req.body.items.reduce((sum, item) => {
        return sum + storeItems.get(item.id).price * item.quantity
    }, 0)
    request.prefer('return=representation')
    request.requestBody({
        intent: "CAPTURE",
        purchase_units: [
            {
                amount: {
                    currency_code: "USD",
                    value: total,
                    breakdown: {
                        item_total: {
                            currency_code: "USD",
                            value: total,
                        },
                    },
                },
                items: req.body.items.map(item => {
                    const storeItem = storeItems.get(item.id)
                    return {
                        name: storeItem.name,
                        unit_amount: {
                            currency_code: "USD",
                            value: storeItem.price,
                        },
                        quantity: item.quantity,
                    }
                }),
            },
        ],
    })

    try {
        const order = await paypalClient.execute(request)
        res.json({ id: order.result.id })
    } catch (err) {
        res.status(500).json({ error: err.message })
        console.error(err.message)
    }
})

actions.order.capture() 和 actions.order.create() 都是客户端代码。

不要将任何一个函数用于服务器集成。创建和捕获都应该在同一个地方完成。

您的 onApprove 函数需要调用服务器上的路由来执行捕获。 Set up standard payments, in the part of 'Add and modify the code' that explains a server integration. Particularly a link to this demo pattern 中有详细信息和示例代码的链接,显示在服务器上捕获时正确的客户端错误处理。