Tag Archives: node

Creating a Subscription Service with PayPal (Part 2 of 2): The Billing Agreement

By

This is part 2 of creating a subscription service. This 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 tutorial assumes that you have already gone through and activated a Billing Plan in part 1, and have an ID for that billing plan to reference in the example.

If you want to jump ahead and just get a complete example for parts 1 & 2, you can get it from the PayPal Developer Github repository.

When you are setting up a billing agreement to create a subscription for a user, you’ll follow 3 steps, which you may find reminiscent to processing a standard PayPal payment:

  1. You create a billing agreement, referencing an underlying billing plan via the ID.
  2. Once created, you redirect the user to PayPal (if paying via PayPal) to confirm the subscription. Once confirmed, PayPal redirects the user back to your site using the redirect provided in the underlying billing plan.
  3. You then execute the billing agreement using a token provided back via the PayPal redirect.

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());

Next up, we need to create a route to handle the creation of a billing agreement and redirect 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');
});

With our billing plan in place, we are able to create a master subscription model for our services. Using that plan, we can then subscribe multiple users via an agreement, which allows us to scale and adjust our plans (and multiple users attached to that plan) very easily.

Creating a Subscription Service with PayPal (Part 1 of 2): The Billing Plan

By

This is the first of a two part tutorial on creating a subscription model. Over the next two posts, we will cover everything you’ll need to get started with subscriptions using the PayPal REST APIs:

  • Creating billing plans to build a multi-use model for your subscription payments:
  • Subscribing users to those billing plans via a billing agreement.

If you want to jump ahead and just get a complete example for parts 1 & 2, you can get it from the PayPal Developer Github repository.

When creating a subscription for a user, you first need to create and activate a billing plan that a user is then subscribed to using a billing agreement. The complete process for creating a subscription is to:

  • Create a billing plan. This is a reusable model that outlines the details of the subscription.
  • Activate the billing plan.
  • When you want to create a subscription for a user, after the user has chosen that plan, you create a billing agreement using the ID of the billing plan that they should be subscribed to.
  • Once created, you redirect the user to PayPal to confirm the subscription. Once confirmed, the user is redirected back to the merchant’s website.
  • Lastly, you execute the billing agreement to begin the subscription.

Within this example, we’re going to be using the PayPal Node SDK. You can obtain it from NPM using the following command:

npm install paypal-rest-sdk

Within our .js file, we first set up our SDK configuration, which includes adding a requirement for the SDK, defining our client ID and secret from creating our application, and then configuring the SDK for the sandbox environment.

var paypal = require('paypal-rest-sdk');

var clientId = 'YOUR CLIENT ID';
var secret = 'YOUR SECRET';

paypal.configure({
  'mode': 'sandbox', //sandbox or live
  'client_id': clientId,
  'client_secret': secret
});

Next, we need to set up two JSON objects. The billingPlanAttribs object contains the information and payment breakdown for the billing plan that we can subscribe users to, and the billingPlanUpdateAttributes object contains values for setting the billing plan to an active state, allowing it to be used.

var billingPlanAttribs = {
    "name": "Food of the World Club Membership: Standard",
    "description": "Monthly plan for getting the t-shirt of the month.",
    "type": "fixed",
    "payment_definitions": [{
        "name": "Standard Plan",
        "type": "REGULAR",
        "frequency_interval": "1",
        "frequency": "MONTH",
        "cycles": "11",
        "amount": {
            "currency": "USD",
            "value": "19.99"
        }
    }],
    "merchant_preferences": {
        "setup_fee": {
            "currency": "USD",
            "value": "1"
        },
        "cancel_url": "http://localhost:3000/cancel",
        "return_url": "http://localhost:3000/processagreement",
        "max_fail_attempts": "0",
        "auto_bill_amount": "YES",
        "initial_fail_amount_action": "CONTINUE"
    }
};

var billingPlanUpdateAttributes = [{
    "op": "replace",
    "path": "/",
    "value": {
        "state": "ACTIVE"
    }
}];

Within the billingPlanAttribs object, there are some relevant pieces of information:

  • name / description / type: Basic visual information to describe the plan, and the type of plan.
  • payment_definitions: Information on how the plan should function and be billed. More details on fields here.
  • merchant_preferences: Additional fee structures, redirect URLs, and settings for the subscription plan. More details on fields here.

With those objects in place, we can now create and activate the billing plan.

