← Insights

Engineering

An EV charger is the hardest point of sale you will ever run

Bolt EV · 27 May 2026 · 6 min read

A supermarket checkout has a safety net you never think about: a human. When the card reader hangs, the cashier voids and re-rings. When the receipt printer jams, they hand you a written slip. When the network drops, they take an imprint and reconcile later. Every failure path in a manned point of sale terminates at a person who can improvise.

Now take that person away. Put the terminal on a pole, at the edge of a car park, in the rain, on a connection that comes and goes with the weather, and let it run unattended at three in the morning with nobody within a kilometre. That is an EV charger — and under AFIR, the higher-power ones must take an ad-hoc card or contactless payment from any driver who pulls in. It is the most hostile point of sale you will ever run, and almost nothing about it is a charging problem. It is a distributed-systems problem that happens to dispense electrons.

The cashier was the error handler

Retail payments software is quietly built on one assumption: a human is the exception handler of last resort. The code covers the cases worth automating; everything else falls through to the operator standing at the till. The assumption runs so deep that most engineers never name it.

At an unattended charger, that fallthrough leads nowhere. No one notices that the pre-authorization succeeded but the start command timed out. No one spots that the session is charging while the terminal thinks it never began. No one re-prints the receipt, re-runs the capture, or apologises. Every transaction has to converge to one consistent final state on its own — because the only other outcome is a driver standing in the cold at a frozen screen, or, worse, a hold sitting on their card for a charge that never happened.

So the bar moves. A manned POS can be almost-right and let humans mop up the rest. An unattended charger has to be correct in the protocol, because the mop is gone.

One charge, four systems, zero supervision

Here is what actually has to agree by the end of a single charge:

  • The terminal holds an amount on the driver’s card.
  • The charger delivers energy and reports it to its CSMS over OCPP.
  • The payment side rides OCPI — where the pre-authorization, the start/stop, and the final settled figure live.
  • The acquirer eventually settles that figure, and the fiscalization round trip produces a receipt the tax authority will accept.

Four independent systems, four independent clocks, four independent ways to fail — and they must end up telling the same story about one car that plugged in for twenty minutes.

They will not naturally agree. The charger’s meter says, say, 31.2 kWh. The CDR that arrives ninety seconds later says 30.9. The acquirer captured against a hold placed before either number existed. The fiscal signature has to be requested, returned, and stamped onto a receipt while the driver is already pulling out of the bay. Any one of these can arrive late, arrive twice, or never arrive at all.

The work is not “talk to a card reader.” The work is reconciling four sources of truth into one final state, unattended, every time, forever — and doing it across any terminal, any acquirer, any CSMS, because the operator picked those independently and will swap them later.

The non-happy paths are the actual product

The happy path is trivial: hold, charge, capture the same amount, print receipt. You could write it in an afternoon. It is also the path that almost never breaks. The entire engineering weight of an unattended charger sits in the paths nobody demos:

  • The driver yanks the cable at minute three of a planned twenty. The session has to stop, the delivered energy has to be captured, and the unused portion of the hold has to be released — not silently abandoned to expire days later on the driver’s statement.
  • The terminal loses connectivity after placing the hold but before it hears that the start command landed. On reconnect, it must discover whether a session is live rather than blindly retrying and double-charging.
  • The capture succeeds at the acquirer but the response is lost in transit. The engine has to ask “did this already happen?” instead of trying again.
  • The fiscalization call fails after the money has moved, leaving a settled charge with no legal receipt — a state that has to be detected and resolved, not logged and forgotten.

None of these are exotic. On a fleet of unattended terminals running around the clock, they are Tuesday. They are also exactly the cases a human cashier absorbs without anyone writing a line of code — which is why teams that port retail payments thinking to a charger get blindsided. The non-happy paths were always handled by a person, and out here, there is no person.

Idempotency is the floor, not a nice-to-have

The discipline that makes this survivable is the same one that makes any unattended distributed system survivable, and it is unglamorous: idempotency, retries with dedup, and crash recovery.

  • Idempotency means the same capture — replayed after a lost response, a process restart, or a flaky link that re-sent the message — moves the money once, not twice on a driver who already drove off.
  • Retries mean a transient failure does not strand a driver; the engine keeps working toward the agreed final state.
  • Dedup means a charger or CSMS that re-sends a CDR, or a terminal that re-announces a transaction after reconnecting, does not get billed twice.
  • Recovery means that when a process dies mid-charge — and over years of 24/7 operation it will — it comes back, reads the durable record of what was in flight, and drives each unfinished transaction to its single correct conclusion.

The charger is not where the hard work lives. The state machine behind it is the part that has to stay correct as everything around it moves.

This is ordinary in payments infrastructure and entirely absent from a bespoke POS welded to one charger model. A one-off integration handles the demo. It does not handle the night the link flaps for an hour across a hundred poles, the firmware update that changes message timing, or the acquirer that quietly tightens an API.

Why this is built once, not per operator

OCPI gives you the connection — a Terminal object, a pre-authorization tied to a tariff, start/stop, a Financial Advice Confirmation carrying the settled amount. It does not give you the convergence. It says nothing about how you reconcile a hold against a CDR against a capture, what you do when finalization fails, how you release an unused authorization, or how you stay correct when versions move underneath you. That is the engine — and the engine is what every operator otherwise rebuilds alone.

The economics make rebuilding it the wrong call twice over. The reliability bar is highest exactly where the stakes are: a DC fast charger can cost an order of magnitude more than an AC unit, its sessions are fast and high-value, and a stuck transaction there is no rounding error. Meanwhile the operator wants to keep their own acquirer and card-present economics — the money never routes through the middleware, the operator stays the merchant — so the convergence logic cannot be welded to a payment processor either. It has to be neutral middleware: bridging payments over OCPI to any charger and CSMS, running the full state machine including the fiscal round trip per country, and letting the operator swap terminal, acquirer, or country without rewriting the part that keeps every transaction correct.

An EV charger looks like a charging product with a card slot. The slot is the easy part. Making one charge converge to one final state — unattended, in the rain, at three in the morning, with nobody home — is the whole job. Build it once for the market, or rediscover every non-happy path the hard way, one stranded driver at a time.

Run this on your network.

Bolt is the payments layer for EV charging — any terminal, any acquirer, any CSMS, and your bank stays yours.