
There are some jobs in a business that are difficult.
Sending somebody an invoice isn't one of them.
That's precisely why I didn't want anybody wasting time doing it manually.
The process used to be completely normal:
- An order gets paid.
- Find the order.
- Generate the invoice.
- Download the PDF.
- Find the correct email address.
- Attach it.
- Send it.
- Repeat.
None of those steps are particularly painful.
Do them hundreds of times and they're exactly the sort of background admin that quietly eats chunks out of the working day.
So I automated it.
The interesting part wasn't generating a PDF.
It was working out who should receive it, when it should be sent, and how to make the whole thing reliable enough that nobody has to think about it.
I've already written about how I built the sending route without paying for another Microsoft service. This one is about the other half: who gets the invoice, and when.
A customer isn't always an email address
For a straightforward consumer order, sending an invoice to the customer is easy.
Trade orders are different.
A company may have:
- somebody placing the order
- a purchasing contact
- an accounts department
- a separate invoice recipient
- multiple trading locations
Sending every invoice to whoever happened to click the checkout button isn't good enough.
So our Shopify company records contain invoice-recipient information at the location level.
When an order is paid, the automation first works out whether there is a specific paid-invoice recipient for that purchasing location.
If there is, it uses it.
If there isn't, it falls back to the ordinary order email address.
That sounds like a tiny detail.
It is also the difference between automation that genuinely replaces the manual process and automation that just sends emails quickly to the wrong person.
Paid is the trigger
I also didn't want invoices flying out simply because somebody had created an order.
Trade ecommerce gets messy.
- Some customers pay immediately.
- Some have payment terms.
- Some orders remain pending.
- Some become overdue.
So invoice delivery is tied to the payment state.
Once the order reaches the correct paid state, Shopify starts the workflow.
From there, the system passes the information into the automation that generates and sends the invoice.
That means the trigger reflects what actually happened commercially, rather than treating every Shopify order as if it were the same.
Shopify doesn't have to do everything
One trap with automation is assuming one platform should own the whole process.
It doesn't have to.
In our case, Shopify is very good at being the commerce system.
It knows:
- the order
- the company
- the location
- the payment status
- the customer information
The automation layer handles the workflow between systems.
Outlook handles the email delivery.
The invoice service produces the document.
Each bit does the thing it's good at.
The job is getting them to communicate reliably.
The invoice recipient problem
This was one of the fiddlier parts.
The invoice recipient isn't always stored as one simple piece of text.
A company location can contain a list of recipients, while another field can contain an additional invoice address.
That means the automation has to resolve the right value before sending anything.
Conceptually, it works like this:
- Order paid.
- Is this a company purchase?
- Does this company location have a paid-invoice recipient?
- Yes: use that. No: fall back to the order email.
- Generate invoice.
- Send it.
Simple once it's working.
Less simple while you're discovering all the places business data can hide.
Then I wanted the customer to be able to get it themselves
Automating the email removed one job.
But customers occasionally need an old invoice again.
The traditional workflow goes something like:
“Can you send invoice 1234 again?”
Somebody searches for it. Downloads it. Replies. Done.
Two minutes.
Which is still two minutes too many when the customer could simply press a button.
So the next step was putting invoice access directly into the customer’s Shopify account.
Open the order. Download the invoice. Done.
No email. No support ticket. No member of staff doing digital archaeology through six months of orders.
This caused another unnecessarily interesting problem
The neat solution was a customer-account extension.
The less neat part was getting the extension to behave properly in the environment we were using.
At one point the editor and domain setup decided they weren't particularly interested in cooperating.
Rather than abandoning the feature, I ended up using a different method to add the invoice action into the account interface.
Not necessarily the prettiest route on paper.
But it worked.
And that is another recurring lesson with business systems:
The technically elegant solution isn't worth much if the customer can't click the button.
The automation nobody notices
This isn't a flashy AI project.
There's no chatbot.
Nobody is going to make a keynote presentation about the revolutionary possibilities of automatically sending a PDF.
That's why I like it.
- Order gets paid.
- Invoice goes to the correct person.
- Customer can retrieve another copy whenever they want.
- Nobody in the business needs to touch it.
That is what useful automation often looks like.
Not replacing an entire department.
Not producing a dramatic demo.
Just removing a repetitive little job permanently.
Do that enough times across a business and the effect starts becoming quite significant.
The actual test
There's one question I keep coming back to with automation:
Does this remove work, or has it just moved the work somewhere else?
If somebody still has to inspect every invoice email, correct the recipient, fix failed PDFs and manually handle half the edge cases, you haven't really automated anything.
You've built another system to supervise.
The goal isn't to make the workflow look clever.
The goal is for the workflow to disappear.
In this case:
Paid order in.
Invoice out.
That's the result I wanted.
And unlike some of my projects, this one may actually save more time than it took me to build.
Probably.
Good job, buddy.