Stop. Writing. Billing. Code. Right. Now.

Doug Breaker here, CEO of Writing billing code is hard. Really hard. If you’re wrong by a penny, you’re all wrong.

I used to write billing code as a young developer.  I once made a mistake that cost a client $1,200,000! Oops, not my best day.

Any business not in the business of writing billing code should not write billing code. Outsource it instead.   

I guarantee it will save you time, make your other development faster, and save your sanity. Spend time building your competitive advantage, not wasting it writing billing code.

At Earth Class Mail, we use Chargify (Full disclosure: Scaleworks owns both Chargify and Earth Class Mail.  We used Chargify well before Scaleworks bought them).   

When I ran HomeFinder, we used Recurly and liked it.   Stripe’s subscription functionality offers a ton of time savings and robust tool set.  Check them all out, all offer immense developer time savings vs. developing your own billing system.  

Repeat after me ten times, “we will not have developers spend time on billing code!”

CRITICAL TIP:  before you choose, ask yourself, “will we ever want to charge for something like ‘get 20 widgets for free on our $99 plan, and 40 widgets for free on our $149 plan and charge for widgets over those amounts?'”

If you answer “yes”, then keep reading for a MASSIVE difference between Chargify/Stripe/Recurly.    This one tip can save you months of developer time, make you more money, and launch your products faster.

Let me explain with two real world examples, one using Recurly, and one using Chargify.

Example 1: Offering Free Usage on Recurly

My wife runs a little site called   The site lets consumers read 100% verified reviews from moving companies and get free quotes from them.   For example, check out all the reviews for Tampa movers or Orlando movers.  

Consumers can even get a free pizza on their move day if they find a mover through the site. Who doesn’t love pizza on their move day?

(Quick backstory: Before I took over as CEO of Earth Class Mail, I was CEO of HomeFinder. While at HomeFinder, we launched as an internal startup. After I left, Placester bought HomeFinder about 6 months later. Placester didn’t want, so we bought it from them.)

We offer a product to moving companies called “Review Advantage“.   For that product we email prior customers of moving companies and collect reviews on behalf of the moving companies.   

We offer the first bunch of customers to write a review per month a free Starbucks coffee. The product used to be manual, but we just launched an automated version.  We set out to offer different plans with different number of free coffees:

  • $19 per month includes 3 free customer coffees
  • $99 per month includes 15 free customer coffees
  • $299 per month includes 50 free customer coffees

After we hit the free coffee limit, we wanted to charge the moving company a certain amount per coffee.   Here’s how it looks to our movers:

Here’s how we set that up on Recurly:

  1. Set up a “Measured Unit” for free coffees
  2. Set up the pricing plans, including a billable add-on for the extra coffees.  Here’s the $19 plan.
  3. Write a bunch of custom billing code to do the following:
    • Keep track of how many free coffees we’ve given in a billing period
    • Report any coffees over that the free limit to Recurly
    • Reset the counter when a customer’s billing period renews

That’s not easy code to write!   We did it, but it took our developer about three weeks of hardcore coding time to get it correct, get automated tests in place, and get fully confident that it worked.

Recurly gives us a ton of benefit, and we enjoy using it.   Unfortunately their metered component functionality still required us to write complex billing code in order to give away a different number of free coffees by plan price point.   

We made the investment because it was worth it.   However, we’d much rather spend our coding time helping consumers find great moving companies.

Example 2: Offering Free Usage on Chargify

Here at Earth Class mail, we just launched a killer new check deposit/lockbox product on Earth Class Mail called CheckStream.    

If you’re a business that gets checks, it can revolutionize the way you deposit them and record payments in Xero or QuickBooks Online.   

You can deposit any sized check into any bank in the US without going through any application process, or worrying about per check credit limits.    

Once you deposit the check, you can record payments to customers & invoices right from our app into Xero & Quickbooks online.

We launched with three pricing plans, each with a different number of checks included.   

  • $99 per month includes  30 check deposits
  • $249 per month includes 125 check deposits
  • $499 per month includes 265 check deposits

If customers pass those limits, we charge $2 per check deposit on the first two plans, and $1.90 per check on the $499 plan.

Thanks to Chargify’s new price point functionality, charging for this is a breeze.   

