Saturday, 22 September 2018

PayPal SDK + node express + heroku

project linkhttps://chuanshuoge2-paypal-node.herokuapp.com/

get testing buyer and store account from paypal developer, by logging in real paypal account

in app&credentials get store client ID and secret, paste in app.js

store web page, buyer purchase 555.55

redirect buyer to login page, enter buyer sandbox paypal, continue

buyer's password can be changed in https://developer.paypal.com/developer/accounts/, account detail

transaction success , receipt sent

transaction cancelled

buyers account, 555.55 is charged

store account, 555.55 in

--app.js
--package.json
--views
  --index.ejs
--public
  --sale.png
--.gitignore

------------------------------------------

package.json

{
  "name": "paypal",
  "version": "1.0.0",
  "description": "paypal app",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^2.6.1",
    "express": "^4.16.3",
    "paypal-rest-sdk": "^1.8.1"
  }
}

----------------------------------------

app.js

const express = require('express');
const paypal = require('paypal-rest-sdk');
const path = require('path');
const bodyParser = require('body-parser');
const exphbs = require('ejs');

paypal.configure({
    'mode': 'sandbox',
    'client_id': 'Aa0fwwAFGqliwRTrBgHaEPZ2Ry3lqcynylfgNU0KuHO4W6vDJ-_hiF44-k4_6FTlT9iLBkuDqJ8Gse4P',
    'client_secret': 'EEYSP5SgoxnZ5rlZag4gleJP4FuITpp5wGfv0GotpcPWkgaM9pXPfzIWiNhguIAaKTEwwPNx4-U_1bDF'
})

const app = express();

app.set('view engine', 'ejs');

//Body parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

//Set static Folder
app.use(express.static(path.join(__dirname, './public')));

app.get('/', (req, res) => res.render('index'));

app.post('/pay', (req, res) => {

    // Build PayPal payment request
    const payReq = JSON.stringify({
        intent: 'sale',
        payer: {
            payment_method: 'paypal'
        },
        redirect_urls: {
            return_url: req.headers.origin + '/success',
            cancel_url: req.headers.origin + '/cancel'
        },
        transactions: [{
            amount: {
                total: req.body.price.toString(),
                currency: 'CAD'
            },
            description: 'one time charge'
        }]
    });

    console.log('payment ' + req.body.price.toString()+' request created')

    //create payment
    paypal.payment.create(payReq, function (error, payment) {
        let links = {};

        if (error) {
            console.error(JSON.stringify(error));
            res.send(JSON.stringify(error));
        } else {
     
            //sample approval_url href:
            //'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-6BG01810KP0350828',

            payment.links.forEach(function (linkObj) {
                links[linkObj.rel] = {
                    href: linkObj.href,
                    method: linkObj.method
                };
            })

            console.log('payment approval url: ' + links['approval_url'].href);

            if (links.hasOwnProperty('approval_url')) {
                // Redirect the customer to links['approval_url'].href
                res.redirect(links['approval_url'].href);
            } else {
                console.error('no redirect URI present');
                res.send('no redirect URI present');
            }
        }
    });
});

app.get('/success', (req, res) => {
    const paymentId = req.query.paymentId;
    const payerId = { payer_id: req.query.PayerID };
   
    //execute payment
    paypal.payment.execute(paymentId, payerId, function (error, payment) {
        if (error) {
            console.error(JSON.stringify(error));
        } else {
            if (payment.state == 'approved') {
                console.log('payment completed successfully');
                console.log(payment);
                res.send('payment success <br/>' + JSON.stringify(payment).split(',').join('<br/>'));
            } else {
                console.log('payment not successful');
            }
        }
    });
});

app.get('/cancel', (req, res) => res.send('cancelled'));

//server entry port for heroku and localhost
const port = process.env.PORT || 3000;

app.listen(port, () => console.log('server started'));

-----------------------------------------------

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width-device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"/>
    <title>stripe transactions</title>
</head>
<body>
    <div class="row">
<div class="col-md-12 text-center">
<img src="/sale.png" alt="sale" class="img-fluid" /><br/><br/>

<form action="/pay" method="post">
Price: $<input type="number" id="price" placeholder='123.45' step=".01"
                   onchange='priceChange()'/><br /><br />

<input type="hidden" id="priceSent" name="price" value="123.45" />

<button type="submit" class="btn-primary btn-block">Purchase</button><br />
</form>
</div>

</div>

<script>
function priceChange() {
document.getElementById("priceSent").value = document.getElementById("price").value;
        }

</script>
</body>
</html>
  
----------------------------------

reference:
https://www.youtube.com/watch?v=7k03jobKGXM
https://developer.paypal.com/docs/api/quickstart/#how-to-use-this-guide
https://developer.paypal.com/developer/accounts/
https://www.sandbox.paypal.com

https://stackoverflow.com/questions/21520244/how-to-simply-send-a-request-parameter-with-jquery-form-submit
https://stackoverflow.com/questions/18679690/heroku-nodejs-app-with-r10-h10-and-h20-errors
https://stackoverflow.com/questions/20705602/how-can-i-check-in-which-url-my-node-js-server-is-running

No comments:

Post a Comment