The second step to creating a subscription for a user is to create and execute a billing agreement, based on an existing activated billing plan. This example assumes that you have already gone through and activated a billing plan in the previous example, and have an ID for that billing plan to reference in the example.
When you are setting up a billing agreement to create a subscription for a user, you'll follow 3 steps, which may be reminiscent of processing a PayPal payment:
This example is setting up an Express based HTTP server to showcase the billing agreement process.
To start the example, we first need to set up our configuration. We add four requirements, the PayPal SDK, body-parser
for handling JSON encoded bodies, http
for our simple server integration, and express
for the Express framework. We then define our client ID and secret from creating an application, configure the SDK for the sandbox, then configure bodyParser for handling JSON bodies.
var paypal = require('paypal-rest-sdk'),
bodyParser = require('body-parser'),
http = require('http'),
app = require('express')();
var clientId = 'YOUR APPLICATION CLIENT ID';
var secret = 'YOUR APPLICATION SECRET';
paypal.configure({
'mode': 'sandbox', //sandbox or live
'client_id': clientId,
'client_secret': secret
});
app.use(bodyParser.json());
Our first step in the billing agreement is to create a route to handle the creation of a billing agreement, and redirecting the user to PayPal to confirm that subscription. We are assuming that a billing plan ID is passed as a query string parameter, such as by loading the following URL with a plan ID from the previous example:
http://localhost:3000/createagreement?plan=P-3N543779E9831025ECYGDNVQ
We now need to use that information to create the billing agreement.
app.get('/createagreement', function(req, res){
var billingPlan = req.query.plan;
var isoDate = new Date();
isoDate.setSeconds(isoDate.getSeconds() + 4);
isoDate.toISOString().slice(0, 19) + 'Z';
var billingAgreementAttributes = {
"name": "Standard Membership",
"description": "Food of the World Club Standard Membership",
"start_date": isoDate,
"plan": {
"id": billingPlan
},
"payer": {
"payment_method": "paypal"
},
"shipping_address": {
"line1": "W 34th St",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country_code": "US"
}
};
// Use activated billing plan to create agreement
paypal.billingAgreement.create(billingAgreementAttributes, function (error, billingAgreement){
if (error) {
console.error(error);
throw error;
} else {
//capture HATEOAS links
var links = {};
billingAgreement.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');
}
}
});
});
We start by extracting the billing plan ID from the query string and create the date when the plan should start.
The next object definition, billingAgreementAttributes
, consists of information for the subscription. It contains readable information on the plan, a reference to the billing plan ID, the payment method, and shipping details (if needed for the subscription).
Next, a call to billingAgreement.create(...)
is made, passing in the billingAgreementAttributes
object we just created. If all is successful, we should have a billing agreement object passed back to us containing details about our newly created subscription. That object also contains a number of HATEOAS links providing us next steps that can be taken on this newly created agreement. The one we care about here is labeled as approval_url
.
We loop through all provided links to put them into an easily referenced object. If approval_url
is one of those links, we redirect the user to that link, which is PayPal.
At this point the user confirms the subscription on PayPal, and is redirected back to the URL provided in the underlying billing plan. Along with that URL, PayPal will also pass a token along the query string. That token is what we're going to use to execute (or start) the subscription.
Let's set up that functionality in the following route.
app.get('/processagreement', function(req, res){
var token = req.query.token;
paypal.billingAgreement.execute(token, {}, function (error, billingAgreement) {
if (error) {
console.error(error);
throw error;
} else {
console.log(JSON.stringify(billingAgreement));
res.send('Billing Agreement Created Successfully');
}
});
});
We extract the token from the query string, then make a call to billingAgreement.execute
, passing along that token. If all is successful, we now have a valid subscription for the user. The return object contains information about the active billing agreement.
Lastly, we set up our HTTP server to listen for traffic to our routes.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});