Check out how easy Chargify made it to set this up:

  1. Set up our 3 plans, here’s the $99 plan.
  2. Set up our metered “check deposit” component, with the three different price points.
  3. Configure each price point to include the correct number of free check deposits, see screenshot below.  
  4. When someone signs up for a plan, set the correct price point on their subscription (we do this in our ordering code, but you can do it via the user interface as well).
  5. Ship it!   That’s it!  Since our app already tracks which plan a customer is on and reports check deposits to Chargify, we didn’t have to do anything else.

Notice the step we didn’t have to do?   Write complex billing code!    Magic!    

Chargify saved us weeks or months of development & testing time.  Instead of spending weeks or months coding & testing, we launched the new plans in days.  

So do you and your company a favor, don’t write billing code!   After having hands-on experience with various billing solutions, Chargify has been the clear winner for Earth Class Mail’s needs, but I encourage you to check out all the options before committing to a provider.

Going with any will save you development time and future tears when your custom billing code breaks.    

However, make sure you bump your current and future billing scenarios against each provider to make sure you don’t get sucked back into the swampy quagmire of billing code development.

Lastly, if you’re a business that gets check in the mail, check out our new check deposit service, it’ll save you bunch of time, get money in your bank account faster, and save you from keying in payments in Xero and Quickbooks Online.

Open Source Experiment: Chargify App for Zendesk

From Steven Maguire, VP of Tech @ Earth Class Mail

One of the key value propositions of Earth Class Mail is the ability to access important business information, the kind contained in your mail and physical documents, from anywhere in the world.

This same principle drives the development of internal tools that we use to ensure our customers have a positive experience with our services.

The Problem

Two of the third-party tools that we use a lot everyday are the Chargify recurring billing platform and the Zendesk customer service platform. They are “mission critical” and we couldn’t deliver the level of service our customers expect without them.

Each of those tools contains important information about each customer, their accounts, history, pending support requests, and the like.

We noticed that our own team members were switching between Chargify and Zendesk dozens, if not hundreds, of times everyday.

The Solution

We also observed that the primary reason for switching to Chargify’s web UI was to view read-only data within Chargify’s platform. That is, they were just looking at customer information, not taking any billing related actions.

That observation led us to a very natural and, it seems now, obvious hypothesis:

If we eliminate the need to switch between Zendesk and Chargify, then our team members would be more productive and be able to provide better service to customers.

Fortunately, Zendesk supports a third-party application development platform, that means we can build internal tools that will work natively in the Zendesk platform. So now we have a great opportunity to test our hypothesis.

We’ve also decided to make our Chargify Zendesk app open source, so that anyone can use it. The reasons for that are:

  1. Zendesk apps are not how we make a living.
  2. The more contributors there are to this project, the more we will all benefit from a better product.
  3. If we can make it easy for other businesses to provide better customer service, then we’ve done some good in this world.

We’ve built, tested, and released a minimum viable product of the open source Zendesk app, here’s how:


After reading the documentation for Zendesk’s Apps Framework v1 we learned a few things:

  1. A tool to create and scaffold a new blank project.
  2. A tool to lint and validate the code that you write for your project.
  3. A tool to package your application code in a zip file that will be uploaded, unzipped, and installed within your Zendesk account.
  • Zendesk supports a third-party app marketplace where you can find and install public applications; some free and some paid.
  • Zendesk supports installation of private apps without going through the marketplace.

With these observations in mind we created a goal for the experience of our app:

Whenever a Zendesk agent is viewing a customer profile or ticket, we want to use the email address associated with that customer or ticket to display customer and subscription records from within Chargify.

After some research we discovered that a single email address can be associated with more than one Chargify customer record, and each Chargify customer record can be associated with more than one subscription.

This discovery drove the decision to include two views:

  1. A customer search results view, and
  2. A customer detail view.

Using the “app.activated” event emitted by the Zendesk application framework we attempt to load the customer search results view first.

During the creation of this view we use Zendesk’s Data API to fetch the customer’s email if we are looking at a customer profile view in Zendesk, or the requester’s email if we are looking at a ticket.

With this value in memory we issue a customer search to Chargify to fetch customer results.

We introduced a few use cases here:

  • If no Chargify customer records are returned we update the search results view with an “empty results” alert.
  • If more than one Chargify customer records are returned we update the search results view with a list of each of those customer records as links which will load a customer detail view.
  • Finally, if a single Chargify customer record is returned we redirect the application to that customer detail view; we feel a search results page with one result is not valuable.

