This one is our own problem. We resell a cloud backup service to our clients. The vendor bills us per customer group and emails a receipt for each one. For each receipt, someone had to find the matching client, apply our markup for that product, create an invoice in QuickBooks Online and send it.
It wasn't hard work, but it was constant and easy to get wrong. A missed receipt meant revenue we never billed. A typo meant a confused client. It is the same kind of problem most of our clients bring us: a routine data handoff between two systems, done by a person because nobody connected them.
What the automation does
A small Azure Function runs every five minutes and does what the person used to do:
- Reads the billing mailbox through Microsoft Graph and picks out new vendor receipts
- Parses each receipt into structured data: the customer group, the product and the amount
- Matches the group to a client using a mapping table we control
- Applies the markup for that product type, from configuration, not hard-coded
- Creates the invoice in QuickBooks Online through the QuickBooks API
- Emails the invoice to the client from QuickBooks, just as if we had sent it by hand
- Files the receipt into a Processed folder so the inbox shows only what still needs attention
The safeguards matter more than the happy path
Automating billing is only worth it if you can trust it. Most of the design went into what happens when something is wrong.
Nothing is skipped silently. Every receipt ends a run in a clear state: invoiced, excluded on purpose, or failed with a plain-English reason. A receipt for a customer group with no client mapping, or a client with no QuickBooks customer, doesn't disappear. It is recorded with the reason and moved to a Failed folder in the mailbox, where a person can see exactly what to fix.
No double billing. Each receipt is recorded by its unique email ID, and every run checks that record first. If a receipt is seen again, for example after a hiccup moving the email, it is recognized and skipped, not invoiced twice.
Dry-run mode. A single setting makes the whole run do everything except create and send invoices, and it produces a full report of what it would have done. We ran it that way against real receipts until the report matched what we would have billed by hand.
A manual trigger. Besides the timer, there is an endpoint that runs a batch on demand and returns the full report. That is useful when testing a change or catching up after a vendor outage.
Token handling is built in. QuickBooks Online gives you a new refresh token every time you refresh, and the old one stops working. If you don't save the new one right away, your integration eventually locks itself out. The function saves every new token immediately and shares them with our client portal, so the two never fight over access.
What changed
Billing for this product no longer depends on anyone remembering to do it. Invoices go out within minutes of the vendor receipt arriving. The only time a person gets involved is when the automation flags an exception, and it tells them exactly which one and why.
The pattern is everywhere
Swap in your own vendor and your own accounting system and you probably have this problem too: supplier invoices becoming bills, order confirmations becoming sales orders, timesheets becoming invoices. If a person is copying numbers from an email or PDF into your accounting system, that step can usually be automated safely, with a dry run and clear exceptions so you never lose control.
See how we approach systems integration, or get a free assessment and we'll show you which of your handoffs are worth automating first.