The Receipt Nobody Notices
Why receipts are one of the hardest emails to build. Order number, line items, total, thanks for your purchase — a receipt reads like nothing until you actually sit down to build one. Then it turns into a small case study in everything that’s hard about email: design, engineering, business logic, tax law, localization, and a decade of inconsistent rendering engines, all packed into a message most people glance at for four seconds and then archive.
Why receipts carry more weight than marketing email
Marketing email and transactional email get talked about like they’re the same discipline with different content. They aren’t. A promotional email that renders badly costs you a click. A receipt that renders badly, or worse, states the wrong total, costs you a support ticket, a refund, or a customer’s trust in whether the purchase actually went through. Receipts are also expected to arrive, and arrive fast — inbox placement on a transactional message isn’t a nice-to-have, it’s the whole job. Nobody re-sends a receipt out of a marketing calendar. It has to work the first time, every time, because for a lot of customers the receipt is the only proof they have that the transaction happened.
That’s the real reason receipts get treated as boring by people who haven’t had to build them: they’re not allowed to fail in ways that are visible, so most people never see how much engineering it takes to make them invisible.
The scenario problem
A marketing email usually has one payload: a promotion, a headline, a CTA. A receipt template has to survive hundreds of purchase scenarios, often inside the same merchant’s data. One item or twelve. A single shipment or three partial shipments arriving over two weeks. A discount code, a gift card, a store credit, and a partial refund all applied to the same order. Buy-online-pickup-in-store versus straight shipping. A subscription renewal versus a one-time purchase. Every one of those states changes what the receipt needs to say, and a template that only handles the happy path breaks the moment a real customer does something a designer didn’t picture in the mockup.
This is the part of the job that pulled me toward building Receipt Lab in the first place — a way to render the same Handlebars template against dozens of different JSON payloads and actually see the edge cases before a customer does, rather than discovering them after a partial-refund order goes out looking broken. When your logic branches this many ways, “did we test the receipt” stops being a yes-or-no question and becomes a coverage question.
Money, taxes, and loyalty math
Once the scenario handles itself structurally, the numbers on it have to be right, and that’s its own layer of complexity. Currency formatting isn’t just a symbol swap — decimal placement, thousands separators, and rounding conventions differ by locale, and a receipt that’s localized for language but not for currency formatting reads as sloppy at best and wrong at worst. Tax display requirements vary by jurisdiction, and getting the breakdown wrong isn’t a cosmetic bug, it’s a compliance problem. Layer loyalty programs on top — points earned, points redeemed, tier status, a partial payment made in points and the rest in currency — and you’ve got math that has to reconcile perfectly against a total the customer already saw at checkout. None of this is optional detail. It’s the actual content of the email, and it has to be correct before it’s ever styled.
Rendering: the part nobody outside email dev believes
Then there’s making it look right, which in email means making it look acceptable across a set of clients that don’t agree on what HTML and CSS mean. Outlook’s desktop apps have historically rendered HTML email using Word’s layout engine rather than a standard browser engine, which is why so much receipt code still leans on MSO conditional comments and table-based layouts instead of anything resembling modern CSS. Gmail has its own quirks, including clipping messages once the HTML payload crosses roughly 102KB, which matters a lot for a receipt with a long line-item table, embedded terms language, and tracking pixels all competing for the same budget. Mobile clients need the layout to hold at a fraction of the width without turning a tax breakdown into an unreadable column of numbers. And printing — because customers still print receipts for expense reports and returns — means the design has to survive without the CSS trickery that makes it look good in a browser.
Dark mode adds a layer most people don’t think about until it bites them: some clients auto-invert colors or reinterpret backgrounds to match system theme, which can turn a carefully chosen brand color scheme into something illegible or, worse, turn a white logo on a transparent background into an invisible one on a dark background. It’s a big enough problem in its own right that I built DarkPrefer and DarkView specifically to catch it before customers do — because “it looked fine in light mode” has never been a useful QA standard for email.
And accessibility isn’t a separate checklist item bolted on afterward — a receipt read by a screen reader, at a contrast ratio that actually meets the WCAG guideline of 4.5:1 for normal text, is table stakes, not a stretch goal.
Why testing a receipt is its own discipline
Put all of that together and you get why testing a receipt properly is genuinely hard: you’re not testing one email, you’re testing a matrix — every scenario, times every currency and tax jurisdiction, times every loyalty state, times every major client in both light and dark mode, times mobile and desktop and print. Manual QA doesn’t scale against that matrix, which is exactly the problem that pushed me to build tooling rather than just click through previews by hand. The goal isn’t to eyeball a receipt and hope it’s fine. It’s to have a fast, repeatable way to see every version of the truth before a real customer does.
The point of all of it
A great receipt isn’t noticed. Nobody forwards it to a friend, nobody screenshots it for a portfolio, nobody compliments the tax line. It just lands, it’s correct, it’s legible in whatever client and mode the customer happens to be using, and it answers the one question the customer actually has: did this work.
That invisibility is the whole craft. The people who build receipts well are solving problems that most people don’t even know exist, and the only visible evidence of the work is that nothing ever goes wrong.