Paypal Reccuring Payment Integration with Node.js
I recently have provided consultation in a Node js project where monthly subscription via PayPal was required and payments are to be made through Paypal, so for that, I used Billing Plan and Billing Agreement API’s for PayPal. This blog will help you in how to implement the recurring payments via PayPal for monthly subscriptions. We will be using billing plans and billing agreements to create an agreement for a recurring credit card, bank card, or PayPal payment for goods or services.
Steps to integrate it in your application:
Step 1.
Go to PayPal developer website and create your app and get the client_Id and client_secret keys. Go to “My Apps & Credentials” and create an App from there. After creation of the app, copy client Id and secret, and add them to your application. For example config.json file
Click on “Create App” and enter the name of your app.
Enter your app name and account details.
We will see two different modes here “Sandbox” and “Live”. Use sandbox keys for development purpose.Once you are ready with your implementation, switch to the Live mode for your production environment.
Step 2.
For integrating the PayPal checkout button with following a piece of code.
[js]
<img src="/blog/wp-ttn-blog/uploads/2024/01/silver-rect-paypalcheckout-34px.png" alt="PayPal Checkout" />
[/js]
Step 3.
Install the PayPal rest sdk module with npm:
npm install paypal-rest-sdk –save
That’s how our package.json looks like after installing the paypal rest sdk:
[js]
{
…
"dependencies": {
…
"paypal-rest-sdk": "^1.7.1",
…
}
}
[/js]
Setting up the configuration for PayPal in our config.json file:
[js]
{
"port": 5000,
"api": {
"host": "api.sandbox.paypal.com",
"port": "",
"mode":"sandbox"
"client_id": "paypal_client_id",
"client_secret": "paypal_client_secret"
}
}
[/js]
Step 4.
Initializing the PayPal configuration in payment.js file:
[js]
// initialize paypal configuration
init();
function init() {
Paypal.configure(config.api);
}
[/js]
Step 5.
Following code will be used to create a plan and agreement, and the user will be redirected to PayPal portal for confirmation of the agreement. Once you accepted the agreement details, we can execute the agreement.
payment.js
[js]
//Require the need modules.
var Paypal = require(‘paypal-rest-sdk’);
var Moment = require(‘moment’);
var _ = require(‘lodash’);
exports.createPaymentAgreement = function(req,res) {
//Atrributs for creating the billing plan of a user.
let billingPlanAttributes = {
"description": " Add about subscription details.",
"merchant_preferences": {
"auto_bill_amount": "yes",
"cancel_url": "http://localhost:3000/cancel",
"initial_fail_amount_action": "continue",
"max_fail_attempts": "1",
"return_url": "http://localhost:3000/success",
"setup_fee": {
"currency": "USD",
"value": "1"
}
},
"name": "Paypal Agreement",
"payment_definitions": [
{
"amount": {
"currency": "USD",
"value": "25"
},
"charge_models": [],
"cycles": "0",
"frequency": "MONTH",
"frequency_interval": 1,
"name": "Regular Payments",
"type": "REGULAR"
}
],
"type": "INFINITE"
};
//Once a billing plan is created it must be updated with the following attributes.
let billingPlanUpdateAttributes = [
{
"op": "replace",
"path": "/",
"value": {
"state": "ACTIVE"
}
}
];
//Attributes for creating the billing agreement.
//Start Date should be greater than current time and date.
let startDate = Moment(new Date()).add(10, ‘minute’).format(‘gggg-MM-DDTHH:mm:ss’)+’Z’;
let billingAgreementAttributes = {
"name": "Name of Payment Agreement",
"description": "Description of your payment agreement",
"start_date": startDate,
"plan": {
"id": ""
},
"payer": {
"payment_method": "paypal"
}
};
//Creating the billing plan and agreement of payment.
//Step 6:
Paypal.billingPlan.create(billingPlanAttributes, (error, billingPlan) => {
if (error) {
console.log(error);
} else {
//Step 7:
Paypal.billingPlan.update(billingPlan.id, billingPlanUpdateAttributes, (error, response) => {
if (error) {
console.log(error);
} else {
// update the billing agreement attributes before creating it.
billingAgreementAttributes.plan.id = billingPlan.id;
//Step 8:
Paypal.billingAgreement.create(billingAgreementAttributes,(error, billingAgreement) => {
if (error) {
console.log(error);
} else {
_.forEach(billingAgreement.links, (agreement) => {
if (agreement.rel === ‘approval_url’) {
//Redirecting to paypal portal with approvalUrl.
let approvalUrl = agreement.href;
let token = approvalUrl.split(‘token=’)[1];
console.log(approvalUrl,token);
res.redirect(approvalUrl);
}
});
}
});
}
});
}
});
}
[/js]
Step 6.
We need to create a billing plan with billing plan attributes which include payment definitions and other details. A plan must include at least one regular payment definition and, optionally, a trial payment definition. By default the plan is not active, to activate it, we need to update it’s stated to ACTIVE.
Step 7.
Next, we have to activate the billing plan with update billing plan attributes which look like:
[js]
{
"op": "replace",
"path": "/",
"value": {
"state": "ACTIVE"
}
}
[/js]
Step 8.
Our next step would be to create the billing agreement. To create an agreement, we reference an active billing plan. If the payment method “PayPal” then the user will be redirected to the PayPal portal for confirmation. We use the billing agreement attributes for creating the agreement:
[js]
{
"name": "Name of Payment Agreement",
"description": "Description of your payment agreement",
"start_date": startDate,
"plan": {
"id": ""
},
"payer": {
"payment_method": "paypal"
}
}
[/js]
Step 9.
Next, if the payment method is PayPal, we have to execute the billing agreement with the token which we would get after creating the billing Agreement:
[js]
// we will receive a token in the query parameter of our route on success of agrrement creation. Use that token for executing the billing agreement.
exports.processPaymentAgreement() = function(req , res) {
let token = req.query.token;
Paypal.billingAgreement.execute(token, {}, (error, billingAgreement) => {
if(error) {
console.log(error);
} else {
console.log(billingAgreement);
//Billing agreement will have all the information about the agreement.
res.json({message:"Successfully created the agreement."})
}
});
}
[/js]
For more information, you can have a look at the sample code here.