When loading a customer detail view we issue a couple other calls to Chargify to first fetch the fully hydrated customer record as well as a second call to fetch each of the subscriptions associated with the customer.

When all this data is available we update the customer detail view to display the data.In order to facilitate these API calls to Chargify our Zendesk application needs to know two pieces of unique information:

  1. The subdomain associated with our Chargify account
  2. The API key associated with our Chargify account

Fortunately, the Zendesk framework provides a way to ensure we can gather and securely store that information during installation.

In the unlikely event that the app begins running and that information has not been set, the app will display a third settings view with instructions on adding that information via the Zendesk API.


Another hat tip to Zendesk here as they have made the installation and management of third-party apps very simple and straightforward.

The process involves:

  1. Downloading the zip file of the latest binaries
  2. Uploading the zip file
  3. Accepting some terms and conditions
  4. Providing subdomain and API key

That’s basically it! Be sure to read the documentation on the project page for a more granular walkthrough.

Additionally, if you need to update your subdomain or API key, you are welcome to do so via the API or a point and click interface provided by the Zendesk App management tool.

Once installed the app will appear in a new pane to the right of a Zendesk user profile view and Zendesk ticket view.

The Future

We mentioned previously that this project was designed as a minimum viable product, and that’s what we’ve delivered here. While our team is really enjoying the current version, there is plenty of room for improvement.

Here’s a short list of immediate opportunities that we see:

  • Add client side caching to reduce API traffic to Chargify’s API
  • Add nested detail views for things like Subscription Statements, Subscription Invoices, etc
  • Add some update operations to push data into Chargify’s API
  • Add the project to the Zendesk App Marketplace
  • Minor enhancements designed to get novice engineers involved in open source; look for the “first-timers-only” label in the issues.

Contributions to the project are very much welcome in regards to any of the items listed above, or any other improvements you can dream up!

Effective remote work with Status Updates

This is the inaugural post in the “remote work” tag of this blog. Earth Class Mail has employees across 4 different timezones (I myself am in Sweden), we take remote work seriously and try to be a remote-first company. I have worked remotely most of my life and so there are many things I take for granted, when we should actually make a point to talk about and question even the smallest things. Today I’m going to talk about the status update, what it is, why it exists and some challenges one might come across with it.

What’s in a status update?

I’ve gone through most popular remote-management practices like daily stand-ups on Skype (then Hangouts). In the past few years status updates on HipChat (then Slack) have become a popular replacement for the stand-up. Status updates follow the same principles of a stand-up but can be done asyncronously across people in different timezones. I really like status updates, but they can be done well or not so well, but the tricky thing is that it can be hard to tell the difference.

It’s easier to get lazy when writing text than it is when you’re in a stand-up and see the other people face-to-face, so it’s important that everyone is on the same page and enforce the discipline required to write good status updates.

What’s a status update?

So first of all, let’s establish a clear definition of what a status update is. By my (and most peoples) definition, it’s a text-update posted every day in a chat channel dedicated only for status updates. In our company right now we have a #status channel on Slack where everyone posts every morning, because our team is small enough we can keep this to one channel, but in larger companies you might have a per-team channel for it. But what does an update look like?

The format can vary slightly, but it usually takes on the following form.

– list of things I actually achieved yesterday
– list of notable things that I had to do, that got in my way of
achieving what I set out to
– things i hope to achieve by the end of the day
– list of blockers that stand in your way of accomplishing your goals for today (if any)

I have seen variations where the separate Blockers field is left out entirely and instead baked into the the reasons why you didn’t achieve what you set out to achieve in the Yesterday field. I think either way of doing it is fine, but having a separate Blockers field may be useful if it can be highlighted sufficiently.

What’s the point?

There is a very specific goal with the status update: to keep everyone on the team in the loop and to force yourself to think about what you should be doing. If everyone knows what everyone is working on, people can plan around what’s going on and adjust their own priorities based on that. Lucid Meetings has a great blog post about different types of meetings, in which they write the following about the point of the stand-up meeting.

Focus on progress and what people are actually doing, only to encourage team accountability to each other and the plan.

