This is going to be a super quick tutorial on how to accept payments with Stripe payment processor and node.js. At Browserling we're moving to Stripe right this very moment so I thought I'd write this quick post. Stripe is the most incredible payment processor - it took me like 30 minutes to figure everything out. Everything is well documented and works like a charm!

First, you will need the node-stripe module. Install it through npm, as always:

npm install stripe

Next, you'll need to login into Stripe, and setup a plan:


Setting up a new Stripe plan.

Next, you'll need to find the test and live keys that are used in the payment code. They are located in Account Settings -> API Keys.


Stripe keys are located in Account Settings -> API keys.

Next, you'll need to include Stripe's JavaScript library in your HTML code:

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

Next, you'll need to setup an HTML form with card name, cvc, expiration date, amount (in cents!). You don't need to ask the name or address, that stuff is old school:

<div id="stripe-form">
  <form action="/plans/browserling_developer" method="POST" id="payment-form">
    <div class="form-row">
      <div class="cc-text">Card Number</div>
      <input type="text" size="30" autocomplete="off" class="card-number"/>
    </div>
    <div class="form-row">
      <div class="cc-text">CVC</div>
      <input type="text" size="4" autocomplete="off" class="card-cvc"/>
    </div>
    <div class="form-row">
      <div class="cc-text">Expiration (MM/YYYY)</div>
      <input type="text" size="2" class="card-expiry-month"/>
      <span> / </span>
      <input type="text" size="4" class="card-expiry-year"/>
    </div>
    <input type="hidden" name="amount" value="2000" id="cc-amount">
    <button type="submit" class="submit-button">Submit Payment</button>
  </form>
</div>
<div id="error" class="hidden"></div>
<div id="success" class="hidden">Thanks for signing up at Browserling!</div>

Next, you'll need to generate a token when the form gets submitted, and submit it to your node.js application, instead of submitting credit card number and other info:

var publicStripeApiKey = '...';
var publicStripeApiKeyTesting = '...';

Stripe.setPublishableKey(publicStripeApiKey);

function stripeResponseHandler (status, response) {
  if (response.error) {
    $('#error').text(response.error.message);
    $('#error').slideDown(300);
    $('#stripe-form .submit-button').removeAttr("disabled");
    return;
  }
  
  var form = $("#payment-form");
  form.append("<input type='hidden' name='stripeToken' value='" + response.id + "'/>");

  $.post(
    form.attr('action'),
    form.serialize(),
    function (status) {
      if (status != 'ok') {
        $('#error').text(status);
        $('#error').slideDown(300);
      }
      else {
        $('#error').hide();
        $('#success').slideDown(300);
      }
      $('.submit-button').removeAttr("disabled");
    }
  );
}

