Forecourt Engineering

11 parts, in reading order.

May 16, 2026·10 min read

Forecourt Engineering, Part 1: Why the Pump Holds £100 on Your Card

You fill up for a few pounds and your banking app shows a £100 hold. That isn't a mistake, it's pre-authorisation doing its job, and the interesting engineering is in what happens when the link to the payment switch drops halfway through.

paymentsarchitecturedotnetreliability
May 18, 2026·10 min read

Forecourt Engineering, Part 2: The Side Effect That Gave the Fuel Away

A pay-at-pump sale delivered the fuel and cashed out at £0. The cause was a generic stop command that quietly gave up ownership of the pump, reused somewhere nobody expected. The fix was one line, and the audit that made it safe was the real work.

dotnetarchitecturedebuggingreliability
May 20, 2026·10 min read

Forecourt Engineering, Part 3: When Every Client Reconnects at Once

A whole bank of card terminals went dark overnight, and the payment switch that fell over was perfectly healthy until every terminal signed in at the same moment. The burst was ours to prevent, the main fix was someone else's, and the timeline everyone believed was wrong.

architecturereliabilitypaymentsdotnet
May 22, 2026·10 min read

Forecourt Engineering, Part 4: Your Sockets Are Lying to You

A socket that died quietly looks exactly like one with nothing to say, and on a forecourt network nobody closes a connection politely. A colleague and I stopped a service holding on to dead links until someone drove out to restart it.

dotnetnetworkingreliabilityarchitecture
May 24, 2026·10 min read

Forecourt Engineering, Part 5: Two Timers, One Timeout, and the One That Always Wins

A settings change only took effect on the third button press, and the value in the database was right the whole time. Two components were each running a timer for the same thing, and the shorter one always wins.

dotnetarchitecturedebuggingreliability
Jun 11, 2026·10 min read

Forecourt Engineering, Part 6: The Empty Window at Start-Up

After a restart, the pump list was briefly empty, because the code cleared it before the thing that would refill it had even connected. Everything that read it in that window quietly worked on nothing, including the step that closes pumps overnight.

dotnetarchitecturereliabilitydebugging
Jun 15, 2026·10 min read

Forecourt Engineering, Part 7: The Simulator Was Too Polite

I designed a payment-host simulator to answer straight away and send the receipt afterwards, because that seemed sensible. Real captures showed real hosts hold the payment response until the receipt is acknowledged. A capture beats a design decision, even one you've already written down.

dotnettestingpaymentsarchitecture
Jul 12, 2026·9 min read

Forecourt Engineering, Part 8: Fail per Pump, Not per Terminal

Choose the smallest failure domain you can, so one broken link takes out one pump, not a whole island. A card terminal at a fuel pump keeps one link per pump. The post covers what customers see when one fails, and why 'no link configured' and 'link down' are very different.

paymentsarchitecturereliabilitydotnet
Jul 29, 2026·9 min read

Forecourt Engineering, Part 9: Store and Forward, and How Long the Store Can Hold

Store-and-forward doesn't remove risk, it moves it from 'the sale is lost' to 'how long can we wait'. What a card terminal does with completions and reversals when the link to the switch is down, the one case where retrying is pointless, and what to monitor so a store that never drains gets noticed.

paymentsreliabilityarchitecturedotnet
Aug 14, 2026·9 min read

Forecourt Engineering, Part 10: Keep Money in Whole Pence

When money is already whole pence in the code, keep it whole pence in config too, and a lot of parsing, rounding and culture handling disappears. A test amount first written with a decimal point shrank a design, and the comparison is against what the customer chose.

paymentsconfigurationdotnetdesign
Aug 30, 2026·9 min read

Forecourt Engineering, Part 11: One Transaction, Two Numbers

If a record is stored under one identifier and looked up by another, it will look missing, and the logs will make it look like something else entirely. A receipt reprint couldn't find its transaction. The post covers my best reading of why, and how to keep one real defect apart from declines and noise.

debuggingpaymentsdotnetinvestigation