paypal.billingPlan.create(billingPlanAttribs, function (error, billingPlan){
    if (error){
        console.log(error);
        throw error;
    } else {
        // Activate the plan by changing status to Active
        paypal.billingPlan.update(billingPlan.id, billingPlanUpdateAttributes, 
            function(error, response){
            if (error) {
                console.log(error);
                throw error;
            } else {
                console.log(billingPlan.id);
            }
        });
    }
});

We call billingPlan.create(...), passing in the billingPlanAttribs object that we just created. If that is successful, the return object will contain information about the billing plan. For the sake of the example, we just need to use the billing plan ID in order to activate the plan for use.

Next, we call billingPlan.update(...), passing in the billing plan ID and the billingPlanUpdateAttributes object we created earlier. If that is successful, our billing plan is now active and ready to use.

In order to create a subscription for a user (or multiple users) on this plan, we’ll need to reference the billing plan id (billingPlan.id above), so store that in a place that can be referenced easily.

In the second subscription step, we need to create a billing agreement based on the plan we just created and execute it to begin processing subscriptions for a user.

Stay tuned for part 2…

Processing a Credit Card Payment with a Vaulted Card

By

In this tutorial, we’ll be looking at a Node example to show how to store a credit card using the PayPal vault, then reference that stored credit card to process a credit card transaction for a user.

The reason why we would want to use the vault is so that we don’t have to store sensitive credit card information on our own servers. We simply reference the payment method via a provided vault ID, meaning that we don’t have to deal with many PCI compliance regulations with storing the credit cards ourselves.

For the full example code used in the below tutorial, go to the PayPal Developer Github account.

Our first step is to require the packages that we need, and configure our environment.

var paypal = require('paypal-rest-sdk'),
    uuid = require('node-uuid');

var client_id = 'YOUR CLIENT ID';
var secret = 'YOUR SECRET';

paypal.configure({
  'mode': 'sandbox', //sandbox or live
  'client_id': client_id,
  'client_secret': secret
});

We add the requirement for the PayPal SDK & a uuid package (more on that in a moment), then set up variables for the client ID and secret that were obtained when creating an application. We then configure our application using these details, and specify the environment that we are working in (live or sandbox). We are using the node-uuid package in order to be able to generate unique UUID’s for the payers when storing the card. An alternative for this is to use your unique customer IDs in place of this functionality. You can install that package via:

npm install node-uuid

Next, we define the credit card JSON object that will be sent to the PayPal vault for storage. It contains information from the card, as well as a unique payer ID that we generate using node-uuid. You should store this unique payer_id in your own database as it will be used when creating a payment with the vaulted card.

var create_card_details = {
    "type": "visa",
    "number": "4417119669820331",
    "expire_month": "11",
    "expire_year": "2018",
    "first_name": "John",
    "last_name": "Doe",
    "payer_id": uuid.v4()
};

Lastly, we need to store the credit card and process the payment using that card. To vault a credit card, we call credit_card.create(...), passing in the credit_card_details object that we just created. If all goes well, we should have an object returned to us with details about the vaulted card. For the sake of a payment with that card, we only really need two pieces of information: the payer_id that we already stored, and the vault ID, that should also be stored as a reference in our own database.

paypal.credit_card.create(create_card_details, function(error, credit_card){
    if(error){
        console.error(error);
    } else {
        var card_data = {
            "intent": "sale",
            "payer": {
                "payment_method": "credit_card",
                "funding_instruments": [{
                    "credit_card_token": {
                        "credit_card_id": credit_card.id,
                        "payer_id": credit_card.payer_id
                    }
                }]
            },
            "transactions": [{
                "amount": {
                    "total": "7.47",
                    "currency": "USD",
                    "details": {
                        "subtotal": "7.41",
                        "tax": "0.03",
                        "shipping": "0.03"
                    }
                },
                "description": "This is the payment transaction description." 
            }]
        };

        paypal.payment.create(card_data, function(error, payment){
            if(error){
                console.error(error);
            } else {
                console.log(JSON.stringify(payment));
            }
        });
    }
});

In the section following the successful vaulting of the credit card, we then define our card_data object in order to process the payment. The main difference between a regular card payment (where you add in the card details) and processing via a vaulted payment in the structure of the card_data object, is the funding_instruments section, that we define under payer. Instead of defining the credit card information, we instead use the following object that contains the vault ID reference, and the payer ID:

"credit_card_token": {
    "credit_card_id": credit_card.id,
    "payer_id": credit_card.payer_id
}

Other than that, we simply set an intent of sale and define our transactions object, which details the payment to be made.

Lastly, we make a request to payment.create(...), passing in the card_data object that we just defined. If all is successful, we have now just vaulted a card and immediately processed a payment with it.