Written status updates have gained a lot in popularity lately, to the point where there are now several services oriented around them. Three prominent ones are idonethisTeamreporter and Status Hero, and these companies list a lot of good reasons for why you should be doing status updates.

  • Know what is going on in your team and notice upcoming problems early
  • Improve communication and become a more efficient team
  • Connect remote and/or distributed teams
  • Cut through the project management noise
  • Promote transparency & trust
  • Celebrate progress

Basically, everyone on the team should know what everyone is doing, not because of some sense of keeping tabs on people or justifying their existence, but because that’s how teams can work efficiently. It’s also a way for you to say to your teammates “Hey, you may not see the result of this directly, but I did this pretty cool thing that I’m proud of!” (celebrating progress). This can either be solved by a lot of public chat communication and internal monologues held in public, or it can be achieved through status updates (or, preferably, a mix of both). I may write a whole separate post on the importance of public “internal” monologues, but as we say, that’s a different story.

What’s the problem?

I said status updates can be done badly, and it’s often hard to tell if they are. Why is that?

The fundamental problem with status updates is that getting the granularity right is really hard, and it’s easy to just ignore a status update if the granularity is wrong. You want to write a daily goal, but when you’re working on a large project where perhaps the goal for the day is somewhat uncertain, it’s hard to really write a succinct and concrete sentence or point-list that will communicate your goals for the day, it’s tempting to just write “to get as far ahead in this work as possible”. The problem with those kind of vague updates are that it doesn’t actually inform anyone of what’s going to change during the day, it doesn’t highlight what difficulties there are and doesn’t let anyone come in and say “Hey, maybe I can help with that!”. It doesn’t achieve any of the effects we want from a status update, but it will still probably pass for an acceptable update. It’s also useful for yourself to think harder about the problem, try to set out a goal even if you know it’s too ambitious, just so you have some internal roadmap for the day, it will have a good chance to increase your focus and productivity for the day.

It’s also really easy to write something that is too detailed. The status update is not a substitute for a todo-list. If you don’t think you’ll be able to get to it today, don’t write it down. You’re also not supposed to write every little detail that you do during the day, as that will add more noise than relevant communication. If there are recurring items you do every day (like create and study a daily metrics report) you shouldn’t put that on your list of achievements every single day, it doesn’t actually communicate anything to your teammates. Rather than posting that you created and studied a report, post something if there was an anomaly in a report that needed addressing, since that can have real impact to the whole team.

Status updates should explicitly not be about micromanagement or someone keeping tabs on exactly what you do in a day. The most difficult thing with status updates is to find the right resolution. The right resolution for your updates is key, but it’s only one that can be found by some amount of trial and error. If it’s too much detail, it becomes overbearing and doesn’t tell a story of what you are doing or focusing on, it adds more noise to the public communication than it tells a story of what you are working on and where you are heading. If the goal is too lofty and doesn’t actually explain what you did that day then it’s equally useless, because it doesn’t show progress or focus. 

Basically, if you’re writing the exact same thing several days in a row, you need to be more specific, and if you’re posting a bunch of (5+ items) every day, you probably need to be less specific.

If you are writing blockers, you also need to become fairly good at judging what an actual blocker is. A problem that you can work towards solving is not a blocker, it’s something that you can work on, overcome and put on your achievements list for “Yesterday”. A blocker is a problem that prevents you from doing your work and you yourself can not address.

What’s the solution?

When you get in to the office in the morning, think back on what you did yesterday. If there’s things you don’t remember, they probably aren’t important enough to go in a status update. Try to think of what your overall achievements were for the day, try to remember what made you think “Yes, finished this bit!”. Write down those things. Look back at your status update from yesterday and see if they match up, add any major reasons for why they don’t match up (if there were just many small reasons, write that).

Then sit down and think of what you’re going to do today. If it’s a bit undefined, try to define it further, think about what would make you happy if you had it done by the end of the day, and write that down.

Try to think about whether there might be anything that will prevent you from doing what you hope to do for the day. If you can’t think of anything, all clear. If you can think of something, put that in Blockers and then go talk to the person that might be able to remove that blocker for you.

Once you get into the habit of thinking of open communication and the fact that this is intended as guidance for yourself and all of your coworkers, you will hopefully get this practice into a solid place that will make everyone feel part of the family.