Local ledger first
Every transaction was written to a local SQLite ledger before any network call. If the network was down, the customer was served and the transaction queued.
$1.5M+ AUD processed across 100+ devices in 10 days, zero critical failures
A large live event running over 10 days, with payments taken on 100+ Sunmi and Zebra terminals — card payments through Stripe Terminal and RFID wristbands for pre-loaded credit. I was the sole engineer on it.
The hard part wasn’t payments. It was the network.
Venue wifi could not be relied on per transaction, and a terminal that can’t reach the processor still has a customer standing in front of it. Connection loss wasn’t an edge case to handle — it was the normal operating condition to design around.
Every transaction was written to a local SQLite ledger before any network call. If the network was down, the customer was served and the transaction queued.
This is the detail that makes the whole thing safe. A retry whose response was lost returns the original payment rather than creating a second one — so a customer cannot be double-charged by a network failure.
Without jitter, 100+ devices reconnecting simultaneously after a wifi blip become their own outage against the processor.
Offline card-present means accepting before authorisation, so the business carries decline risk. Per-transaction and per-device ceilings bounded that exposure.
Device ledger, server ledger, and Stripe’s settlement report, matched on PaymentIntent ID. Anything unmatched was flagged for human review rather than auto-resolved — with money, silent correction is how small discrepancies become large ones.
Over $1.5M AUD processed across 10 days on 100+ devices, with no critical failures and no unexplained discrepancies in reconciliation.
Most payment integrations work in testing and fail in production, because the happy path is the easy part. The questions worth asking early are what happens when the network drops mid-authorisation, what happens when a response is lost after a charge succeeded, and how you’d know if your ledger and the processor disagreed. If those don’t have answers yet, that’s where the risk is.
Reach out to discuss your project. I typically respond within 24 hours.