x_trans_id Is Not Your Invoice Number: An Authorize.Net Direct-Post Bug
An OR fallback treated x_trans_id and x_invoice_num as the same identifier, so every prod receipt failed while tests passed. The fix was deleting half a line.
The build log
Build log, architecture patterns, and observations from running autonomous AI systems in production.
An OR fallback treated x_trans_id and x_invoice_num as the same identifier, so every prod receipt failed while tests passed. The fix was deleting half a line.
Stripe expects your landing page to capture the charge; Authorize.Net DPM settled before the redirect. Copying one handler for the other fails silently in prod.
When a gateway won't POST to localhost, ship a throwaway relay page to prod and read the real payload. Three bugs surfaced that a faked callback never would.
A 327-unit recovery was too risky to validate by instinct. A plan mode, diffable before-and-after artifacts, and a disposable test database made the production run inspectable before it wrote live data.
After a successful data recovery, the script was still armed: real customer username hardcoded, phase set to run. The most dangerous minute for a destructive tool is the one right after it succeeds.
Three recovery scripts shared one un-scoped UPDATE bug that could corrupt other tenants. Consolidating them gave the bug one place to live.
When a hand-maintained recovery script has to stay in sync with a 14,536-column database, discipline alone won't cut it. Here's how a 418-line Python differ and a source-of-truth decision solved the problem.
When a customer's entire site gets deleted in a shared-database multi-tenant system, RESTORE DATABASE is not an option. Here's the copy-first, remap-IDs-second pattern that makes application-level recovery work without cross-tenant corruption.
SQL Server's datetime epoch (1900-01-01) looks like a real date, serializes cleanly, and inserts without error. That's exactly why it corrupts migrations. Here's how to catch it and why you need to omit the column, not blank it.
How we collapsed a 3.5-million-round-trip ID remap into a handful of set-based join-UPDATEs using temp tables, and why the index matters as much as the query.
The real failures and fixes from building AI systems, one practical lesson per post. Get the next one in your inbox.