Как обрабатывать действия после успешной транзакции PayPal с помощью paypal-checkout-server-sdk

#javascript #node.js #paypal

Вопрос:

Я хочу создать страницу пожертвований для своего веб-сайта, чтобы люди могли делать пожертвования и получать подарки за пожертвования, и я обнаружил API PayPal, а затем на клиенте появляются кнопки, и если вы нажмете на них, вы сможете оплатить с помощью PayPal или кредитной карты, но моя проблема в том, что я еще не понял, как обработать успешный платеж на сервере.

На Клиенте я смог обработать успешный платеж , добавив .then(details) после return actions.order.capture() , но это было слишком небезопасно для меня, чтобы обрабатывать данные на клиенте.

Код клиента:

 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)
    }
})
 

Ответ №1:

действия.порядок.захват() и действия.порядок.создание() являются кодом на стороне клиента.

Не используйте ни одну из функций для интеграции с сервером. Как создание, так и захват должны выполняться из одного и того же места.

Вашей onApprove функции необходимо вызвать маршрут на вашем сервере, чтобы выполнить захват. В разделе «Настройка стандартных платежей» в разделе «Добавление и изменение кода» приведены ссылки с подробными сведениями и образцами кода, которые объясняют интеграцию с сервером. В частности, ссылка на этот демонстрационный шаблон, который показывает правильную обработку ошибок на стороне клиента при записи на сервере.