Building a Subscription Payment and Accounting System

By: George Matelich

Payment systems are complicated. Accounting systems are complicated. We expected some of this and learned a lot of it the hard way.

Initially, we launched iHeart AdBuilder with a direct integration to Cybersource, our payment gateway. This integration was meant to get us to market quickly but didn’t solve every payment problem we might face (card storage, low friction, clean UX, etc.). In tandem with Cybersource, we connected to NetSuite to handle invoicing, recurring payments, and accounting needs.

V1 Architecture:

iHeart AdBuilder payment system v1 architecture

However, as iHeart AdBuilder grew, it quickly became apparent that our MVP solution was no longer cutting it. We lost a lot of customers due to payment failures or confusion with how billing worked. About 30% of all cancellations happened due to payment system issues, and over 50% of revenue loss came from cancellations. It turns out that if the customer sees weekly preauthorizations for one amount and then settlements for another amount, they aren’t always comfortable. We also required customers to re-input their card information every time they checked out because we couldn’t store it for them — talk about friction.

Finding the Right Solution

So, we analyzed the major pain points to determine the most valuable problems to solve and searched for a vendor to help us make these plans a reality. Pain points like checkout friction (only ~63% of users that get to the payment page actually complete this step), billing cycle confusion, invoice customization, and incentives were the priorities as we shifted our focus to potential vendors.

The vendor search surrounded platforms that enabled storage of cards, incentive offerings, and the best billing experience for our customers. This research led us to Recurly. Recurly is “the subscription platform powering possibilities.” It is NOT a payment gateway or a payment processor. Recurly is gateway agnostic, meaning our negotiated contract with Cybersource remains, and instead of directly interacting with the gateway, Recurly does that on our behalf. It also handles card storage and allows us to build our own billing experience through robust APIs.

Designing Our Solution

We began designing and iterating on a new checkout experience that is easier on the user and more intuitive. We determined what was possible with Recurly and started creating our data model.

To take a step back for a second, I should explain the mechanics of a campaign. A campaign can include many spots across multiple radio stations, all of which are different business units. So, one campaign—for which the user is billed a fixed amount—is potentially composed of hundreds or thousands of single billable spots at many different business units. All of this needs to be accounted for on our side and abstracted away from the end-user.

With that in mind, our engineering team began designing a billing microservice to handle the daily aggregation of spots and billable ad plays for each active campaign while ensuring that they were accounted for at the correct business unit at the right time (hello timezone math).

We also designed two flows for billing users: a trusted flow and an untrusted flow that is extensible. A “trusted” existing user who has previously paid for an ad campaign can book and pay in arrears. A new “untrusted” user might hit a usage threshold mid-week at the beginning of their first campaign to ensure they have sufficient funds to keep running their ad. Following that, they will fit the trusted user model as well.

Another important stakeholder for this project is the accounting team. To move this process out of NetSuite, we needed to find a way to get this data to accounting in a manner that was easy to understand and leverage for a monthly, quarterly, and yearly close process. This means that an all-encompassing transaction report for cash reconciliation was essential, as was a revenue recognition report at the business unit level. We had to ask, how aggregated or not should this report be? Should every play at every station show on these reports? If so, we might break excel. What must be, at a minimum, accessible for an audit when the time comes? All of this factored into the data model, micro-service construction, and scheduling of jobs.

Time to Start Building

After consulting major stakeholders and designing solutions, we began to build. The building, of course, uncovered unforeseen issues. Some of those were minor, like learning that MQL (Mongo Query Language) has its quirks. Some issues were more significant such as refunds, which are really complicated when re-distributing a partial or full refund across each business unit. And refunding a settled vs. unsettled transaction, each of which has very different mechanics as far as payments go (voided transaction vs. new refund transaction).

Another unforeseen issue was that payment gateways might allow you to configure requirements like relaxed AVS (address verification service), regardless of what your payment processor requires. In our case, our test gateway was set up with a more relaxed processor than production (whoops!), meaning the switch to production uncovered that we didn’t provide enough information to the payment processor to complete the transaction successfully.

What I Wish I Knew Going Into This

Payments are complicated, and there is much more to handling charges than simply connecting to some gateway. Gateways connect to processors that connect to acquiring banks that connect to card networks which connect to issuing banks that eventually link back to you. That all happens almost instantaneously, and it’s incredible but, it also means that each of those layers has its intricacies that are important to understand. I wish I had gone more into the details initially, not when I had to. I also wish we uncovered some of the more complicated edge cases earlier, but hindsight is 20/20, and planning for edge cases is difficult.

Why I’m Happy It Wasn’t All Smooth Sailing

I am happy there were complications with payment processing because now I feel like I really understand it. I am also glad that we had to iterate on our design and data model because it helped us arrive at an extensible and self-reliant solution.

What It Means For Our Users

iHeart AdBuilder users can now store their payment methods on their accounts, receive more intuitive and descriptive invoices, and checkout easily. Soon, they will also have access to incentives we choose to offer.

In closing, this project has been an incredible learning experience for our team. We came together and built a fully functioning subscription billing and account system that is good for iHeart AdBuilder users and accountants. Despite hurdles, hiccups, and resource constraints, this project brought out the best in terms of communication — it took a lot of clarifying questions from all of us to get to the meat of specific issues.

Now that we are on the other side, it has been gratifying. We are growing fast and ready for the next challenge! To know that this solution will help iHeart AdBuilder scale gives us comfort and excites us about where we’re heading.