Last week, 'Black Friday' kicked off the official start of the holiday shopping madness and if you are like me, the credit card barely stayed in the wallet. I think between my wife and I, we wore out the poor mag stripe on the back of our cards. I would be curious to see the stats from banks on orders of replacement cards in early December, because the stats on the amount of purchase seems to be staggering each year. In the midst of all of this shopping madness, I thought I would take this opportunity to talk about how you can easily 'Payment Enable' your RhoMobile application. You probably have been to a store this past weekend and was helped by an associate carrying a mobile device equipped with credit card reader. This category of accepting payments in a mobile fashion has really taken off and will undoubtedly change the way 'cash registers' look in the future. Heck, who carries cash anymore anyway, right?

 

Well some of these mobile payment solution are not very `developer friendly`: no APIs to fully integrate into my app, limited customization and their solution tends to work differently on different platforms. In a lot of cases, that does not matter and their solution is just fine. But if you are like me, you want the experience to be as seamless as possible, especially if you are a provider of software solutions. I want my app to look like my app and not a pieced together solution.

 

Enter Stripe

In my search for a pain-free, developer-centric way to handle purchases in your apps, I came across a service call Stripe. In the old days of online payments, you would have to create a merchant account, sign a long legal agreement, and wait about a week to have your business credentials verified. Stripe does away with all the bureaucracy while still ensuring transaction safety. Perhaps its best feature is that you can create a developer account right away, without verifying any business information. You can start exploring Stripe’s APIs literally minutes after signing up with them.

 

Signing up is a breeze, in fact you can even skip the step of registration and come back to it later.

Screen Shot 2013-11-27 at 11.53.35 AM.jpg

 

You will then be presented with a few getting started guides

 

Screen Shot 2013-11-27 at 11.53.53 AM.jpg

 

Which automatically adjust the demo code to include the API keys that are assigned to your account. I had to do a double take when I came across this, I was expecting it to just be mock demo code, but it was actually the exact code with my API keys that I needed to get started. How simple!

Screen Shot 2013-11-27 at 11.54.17 AM.jpg

Web = Cross Platform

When looking at the guides, you will see native Android and iOS libraries, but for our app we want to still use our web skills and write code that will work on any platform.  So choose the path for 'Website' since we will be using this in our RhoMobile Application and Rho apps are essentially mini web sites running on the device. Using the web approach may be important because some of those mobile payment solutions that I talked about before don't run on all platforms and also requires platform services like Google Play for instance in order for it to work. So going native may give you some unexpected limitations, where as using the web approach along with RhoMobile will allow you to work across any platform.

Screen Shot 2013-11-27 at 11.55.18 AM.jpg

 

2 minute Integration

Stripe's online docs give you a quick way for seeing how their solution works, but I wanted to see how it would work in a RhoMobile app. So I started by creating a brand new default project. And then I added the suggested form code into my index.erb file and ran it in RhoSimulator.

 

<form action="" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="pk_test_3Y7Ak1wqSncAFFMak4Np9l0T"
    data-amount="2000"
    data-name="Demo Site"
    data-description="2 widgets ($20.00)"
    data-image="/128x128.png">
  </script>
</form>







 

Viola! After entering the dummy credit card, my app was verifying with Stripes backend and giving me a token back to represent that transaction.

 

Screen Shot 2013-11-27 at 11.54.51 AM.jpg

 

As you will see in the rest of Stripe's documentation, I would use this token to send to my server that would in turn talk to Stripe's backend for the complete secure end to end transaction.  The way this sample code works is actually embedding an iframe of the script and UI that is running on Stripes backend. They give you some basic controls for the image that appears as well as the fields that are presented. This may be good for some cases, but if you want to have that seamless experience I was talking about and if you want to auto populate any of the fields (say from swiping a card using the CardReader on the device), you will have to write a custom form.

 

Custom Form

Luckily Stripe's documentation is well written and they clearly walk you through the steps of doing this. Following these steps, I replaced the Form section I added before with the following code:

 

    <form action="" method="POST" id="payment-form">
        <span class="payment-errors"></span>

        <div class="form-row">
          <label>
            <span>Card Number</span>
            <input type="text" size="20" data-stripe="number" placeholder="4242424242424242"/>
          </label>
        </div>

        <div class="form-row">
          <label>
            <span>CVC</span>
            <input type="text" size="4" data-stripe="cvc"/>
          </label>
        </div>

        <div class="form-row">
          <label>
            <span>Expiration Month (MM)</span>
            <input type="text" size="2" data-stripe="exp-month"/>
          </label>
          <span>  Year (YYY) </span>
          <input type="text" size="4" data-stripe="exp-year"/>
        </div>

        <button type="submit">Submit Payment</button>
      </form>







 

