PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, November 22, 2022

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

 November 22, 2022     javascript, node.js, paypal     No comments   

Issue

I want to make a Donation page for my website, so people can donate and receive gifts for donation and i discovered the PayPal API and then on client there appear buttons and if you click them you can pay with PayPal or credit card, but my problem is that I didn't yet figure out how to handle the succeeded Payment on the Server.

On the Client I was able to handle the succeeded payment by adding .then(details) after return actions.order.capture(), but it was too unsecure for me to handle the stuff on the client.

Client code:

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

Server Code:

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

Solution

actions.order.capture() and actions.order.create() are both client-side code.

Do not use either function for a server integration. Both creation and capture should be done from the same place.

Your onApprove function needs to call a route on your server to do to the capture. There are links with details and sample code within 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 that shows proper client-side error handling when capturing on a server.



Answered By - Preston PHX
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing