In this example, we're going to set up an Express server integration to display how to process a payment with PayPal, using the PayPal Node SDK. We will use a static JSON structure for the payment details for the sake of brevity.
There are three general steps that we will follow when building out the functions to handle the PayPal payment:
Breaking this down as a simple Node app, we start by obtaining the PayPal Node SDK from NPM:
npm install paypal-rest-sdk
Next, we set up the app configuration and packages.
var http = require('http'),
paypal = require('paypal-rest-sdk'),
bodyParser = require('body-parser'),
app = require('express')();
var client_id = 'YOUR APPLICATION CLIENT ID';
var secret = 'YOUR APPLICATION SECRET';
//allow parsing of JSON bodies
app.use(bodyParser.json());
//configure for sandbox environment
paypal.configure({
'mode': 'sandbox', //sandbox or live
'client_id': client_id,
'client_secret': secret
});
We require four requirements for this app:
The next few lines set up variables for the client ID and secret that were obtained when creating an application. We then set up bodyParser
to allow for JSON encoded bodies, then configure our application using the application details, and specify the environment that we are working in (live for production or sandbox for testing).
Now let's create the route for creating a payment request with PayPal.
app.get('/create', function(req, res){
//build PayPal payment request
var payReq = JSON.stringify({
'intent':'sale',
'redirect_urls':{
'return_url':'http://localhost:3000/process',
'cancel_url':'http://localhost:3000/cancel'
},
'payer':{
'payment_method':'paypal'
},
'transactions':[{
'amount':{
'total':'7.47',
'currency':'USD'
},
'description':'This is the payment transaction description.'
}]
});
paypal.payment.create(payReq, function(error, payment){
if(error){
console.error(error);
} else {
//capture HATEOAS links
var links = {};
payment.links.forEach(function(linkObj){
links[linkObj.rel] = {
'href': linkObj.href,
'method': linkObj.method
};
})
//if redirect url present, redirect user
if (links.hasOwnProperty('approval_url')){
res.redirect(links['approval_url'].href);
} else {
console.error('no redirect URI present');
}
}
});
});
The first thing we do is set up the payment request JSON object, which contains the information that we need to provide PayPal with to create the payment. We set the intent
to sale
, specify the redirect URLs (where PayPal should forward the user to after they confirm / cancel the payment), add in a payment_method
of paypal
to signal that we will make a PayPal payment, then specify the transaction information for the payer to confirm.
We then call payment.create(...)
, passing in our payReq
object. This will send the create payment request to PayPal. Once that returns, and is successful, we can loop through the provided HATEOAS links in the return object to extract the URL that we need to redirect the user to, which is labeled under approval_url
.
The format for the HATEOAS links can cause fragile reference code if used directly, so we loop through all provided links and put them in a better reference object to future proof against changes. If the approval_url
is then found in that object, we redirect the user.
At this point the user is redirected to PayPal to confirm the payment. Once they do, they are redirected back to the return_url
that we specified in the createPayment(...)
function.
We now have to provide a route to handle that return, in order to complete the payment.
app.get('/process', function(req, res){
var paymentId = req.query.paymentId;
var payerId = { 'payer_id': req.query.PayerID };
paypal.payment.execute(paymentId, payerId, function(error, payment){
if(error){
console.error(error);
} else {
if (payment.state == 'approved'){
res.send('payment completed successfully');
} else {
res.send('payment not successful');
}
}
});
});
When the user is returned back to your app, there will be three query string parameters that will be sent along as well, the paymentId
, PayerID
, and token
. We only need to deal with the first two.
We extract the parameters, and place the PayerID in a simple object for the need of the payment execution step. Next, a call is made to payment.execute(...)
, passing in those two parameters, in order to complete the payment.
Once that request is made, we see if the payment completed successfully by checking if payment.state
is set to approved
. If so, we can store what we need from the payment object that is returned.
Our last step is to initialize our server and listen for traffic coming to the routes we specified.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});
Once the server is initialized, going to http://localhost:3000/create
initializes the payment process.