// http://stripe.com/docs/tutorials/forms
$("#payment-form").submit(function(event) {
  $('#error').hide();
  // disable the submit button to prevent repeated clicks
  $('.submit-button').attr("disabled", "disabled");

  var amount = $('#cc-amount').val(); // amount you want to charge in cents
  Stripe.createToken({
    number: $('.card-number').val(),
    cvc: $('.card-cvc').val(),
    exp_month: $('.card-expiry-month').val(),
    exp_year: $('.card-expiry-year').val()
  }, amount, stripeResponseHandler);

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

Next, you need to setup a route handler in node.js web server for all your plan names. In this tutorial I'll handle just browserling_developer plan:

var express = require('express');

var stripeApiKey = "...";
var stripeApiKeyTesting = "..."
var stripe = require('stripe')(stripeApiKey);

app = express.createServer(express.bodyDecoder);

app.post("/plans/browserling_developer", function(req, res) {
  stripe.customers.create({
    card : req.body.stripeToken,
    email : "...", // customer's email (get it from db or session)
    plan : "browserling_developer"
  }, function (err, customer) {
    if (err) {
      var msg = customer.error.message || "unknown";
      res.send("Error while processing your payment: " + msg;
    }
    else {
      var id = customer.id;
      console.log('Success! Customer with Stripe ID ' + id + ' just signed up!');
      // save this customer to your database here!
      res.send('ok');
    }
  });
});

That's it! This simple node.js code handles POST requests to /plans/browserling_developer, and creates a new customer at Stripe. Notice that it uses req.body.stripeToken and doesn't even touch credit card info.

I have never worked with a payment processor which was easier to setup. It's a pure pleasure to use Stripe!

perl -lne '(1x$_) =~ /^1?$|^(11+?)\1+$/ || print "$_ is prime"'

Can you figure out how it works? I give an explanation below, but try to figure it out yourself. Here is what happens when you run it:

$ perl -lne '(1x$_) =~ /^1?$|^(11+?)\1+$/ || print "$_ is prime"'
1
2
2 is prime
3
3 is prime
4
5
5 is prime
6
7
7 is prime
8
9
10
11
11 is prime

Here is how it works.

First, the number is converted in its unary representation by (1x$_). For example, the number 5 gets converted into 1x5, which is 11111 (1 repeated 5 times.)

Next, the unary string gets tested against the regular expression. If it matches, the number is a composite, otherwise it's a prime.

The regular expression works this way. It consists of two parts ^1?$ and ^(11+?)\1+$.

The first part matches number 1 and the empty string. Clearly, the empty string and number 1 are not prime numbers, therefore this regular expression matches, which indicates that they are not prime numbers.

The second part determines if two or more 1s repeatedly make up the whole number. If two or more 1s repeatedly make up the whole number, the regex matches, which means that the number is composite. Otherwise it's a prime.

Let's look at the second regex part on numbers 5 and 4.

The number 5 in unary representation is 11111. The (11+?) matches the first two ones 11. The back-reference \1 becomes 11 and the whole regex now becomes ^11(11)+$. It can't match five ones, therefore it fails. But since it used +?, it backtracks and matches the first three ones 111. The back-reference becomes 111 and the whole regex becomes ^111(111)+$. It doesn't match again. This repeats for 1111 and 11111, which also don't match, therefore the whole regex doesn't match and the number is a prime.

The number 4 in unary representation is 1111. The (11+?) matches the first two ones 11. The back-reference \1 becomes 11 and the regex becomes ^11(11)+$. It matches the original string, therefore the number is not a prime.

PS. I didn't invent this regular expression, it was invented in 1998 by Abigail.

Don't take this regular expression too seriously, it's actually neither a regular expression (as defined in automata theory), nor a way to check if a number is a prime. It's just an awesome thing that Perl can do. See this cool article called The Prime That Wasn't by Andrei Zmievski for a discussion about how this regex fails for larger numbers because of backtracking.

Also if you wish to learn more about Perl one-liners, check out my Perl One-Liners Explained article series and download the perl1line.txt file.

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the thirteenth post in the node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers, the ninth was about redis - the best redis client API library for node, the tenth was on express - an insanely small and fast web framework for node, the eleventh was semver - a node module that takes care of versioning, the twelfth was cradle - a high-level, caching, CouchDB client for node.

This time I'll introduce you to a very awesome module called JSONStream. JSONStream is written by Dominic Tarr and it parses streaming JSON.

Here is an example. Suppose you have couchdb view like this:

{"total_rows":129,"offset":0,"rows":[
  { "id":"change1_0.6995461115147918"
  , "key":"change1_0.6995461115147918"
  , "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
  , "doc":{
      "_id":  "change1_0.6995461115147918"
    , "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
  },
  { "id":"change2_0.6995461115147918"
  , "key":"change2_0.6995461115147918"
  , "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
  , "doc":{
      "_id":"change2_0.6995461115147918"
    , "_rev":"1-13677d36b98c0c075145bb8975105153"
    , "hello":2
    }
  },
  ...
]}

And you wish to only filter out doc values from the rows. You can do it easily with JSONStream this way:

var parser = JSONStream.parse(['rows', /./, 'doc']);

This creates a stream that parses out rows.*.doc.

Since it's a stream you have to feed it data and then have it output the data somewhere. You can do it very nicely and idiomatically in node this way:

req.pipe(parser).pipe(process.stdout);

Here is the output:

{
  _id: 'change1_0.6995461115147918',
  _rev: '1-e240bae28c7bb3667f02760f6398d508',
  hello: 1
}
{
  _id: 'change2_0.6995461115147918',
  _rev: '1-13677d36b98c0c075145bb8975105153',
  hello: 2
}

Where req is request to couchdb view and parser is the JSONStream parser, and it all gets piped to process.stdout. The output, as you can see, is only the rows.*.doc. That was a really easy way to parse a JSON stream without reading the whole JSON into memory.

You can install JSONStream through npm as always:

npm install JSONStream

JSONStream on GitHub: https://github.com/dominictarr/JSONStream.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the twelfth post in the node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers, the ninth was about redis - the best redis client API library for node, the tenth was on express - an insanely small and fast web framework for node, the eleventh was semver - a node module that takes care of versioning.

Today I'll introduce you to cradle - a high-level, caching, CouchDB client for Node.js. Cradle is written by Alexis Sellier (cloudhead).

Cradle is somewhat higher-level than most other CouchDB clients, requiring a little less knowledge of CouchDB's REST API. Cradle also has built-in write-through caching, giving you an extra level of speed, and making document updates and deletion easier. Cradle was built from the love of CouchDB and Node.js, and tries to make the most out of this wonderful marriage of technologies.

Here is an example of how simple it's to use cradle:

var cradle = require('cradle');
var db = new(cradle.Connection)().database('starwars');

db.get('vader', function (err, doc) {
    doc.name; // 'Darth Vader'
    assert.equal(doc.force, 'dark');
});

db.save('skywalker', {
    force: 'light',
    name: 'Luke Skywalker'
}, function (err, res) {
    if (err) {
        // Handle error
    } else {
        // Handle success
    }
});

Cradle supports all the operations that you'd expect an API for CouchDB to support like creating a database:

var db = c.database('starwars');
db.create();

Checking if a db exists:

db.exists(function (err, exists) {
  if (err) {
    console.log('error', err);
  } else if (exists) {
    console.log('the force is with you.');
  } else {
    console.log('database does not exists.');
    db.create();
    /* populate design documents */
  }
});

Destroying a db:

db.destroy(cb);

Fetching a document:

db.get('vader', function (err, doc) {
    console.log(doc);
});

Querying a view:

db.view('characters/all', function (err, res) {
    res.forEach(function (row) {
        console.log(row.name + " is on the " +
            row.force + " side of the force.");
    });
});

Creating and updating documents:

db.save('vader', {
    name: 'darth', force: 'dark'
}, function (err, res) {
    // Handle response
});

Creating views:

db.save('_design/characters', {
    all: {
        map: function (doc) {
            if (doc.name) emit(doc.name, doc);
        }
    },
    darkside: {
        map: function (doc) {
            if (doc.name && doc.force == 'dark') {
                emit(null, doc);
            }
        }
    }
});

Deleting documents:

db.remove('luke', '1-94B6F82', function (err, res) {
    // Handle response
});

And it also supports streaming, changes api, and many other things. See the cradle documentation to learn more.

You can install cradle through npm as always:

npm install cradle

Cradle on GitHub: https://github.com/cloudhead/cradle.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the eleventh post in the node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers, the ninth was about redis - the best redis client API library for node, the tenth was on express - an insanely small and fast web framework for node.

Today I'll introduce you to a module called semver. Semver is the semantic versioner. Semver is written by Isaac Z. Schlueter, the author of npm. Semver is used in npm to handle all the node.js module versioning problems.

Here is an example of what it does:

semver.valid('1.2.3') // true
semver.valid('a.b.c') // false
semver.clean('  =v1.2.3   ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7')  // false
semver.lt('1.2.3', '9.8.7')  // true

The ordering of versions is done using the following algorithm - given two versions and asked to find the greater of the two:

  • If the majors are numerically different, then take the one with a bigger major number. For example, 2.3.4 > 1.3.4.
  • If the minors are numerically different, then take the one with the bigger minor number. For example, 2.3.4 > 2.2.4.
  • If the patches are numerically different, then take the one with the bigger patch number. For example, 2.3.4 > 2.3.3.
  • If only one of them has a build number, then take the one with the build number. For example, 2.3.4-0 > 2.3.4.
  • If they both have build numbers, and the build numbers are numerically different, then take the one with the bigger build number. For example, 2.3.4-10 > 2.3.4-9.
  • If only one of them has a tag, then take the one without the tag. For example, 2.3.4 > 2.3.4-beta.
  • If they both have tags, then take the one with the lexicographically larger tag. For example, 2.3.4-beta > 2.3.4-alpha.
  • At this point, they're equal.

Semver supports the following ranges and styles:

  • >1.2.3 means greater than a specific version.
  • <1.2.3 means less than a specific version.
  • 1.2.3 - 2.3.4 means >=1.2.3 <=2.3.4.
  • ~1.2.3 means >=1.2.3 <1.3.0.
  • ~1.2 means >=1.2.0 <2.0.0.
  • ~1 means >=1.0.0 <2.0.0.
  • 1.2.x means >=1.2.0 <1.3.0.
  • 1.x means >=1.0.0 <2.0.0.

Ranges can be joined with either a space (which implies "and") or a || (which implies "or").

Semver supports the following functions:

  • valid(v) - return the parsed version, or null if it's not valid.
  • inc(v, release) - return the version incremented by the release type (major, minor, patch, or build), or null if it's not valid.

Semver supports the following comparisons:

  • gt(v1, v2) - v1 > v2.
  • gte(v1, v2) - v1 >= v2.
  • lt(v1, v2) - v1 < v2.
  • lte(v1, v2) - v1 <= v2.
  • eq(v1, v2) - v1 == v2.
  • neq(v1, v2) - v1 != v2.
  • cmp(v1, comparator, v2) - pass in a comparison string, and it'll call the corresponding function above. "===" and "!==" do simple string comparison, but are included for completeness. Throws if an invalid comparison string is provided.
  • compare(v1, v2) - return 0 if v1 == v2, or 1 if v1 is greater, or -1 if v2 is greater. Sorts in ascending order if passed to Array.sort().
  • rcompare(v1, v2) - the reverse of compare. Sorts an array of versions in descending order when passed to Array.sort().

Semver supports the following range functions:

  • validRange(range) - Return the valid range or null if it's not valid.
  • satisfies(version, range) - return true if the version satisfies the range.
  • maxSatisfying(versions, range) - return the highest version in the list that satisfies the range, or null if none of them do.

You can install semver through npm as always:

npm install semver

Semver on GitHub: https://github.com/isaacs/node-semver.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!