Building an Open-Source Payments Toolkit for the Web

Internally, we use CommonJS and its pattern of composing products via small, focused libraries to write our JavaScript. Since the launch of last year, we have built up a number of these small libraries. Our latest addition to the JavaScript SDK is our Hosted Fields product which allows for full control over UI/UX while helping keep merchants compliant with the latest PCI regulations. We have decided that there is a lot of value in creating these libraries and want to share it with others to see where they can take it.


For our communication between iframes, and to assist in their networking and orchestration we have been using framebus. On the surface it is simple -- it provides a pub/sub event bus. The interesting part about it is that it works transparently across iframe and domain borders. The emitting end and the listening end of an event do not need to know about each other, even if they are in different iframes or even on different domains.

This greatly reduced the complexity of juggling iframe and window references, keeping track of which was the merchant page, which was our own, and where certain state was contained. This gave us the decoupling benefits of events without having to take into account where we were publishing or subscribing from.

// iframe 1
var bus = require('framebus');
bus.on('Marco', function (reply) { reply('Polo!'); });
// iframe 2
var bus = require('framebus');
bus.emit('Marco', function (response) {
  console.log('Got "' + response + '" back!');

Form-Napper (pending)

We make use of "hijacking" native form submissions to be able to asynchronously tokenize credit card information and give back a one-time-use nonce to the merchant. In order to do this, you’ll need to find the form, attach a submit handler, enter a new value, and submit (bypassing any attached handlers) at the end. We wrote a small library that did just this, and only this. When released, here is what that API will look like:

var form = new FormNapper('my-form-id');

form.hijack(function (event) {
  console.log('This form\'s submit has been hijacked.');

  form.inject('ransomNote', 'Send ransom to...');
  form.submit(); // if we're feeling nice

Credit card type detection

Being able to identify the type of card based on the card number is its own class of problem. What maxlength should I use for the input as soon as I know it's an Amex? How long is the security code field? What icon do I show? These questions and more can be deduced (usually) by the time the first few digits are entered.

We abstracted this concept with credit-card-type. Given a partial or full card number, give me the answers to the above questions.

var getCardType = require('credit-card-type');
var card = getCardType('4111');

//  niceType: 'Visa',
//  type: 'visa',
//  pattern: '^4[0-9][\\s\\d]*$',
//  gaps: [ 4, 8, 12 ],
//  lengths: [16],
//  code: { name: 'CVV', size: 3 }

Credit card validation

Building upon the credit card type, card-validator will tell you whether or not the input at any given time is potentially valid, completely valid, or invalid.

Potentially valid would be examples like 411 where the user is on their way to entering a completely valid Visa card number. An invalid, partial number example would be 411x, where no matter what comes after, the resulting string cannot be a valid card number.

A card is treated as completely valid once the length matches one of the card number lengths given by the type (16 usually) and passes a Luhn 10 check. It won't tell you if the card number is an active account (only the banks know that) but it gives you reasonable certainty that you have caught some invalid input[1].

var valid = require('card-validator');

var numberValidation = valid.number('4111');

if (!numberValidation.isPotentiallyValid) {

All of the libraries mentioned here are available through npm. Together, they form the foundations of a toolkit for JavaScript developers to build all kinds of applications -- even those outside of the payments space.

We look forward to working more openly in the community and releasing more libraries in the times ahead.

  1. For information on verifying payment information with Braintree’s server libraries, see Credit card validation in our official documentation.

Eric Mrak Mrak is a Web Developer and Usability Engineer out of the California Bay Area. He enjoys contributing to open-source projects and experimenting with emerging languages. More posts by this author

You Might Also Like