Building a SaaS with Meteor
Technical considerations for building and running a SaaS product with Meteor.

by Ryan Glover (@themeteorchef)
http://talks.themeteorchef.com/building-a-saas-with-meteor
Disclaimer
I am not a millionaire. Or a thousandaire. I'm just a nerd who spent a lot of his time trying to understand how this stuff works so I could build my own stuff. In the process, I learned a few things that may help others who are curious about building a SaaS with Meteor. None of this is a prescription for success.

What we'll be covering
- Know what you're building and who you're building it for.
- Organization, version control, and continuous integration.
- Implementing subscriptions with Stripe.
- Tracking customer behavior.
- Managing data, deployments, and backups.
- Lowering your expectations.
Know what you're building
- What features am I building (map it out)?
- What is technically required to implement those features?
- What packages and libraries do I need? Can I trust them?
- What do I need to research (i.e. "What don't I know for sure")? When?

Know who you're building for
- Are you building for people at home? Businesses? Hospitals?
- What are their expectations?
- What needs to be "perfect" in their eyes?
- What can I revisit later on?
- Understand the importance of each feature in respect to the customer's workflow.
- You're building for CUSTOMERS not for other developers.
Organization
- Think about how your application is structured.
- What is the folder structure?
- What is the general pattern for my templates? Controllers? Routes?
- Documentation in a team setting is priceless.
- How do I keep track of features, bugs, and improvements?
- Keep a dictionary of logins.
- Create a set of snippets, gists, etc. that will be reused.
- This is the most important thing you can do as an engineer.
Version control
- Where are you storing your code? GitHub? Bitbucket? Elsewhere?
- Abuse issue trackers. Everything should have an issue/ticket before it's implemented.
- Have a branching strategy. Be able to identify features, bugs, and refactors.
- Only commit customer-ready work to your master branch.
- In a team? Use Pull Requests.
- Have a versioning scheme and tag your releases. Semantic Versioning is friendly.
- Git Extras by TJ Holowaychuk is awesome for managing all of this.
# Implementing a new feature: descriptive name, issue number from GitHub.
git checkout -b feature/name_of_feature_#01
# Fixing a bug: descriptive name, issue number from GitHub.
git checkout -b bug/name_of_bug_#01
# Improving some existing code: descriptive name, issue number from GitHub.
git checkout -b refactor/name_of_refactor_#01Continuous Integration
- I don't fully understand this, or practice it, but I'm learning it/working on it.
- Velocity is really well done and getting better by the day. Install it in your app, play with it, and get an understanding for how to use it.
- Test the important stuff: payments, critical features, etc.
- Play with a CI service early on (e.g. Codeship) and know how it works.
- Develop a philosophy around testing early on. You're either doing TDD/BDD or you're not, but don't try to implement stuff part way through later on.
- Don't panic. You *can* go into production without tests, but it can get murky and present headaches down the road.
Implementing subscriptions with Stripe
- Stripe API vs Stripe Checkout? When to use which?
- Installing Stripe: Atmosphere packages (e.g. mrgalaxy:stripe) vs. NPM.
- Pre-made implementations on Atmosphere (e.g. woody:stripe-easy).
- Mostly server-side code, API methods are asynchronous so need to make them blocking to play friendly w/ the client.
- Two parts: API method calls and webhooks.
- SSL/Security/PCI compliance?

