Technical considerations for building and running a SaaS product with Meteor.
by Ryan Glover (@themeteorchef)
http://talks.themeteorchef.com/building-a-saas-with-meteor
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.
# 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_#01
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 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.
}
});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": {}
}
}
}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...
Hope for the best, expect the worst." - Mel Brooks
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
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
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