A weekly finance report for a subscription business we built and run

The business charges its customers through Stripe. Here is how the weekly report is built, how every number is checked and what we learned.

The starting point.

Customers pay on a schedule

Weekly, monthly and quarterly plans, each with a free trial, all charged through Stripe.

A payment can end many ways

Paid, still on a trial, cancelled, or declined by the card for one of several reasons.

Stripe holds every payment

Subscriptions, invoices and charges all live in Stripe, so the weekly report starts there.

Customer data stays private

Customer names and emails stay private, out of the program itself.

01

The report can look at every payment and change none of them.

The report downloads every subscription, invoice and charge, to the last one, and saves them exactly as they came. The tool that writes to Stripe is blocked for it.

Try it · example data

Download this week's data and watch every page come in.

It keeps asking for the next page until there is none, so nothing is left out.

Rule for the reportWriting to Stripe is blocked.

It can read payments. It can't refund, charge or edit anything.

From Stripe · read onlyExample
  • Subscriptionswaiting0 pages
  • Invoiceswaiting0 pages
  • Chargeswaiting0 pages

Nothing saved yet

Blocked from writingThe tool that changes Stripe is switched off for this agent, so a mistake can never move money.
Every page, to the endStripe sends data in pages. The agent follows them to the last one, so every payment is counted.
Saved as it cameThe raw data is kept unchanged, so any number in the sheet can be traced back to it.
02

Every subscription gets one clear status.

A tested program goes through every customer, leaves out internal and test accounts, joins tries made within an hour into one, and gives each subscription one of 6 statuses, using the card's real decline reason.

Try it · example data

Sort this week's customers and see where each one lands.

Several tries within an hour count as one, and test accounts are left out of every total.

This week8 customers
    Tries within an hour count onceA customer who tries their card three times in a few minutes is one subscription, not three.
    The card's real reasonA decline is sorted by the bank's own reason, like not enough funds or a blocked card, not a general label.
    Test accounts left outInternal and test accounts are removed before anything is added up, so they never inflate a number.
    03

    The sheet must match the payments to the cent, or it isn't sent.

    Two independent sources are compared: the sheet's total and the sum of paid charges in Stripe. If they differ by more than one cent, the program stops with an error and no sheet goes out.

    Source 1The sheet's total$1,000.00
    Source 2Paid charges in Stripe$1,000.00
    DifferenceUp to $0.01 allowed$0.00
    ResultThe sheetSent

    Both sources agree, so the sheet goes out.

    Entries · one customer per lineWeeks · live formulasCash · money in per week

    Example figures. The check runs every time the sheet is built.

    Two sources, one answerThe sheet is built from the downloaded data, and Stripe's paid charges are added up on their own, so one checks the other.
    It stops instead of guessingWhen the totals differ, nothing is adjusted or rounded away. The program stops with an error instead.
    Formulas anyone can recheckThe Weeks tab counts and adds with live formulas, so anyone can open a cell and see how it was worked out.
    04

    The AI writes the words, never the numbers.

    The program saves its results in one small file. The AI reads only that file and fills in a fixed template, so every number in the summary comes from the calculation.

    The program's resultsExample
    
            
    The weekly summary
    The summary is written once the results file is ready.
    A fixed templateThe summary always follows the same structure, so it is easy to read and easy to compare week to week.
    One file in, words outThe AI sees the results file and nothing else, so it has no way to add a number of its own.
    13 automated testsThe rules behind the statuses and the sums are covered by tests, so a change that breaks a rule is caught.

    The project in numbers.

    13automated tests on the calculation rules
    6statuses for every subscription
    3tabs in the weekly sheet: entries, weeks and cash
    $0.01the largest difference allowed between the sheet and Stripe

    Source: the project's code, read on 21 October 2026.

    What we learned.

    01Give an agent only the access it needs.

    Reading payments was all the report needed, so writing was switched off from the start.

    02Numbers come from code you can test.

    The AI is good with words. Sums belong to a program with tests.

    03Two sources must agree.

    Comparing the sheet with Stripe catches a mistake before anyone reads the report.

    04Use the real reason.

    A declined card has a specific reason, and the follow-up depends on which one it is.