Stripe (cont.): API Methods
Which API methods do I need to support? It depends. The basics:
Stripe.customers.create
Creates a customer on Stripe to associate a subscription with.
Stripe.customers.createSubscription
Creates the actual subscription to a plan you specify (and associates it with a customer).
Stripe.customers.updateSubscription
Updates an existing subscription (e.g. changing a plan).
Stripe.customers.cancelSubscription
Cancels an existing subscription for a customer.
Stripe (cont.): API Methods in Practice
Stripe is incredibly simple to use. An example API call:
// Include Stripe via NPM using the meteorhacks:npm package.
var Stripe = Meteor.npmRequire('stripe')(secret);
// With a card object.
{
number: String,
exp_month: String,
exp_year: String,
cvc: String
}
// Calling on Stripe
Stripe.customers.create({
card: card,
email: email
}, function(error, response){
if (error){
// Do something with the error.
} else {
// Do something with the response.
}
});Stripe (cont.): Webhooks
How do I handle webhooks in my Meteor app? An example using Iron Router:
Router.route('/webhooks/stripe', function () {
var request = this.request.body;
switch(request.type){
case "customer.subscription.updated":
stripeUpdateSubscription(request.data.object);
break;
case "invoice.payment_succeeded":
stripeCreateInvoice(request.data.object);
break;
}
// Let Stripe know that we receive its request as expected.
this.response.statusCode = 200;
this.response.end('Oh hai Stripe!\n');
}, {where: 'server'});
{
"created": 1326853478,
"livemode": false,
"id": "evt_00000000000000",
"type": "customer.subscription.created",
"object": "event",
"request": null,
"pending_webhooks": 1,
"api_version": "2015-01-11",
"data": {
"object": {
"id": "sub_00000000000000",
"plan": {
"interval": "month",
"name": "Tiny",
"created": 1421530286,
"amount": 500,
"currency": "usd",
"id": "tiny_00000000000000",
"object": "plan",
"livemode": false,
"interval_count": 1,
"trial_period_days": 1,
"metadata": {},
"statement_descriptor": "todoodle - tiny plan"
},
"object": "subscription",
"start": 1423772500,
"status": "trialing",
"customer": "cus_00000000000000",
"cancel_at_period_end": false,
"current_period_start": 1423772500,
"current_period_end": 1423858900,
"ended_at": null,
"trial_start": 1423772500,
"trial_end": 1423858900,
"canceled_at": null,
"quantity": 1,
"application_fee_percent": null,
"discount": null,
"tax_percent": null,
"metadata": {}
}
}
}Tracking customer behavior
This recently just got really easy thanks to the okgrow:analytics package and Segment. Once the package is installed, configure it in settings.json and then log events:
{
"public": {
"analyticsSettings": {
// Add your analytics tracking id's here
"Google Analytics" : {"trackingId": "Your tracking ID"},
"Mixpanel" : {"token": "your token"},
"KISSmetrics" : {"apiKey": "your api key"},
"UserVoice" : {"apiKey": "your api key"},
"Sentry" : {"config": "your config key"},
"Segment.io" : {"apiKey": "your api key"}
}
}
}Template.exampleTemplate.events({
'click .money-making-button': function(){
analytics.track("Clicked the money making button" {
eventName: "scrooge-mcduck-dive",
propertyToTrack: "I'm a string of some sort."
});
}
});In /settings.json...
Somewhere in your client code...
Managing Data & Backups
- For MongoDB deployments: Compose.io makes it incredibly easy. Replica sets, ability to turn on oplog tailing, daily backups to Amazon S3.
- A little paranoia is good: have a backup database provider and use a remote backup service in addition to Compose.io (e.g. MongoLab is good for this and you control backup location).
Hope for the best, expect the worst." - Mel Brooks
Deployments
- Modulus is the easiest/most roboust for hosting at the moment. Makes deployments as easy as running a single command. Bonus: auto-scaling of instances, easy to use interface, and easy to reach support team.
- If you prefer to be in control of deployments, Arunoda's meteor-up command line tool makes deployments to Digital Ocean (and friends) a bit easier.
- Multiple servers for an app: production, staging, and operations.
- Make use of Meteor's DDP.connect() method to connect to remote instances. Allows you to call methods remotely, subscribe to collections, etc.
- Install Kadira & Use it. Read through Bulletproof Meteor.
Lower your expectations
- Writing a few hundred lines of code does != champagne wishes and caviar dreams.
- Focus on quality of product, not payday.
- Do it right the first time, don't be lazy.
- Have fun! You're building software for a living, that's awesome!

Resources
Building a SaaS with Meteor: Stripe (Part 1 & 2)
https://themeteorchef.com/recipes/building-a-saas-with-meteor-part-1
https://themeteorchef.com/recipes/building-a-saas-with-meteor-part-2
Velocity (Testing): Getting Started
http://velocity.meteor.com/getting-started
Git Extras
https://github.com/tj/git-extras
woody:stripe-easy
https://atmospherejs.com/woody/stripe-easy
Abigail Watson: Meteor Cookbook
https://github.com/awatson1978/meteor-cookbook/tree/master/cookbook
Resources
Bulletproof Meteor
https://bulletproofmeteor.com/
The Long Slow SaaS Ramp of Death by Gail Goodman
https://vimeo.com/54076835
Arunoda: Meteor Up
https://github.com/arunoda/meteor-up
Thanks for listening!
If you'd like to learn more about Meteor, make sure to check out themeteorchef.com and follow @themeteorchef on Twitter.

Review these slides: http://talks.themeteorchef.com/building-a-saas-with-meteor
Building a SaaS with Meteor
By themeteorchef
Building a SaaS with Meteor
Technical considerations for building and running a SaaS product with Meteor.
- 3,163