Before I could use this form, we have to include Stripe's Javascript library:

<script type="text/javascript" src="https://js.stripe.com/v2/"></script>







 

And initialize it with our API key

<script type="text/javascript">
  // This identifies your website in the createToken call below
  Stripe.setPublishableKey('pk_test_3Y7Ak1wqSncAFFMak4Np9l0T');
  // ...
</script>







 

This is the same test API key that we used before with the embedded form.

 

Now we have to handle the event for when the Submit Payment button is pressed

jQuery(function($) {
  $('#payment-form').submit(function(event) {
    var $form = $(this);


    // Disable the submit button to prevent repeated clicks
    $form.find('button').prop('disabled', true);


    Stripe.card.createToken($form, stripeResponseHandler);


    // Prevent the form from submitting with the default action
    return false;
  });
});






 

This essentially sends the details via the form to the be processed by Stripes backend and then sets up a handler function to handle the response. Stripe requires certain fields and know which ones those are by using the data-stripe attribute.

 

<input type="text" size="2" data-stripe="exp-month"/>






 

The stripeRespondeHandler function handles the callback from Stripe's backend. Here is where you would handle errors and if successful submit the form to your back end to complete the transaction. Notice that we inject the token into the form. This is the key piece of information that is needed on the backend. You don't have to send any of the other sensitive information across the wire.

 

var stripeResponseHandler = function(status, response) {
  var $form = $('#payment-form');
  console.log(status);
  console.log(response);
  if (response.error) {
    // Show the errors on the form
    $form.find('.payment-errors').text(response.error.message);
    $form.find('button').prop('disabled', false);
  } else {
    // token contains id, last4, and card type
    var token = response.id;
    // Insert the token into the form so it gets submitted to the server
    $form.append($('<input type="hidden" name="stripeToken" />').val(token));
    // and submit
    alert('Card Accepted: ' + token);
    //$form.get(0).submit();

  }
};






 

Integrated Card Reader

Some of the Motorola Solutions devices may be equipped with a built in MSR reader. Take the MC40 for example, this device optionally has a built-in MSR and it also is supported by RhoMobile's CardReader API. In order to use this API, we have to first include an extension in our build.yml file before building the project.

 

extensions: ["cardreader"] 

 

Now when we build our application, the Rho.CardReader api will be available to us. We will use the Javascript version, so I also need to make sure I include the rhoapi-modules.js file in my layout.erb (this should be there by default, but just double check)

 

<script src="/public/api/rhoapi-modules.js" type="text/javascript"></script>






 

Enabling the CardReader takes just one call to the Rho.CardReader.open method that requires a callback.

 

Rho.CardReader.open(function(d){
                  console.log(d.data);
                  });






 

The callback function will get a response that contains the card details. The callback params will depend on the type of card swiped. There will be a data attribute along with several track data. Below is a sample of that, of course blacking out some of my sensitive information:

 

Screen Shot 2013-12-02 at 10.04.01 AM.jpg

As a side note, you can see above that this output is being shown using a web inspector, but as you know the CardReader API actually needs to run on real hardware. To easily see this, I am using Weinre on my device so I can inspect Javascript objects with ease and test the API before putting it into my app.

 

Parsing the Card Data

When you look at the data you get from the callback, it looks like a very long string of gobbly gook. See http://en.wikipedia.org/wiki/Magnetic_stripe_card for information about the format of track data.  But for this demo I am all about not re-inventing the wheel, and a simple Google search on Javascript credit card track parsing revealed a easy to use library written by GitHub user jpartlow. From looking at the web console debug output and the demo code from this library, I can tell that it is expecting the data that is in the callback field: d.data :

 

Rho.CardReader.open(function(d){
                  console.log(d);
                  cc = new CreditCardTrackData(d.data);
                  $('#payment-form input[data-stripe="number"]').val(cc.number);
                  $('#payment-form input[data-stripe="exp-month"]').val(cc.expiration.substring(2));
                  $('#payment-form input[data-stripe="exp-year"]').val(cc.CENTURY + cc.expiration.substring(0,2));
                });






 

The CreditCardTrackData function of the credit_card_track_parser.js library returns an object with several attributes. I used this object to auto populate the fields on my form just using standard jQuery syntax.

Screen Shot 2013-12-02 at 10.23.22 AM.jpg

 

Sample

The simple application described can be found at: https://github.com/rhomobile/rho-samples/tree/master/RhoStripe