Billing Microservice

  • Javascript
  • HTML
  • CSS
  • Node
  • Stripe API
  • Heroku

To satisfy my company's need for the ability to collect payment information during a time when we were short on engineering expertise, I built a Node app using the Stripe Elements library that successfully collects credit card information, tokenizes it on an Express server, then makes an API call to Stripe to create a new customer with an associated credit card. I did this with 0 prior experience in Javascript or Node; this was the first professional programming project I tackled.

Where it all Began

This project holds a special place in my heart, as it launched me down the rabbit-hole of programming that would go on to shape my professional direction and goals through the following years. I began on this when our (then) 6-person team at Astronomer realized we had found product-market fit with our managed Apache Airflow platform. Things got crazy quickly- we had spent a year building an MVP and soon after launching, we found ourselves needing to scale more quickly than we had planned.

Along with that scale came the need for engineers; as it turns out, when you're building a company centered around open-source software that primarily sells to data engineers, technical firepower is essential across every area of the business. There was just one problem: we were quickly running out of money from our previous financing round and couldn't hire the folks we needed to push some of our critical technical projects through the finish line.

The Problem

We had an endless list of engineering projects across the board that needed to be tended to, and, at the time, our CTO, CEO, and a single junior developer were doing the bulk of the technical heavy lifting. One of the projects that our growth team really needed done involved collecting payment information from users of our SaaS product. Astronomer Cloud was maturing and beginning to generate real value for our customers; people wanted to pay us for the service, but we didn't quite know how to collect their credit card information and had no experience integrating with any popular payment APIs.

So, for a time (and this still makes me cringe), we set up a Noteshred account and asked people for their credit card information via that service. It was pretty janky; people were emailed a blank text field and told to submit their credit card number, cvc, billing zip code, and name to that field and we'd go ahead and add their information manually to our Stripe account.

On the same note, we were beginning to normalize our internal processes as we prepared for scale. Towards that objective, I felt that users should be able to sign-up and pay for our product in the self-directed way pioneered by Atlassian back in the 2000s when they successfully scaled their business in a fully automated way without a sales force.

While I’m not sure exactly what my title was at the time, I know that, at a high level, I was responsible for growth of our business. As is typical at an early-stage company, I was given an arbitrary goal (in this case, to do whatever needs to be done to help the company grow our ARR) and told to run with it. To me, the inability to collect payment information in a reliable way was the biggest kink in our sales process; we often had folks sign up for a trial, like the service, then be blocked from converting due concerns with our payment process.

Keep in mind that, at that point in my career, I had virtually no experience programming. I had taken some computer science in college and was pretty solid with git from pushing markdown files to our docs site, but never moved beyond entry-level concepts.

After some research, I learned that Stripe is not only a convenient tool for charging customers cards manually (as we were using it at the time), but also has an API designed to help businesses like ours build more robust payment integrations. This was a pretty big revelation for me, and was the first step on what would become a significant journey in technical exploration.

Scoping the Solution

Idea One: Core Product Integration

My first idea was to build a simple Stripe payment form directly into our app's React UI. How hard could it be, right? All we needed to do was do some programming magic, send some data to Stripe, and - voila - our payment problem would be solved. After digging a bit, I found Stripe's React Elements library that they've open-sourced on Github. After a few nights of wrestling with npm and learning how to run applications locally, I finally was able to actually make something appear in my browser:

Billing 1

It wasn't pretty, but I was absolutely ecstatic to see some progress. At the time, I was basically just following Stripe's guides and copy/pasting code until something worked, but after another week or so of css/html learning and application, I was able to mangle that barebones form into a format that was a bit more passible:

Billing 2

Still not pretty, but progress! At this point, I decided to dive into a Udemy course in React as I continued progressing through this project. That helped get my wheels spinning a bit faster as I continued to build this form out, but it became evident pretty quickly that it wouldn't make sense to bake my amateur work directly into our production application, as the goal here was to just decrease friction in the sales process rather than improve our core product.

Idea Two: Standalone Microservice

After realizing that it wasn't going to make sense to build an integration with our core product right out-of-the-gate, we decided it'd be best to build this as a standalone application that served a purely administrative purpose. So, we planned to stand up a fully independent front-end and API to handle routing network requests to Stripe (you can't make calls directly from the client because it'd expose credit card information to potential man-in-the-middle attacks). After a few weeks of diving deeper into into building full-stack applications and reading literally every post I could find on Stripe integrations for beginners, I ended up forking Stripe's payment form demo on Github and repurposing it to fit our needs.

Billing 3Billing 4

These forms didn't require much tweaking out-of-the-box, but they only encapsulated the client-side work needed for this project; in order to connect to your own Stripe account and transfer a customer's payment information, you need a server-side component to handle decryption and data transfer. So the next step here was to learn about the Express framework so that I could spin up a lightweight Node API and deploy it to Heroku.

The Final Product

At the end of the day, after about 2 months of learning the fundamentals of programming, I was able to get the app running in production. Our count of paying customers jumped by 6x in the month following, as we were free to implement a much greater degree of automation around sign up and payment for our service. While this app is still running in production for us as of September 2019, I actually spent a good bit of time integrating a smoother and more robust Stripe payment system into our core application that will go live soon. I'll save that story for another write-up!