This is an ultra-specific topic (and not crypto accounting), but we’ve run into this issue so many times that it’s worth a full-length Hash Basis article! Most people have interacted with Stripe in one way or another - purchasing a software subscription, event tickets, API calls, you name it. Stripe is worth roughly $70 billion at the time of writing, reflecting its value in the global payment landscape. While it’s function is undisputed, there’s a big drawback for the bean counters of the world: their accounting & reporting infra isn’t great, especially if you don’t purchase their advanced revenue recognition module. Attempting accrual accounting without paying extra is a daunting feat, but luckily we’ve figured it out. 😎
Every month, without fail, we run into reconciling items as we’re cleaning up Stripe accounting for our clients. Even though we’re a crypto accounting firm, these clients use Stripe to collect fiat revenue from their end users for API metering (i.e. for private key tooling) and conference tickets. Completing the Stripe reconciliation is always the last and least appealing item on our close checklist, but we get it done. See below for all the hacks we’ve discovered over the years!
Stripe Accounting 101
The basic structure of the Stripe account is this:
- Beginning cash balance in Stripe
- + Revenue collected
- - Stripe fees
- - Bank payouts
- = Ending cash balance in Stripe
It took me a while to realize that a company typically has an ending balance of cash sitting on Stripe, representing revenue that’s been collected but not disbursed to the bank yet. To account for this balance, we create a separate “Cash In Stripe” account on the balance sheet that fluctuates month over month, based on Stripe’s canned reporting. To find this balance report, head to Stripe → Reports → Balance Summary to see the inflows, outflows and ending balance for a given month. A report with example numbers looks like:
Other Stripe accounts include Account Receivable on Stripe, Stripe fees, and Gross revenue. I recommend creating a “Stripe” vendor in your ERP system so you can easily track the native balances on the platform. Here’s a quick breakdown of these accounts:
- Accounts Receivable - invoices that are created on Stripe that haven’t been paid yet. The sum of the “open” invoices on the Invoices tab should equal the ending Stripe AR balance
- Stripe fees - fees displayed on the balance report above (can also be viewed on the All Activity Balance Report → more on that later)
- Gross revenue - accrual basis revenue for a company’s product or service; could also include revenue billed outside of Stripe
Completing a Manual Stripe Reconciliation at Month-End
Here at Hash Basis, we’ve got our month-end Stripe process down to a science. For our particular customers, this methodology has proven accurate for several closes now, even though we don’t use the advanced revenue module. Our goal is to reconcile the balance sheet to Stripe reports and also ensure revenue is under an accrual basis. See here for an example reconciliation that’ll guide you through this section:
The Hash Basis Recipe for Reconciling Stripe 🍛
- Categorize bank payments from Stripe to the customer’s bank account as revenue - note: this is considered preliminary revenue that will later be adjusted to account for fees and invoices that haven’t been paid by the customer or paid out to the bank yet. It’s a starting point we adjust from.
- Customer creates & sends all manual invoices that need to be added to a given period. Stripe is normally used for goods and more routine services like software subscriptions, but it can also be used as a vanilla invoicing platform. Our customers often have a blend of both, so there’s a manual component at month-end. As we discovered, there’s no way to back-date invoices, so if a client doesn’t get around to sending July invoices until August 2, the invoice date defaults to August, and we have to manually add the invoice back to July close (if the service period relates to July).
- After the manual invoices are added (if any), we run specific Stripe reports and begin the reconciliation process. We download the following reports:
- All Activity Balance Report for the month (Balances → All Activity → Export for last month → Export All Columns)
- I use this report to tie out the total fees Stripe is reporting
- Payout Report (Balances → Payouts)
- This report shows all the payments from Stripe to the connected company bank account. I tie this report out to the bank reconciliation to ensure the company received all the payments Stripe is reporting.
- Invoices (Invoices → All Invoices → Export all dates → Export All Columns)
- This report is a massive data dump that shows all invoices ever created, their current status (i.e. paid, not paid, void, draft) and amounts.
- I create two new columns: 1) Status as of {Month-End Date} and 2) a comparison calculation between the invoice amount and the amount paid, if the invoice has been paid (you’ll see why later)
- I add a new status column because if I run the report as of, let’s say, August 2, there could’ve been July invoices that were paid between August 1 - August 2 that are showing as “Paid”. However, their status was “Open” as of July 31. This is important for getting the revenue in the right period.
- The same concept goes for invoices that were manually created by the customer after period end. I change the date to month end (i.e. July 31) so revenue is accounted for accurately.
- Balance Report (Reporting → Balance Summary → Export for close month)
- All Activity Balance Report for the month (Balances → All Activity → Export for last month → Export All Columns)
- Accrual Revenue calculation - for this step, I create a pivot table of all the invoices sent from inception to period close and separate by customer and status, only pivoting off the “open” and “paid” statuses (so we don’t include junk statuses like void or draft). I calculate the difference between the current sum and the previous months’ pivot table to see the true incremental revenue for the month. This report also tells me what the ending Accounts Receivable balance should be (the sum of the “open” column in the pivot table).
- Reconcile the remaining accounts and book the final entry - this includes looking at what’s currently booked in the ERP and comparing it against what it should be based on Stripe reporting. An AJE might look like this:
You might be pondering, What’s in the Other Receivables account? Oftentimes, my adjusting entry doesn’t tie out, and I find the issue lurking in the Other Receivables account. 👀 Before I spill the beans, check out this video that walks through the example reconciliation in detail!
Ways your Stripe Revenue Reconciliation Can Be Off (and How to Fix It)
As I mentioned, we’re usually off by a small (or large) amount every single month. We’ve discovered a few reasons why the adjusting entry doesn’t tie out:
- Stripe thinks a bank payout (i.e. from Stripe to the company’s bank) has completed, but the cash is still in transit —> this can happen if a payout is initiated on the last day of the month. In that case, you’ll need to debit “Other Receivable” or “Cash in Transit” for the straggler payment. A simple comparison between your bank statement and Stripe’s Bank Payouts report will catch this.
- An invoice is marked as “paid”, but it wasn’t actually paid through Stripe (i.e. it was settled through Ramp, Bill.com, paid directly to the bank, etc). You can catch this because the “Amount” column has the expected revenue, but the “Amount Paid” column says $0 since the customer invoice wasn’t paid through Stripe — this is why I create the “Difference” column in the example recon.
- To fix this, confirm whether those invoices were actually paid and where - you may need to debit “Other Receivable” again for the difference or reconcile the account where funds were actually received.
- The customer paid directly via ACH in Stripe
- For context, a customer can either pay directly through Stripe or ACH directly to Stripe’s bank account. This option appears on manually generated invoices:
- When I investigated this further with a client, we realized Stripe had actually credited the customer’s account for the amount paid, but it never made it into the company bank account. Specifically, it appears direct ACH payments land in the “ACH credit transfer” category. There’s no way to transfer these funds in the UI, so you’ll have to call customer support for assistance.
- Invoice dates can get mixed up. For example, a customer can send an invoice through Stripe on August 2 but the revenue technically relates to July. When reconciling Stripe for July, you’ll need to artificially increase the AR balance for the straggler invoices in August (so Stripe AR may not always tie out to calculated AR).
Oh Stripe 🤦🏻♀️
As you can probably tell, Stripe is finicky and has kept me up many-a-nights during month-end close. The UI is slick and makes me want to spend money, but the accounting reporting leaves a lot to be desired. We’ll keep updating this article as we discover new oddities and solutions to these issues - and if anyone from Stripe is reading this, feel free to reach out for a 1:1 feedback session with a cracked accountant! 😵💫