OCPP MESSAGE · UPDATED 11 AUG 2026

StopTransaction: closing the books on a charge

Every rupee invoiced for a charging session traces back to two numbers on two messages. This is the second one — and it is the closest thing to physical ground truth that a charging platform ever gets.

PART OF THE OCPP COMPLETE GUIDE · 14 MESSAGE GUIDES

IN ONE PARAGRAPH

StopTransaction reports the final meter reading, the time, and why the session ended. The difference between meterStop and meterStart is the energy actually delivered, which makes this the record every downstream invoice must reconcile against. The stop reason is the most under-used operational signal in the protocol.

The message

// Charge point -> CSMS
[2, "19223210", "StopTransaction", {
  "transactionId": 770142,
  "idTag": "DR88231ABCD",
  "meterStop": 4496370,
  "timestamp": "2026-08-11T10:03:41Z",
  "reason": "EVDisconnected",
  "transactionData": [{
    "timestamp": "2026-08-11T10:03:41Z",
    "sampledValue": [{
      "value": "4496370",
      "context": "Transaction.End",
      "measurand": "Energy.Active.Import.Register",
      "unit": "Wh"
    }]
  }]
}]

// CSMS -> charge point
[3, "19223210", { "idTagInfo": { "status": "Accepted" } }]

Energy delivered is 4496370 - 4471820 = 24550 Wh, or 24.55 kWh. That subtraction is the entire financial basis of the session.

idTag is optional and may differ from the one that started the session — a driver can start with a card and stop with an app credential, provided both share a parentIdTag.

The stop reason is diagnostic gold

reason is optional in the spec and routinely ignored in implementations. It is the single best signal you have about what is actually happening across a fleet.

ReasonMeansWhat a cluster of these tells you
EVDisconnectedDriver unpluggedNormal — the healthy majority
LocalStopped at the chargerNormal
RemoteStopped by RemoteStopTransactionNormal — app-initiated
DeAuthorizedAuthorisation withdrawnToken or roaming problem
EmergencyStopEmergency button pressedInvestigate the site immediately
PowerLossCharger lost powerSite electrical problem
Reboot / HardReset / SoftResetCharger restarted mid-sessionFirmware instability — a repeat pattern is a warranty case
UnlockCommandCable released remotelyUsually a stuck-cable incident
OtherUnspecifiedVendor-specific; investigate
Track the reason distribution per charger model and per site. A healthy estate is dominated by EVDisconnected and Local. A model showing 5% Reboot has a firmware defect; a site showing repeated PowerLoss has an electrical problem. Neither shows up in uptime metrics, and both are visible here for free.

transactionData and the offline case

transactionData carries meter samples the CSMS may not have received — typically the full set of readings taken while the charger was offline.

This is why an offline session still bills correctly. The charger stores samples locally and delivers them all in the stop message. Your ingestion must merge these with any MeterValues already received, de-duplicating on timestamp and measurand, rather than treating them as a second set of readings.

Doing that naively double-counts energy. The samples in transactionData frequently overlap with what already arrived.

Reconciliation: the honesty metric

This message is the point where an EV platform can check its own arithmetic. Three reconciliations are worth running continuously:

CheckCompareA mismatch means
Meter arithmeticmeterStop - meterStart vs the sum of MeterValues deltasLost or duplicated meter samples
OCPI CDR energyTransaction energy vs CDR total_energyYour CDR generation is wrong — a billing defect
Session closureEvery StartTransaction has a StopTransactionStuck sessions or lost messages

The second row is the one that matters commercially. A roaming partner's dispute is settled by whether your CDR matches your own StopTransaction. If it does not, you cannot defend the invoice — and the mismatch rate against StopTransaction is the number an audit will ask for.

Sessions that never stop

Some transactions never receive a StopTransaction:

  • The charger lost power mid-session and never recovered its queue.
  • Firmware crashed and lost local state.
  • The unit was decommissioned mid-transaction.
  • The message was sent and lost, and the charger did not retry.

You cannot leave these open forever — they inflate the “currently charging” count and block the connector in your availability model. Age them out on a defined policy: close using the last received meter sample, mark the record as estimated, and exclude it from partner settlement rather than invoicing a number you cannot evidence.

Never silently invoice an estimated close. If you cannot evidence the energy, you cannot defend the charge.

Production lessons

  • Reconcile every CDR against its StopTransaction. The mismatch rate is your platform's honesty metric.
  • De-duplicate transactionData against received MeterValues before summing anything.
  • Record and dashboard the stop reason. It is free fleet diagnostics that most platforms discard.
  • Age out unclosed transactions with an explicit policy, flagged as estimated.
  • Handle zero-energy stopsDeAuthorized seconds after start must not generate an invoice.
  • Keep the raw payload. When a partner disputes energy, the original StopTransaction ends the discussion.
  • Accept late stops without complaint. An offline charger delivering yesterday's transaction is working correctly.

Frequently asked questions

How is energy calculated in OCPP?

By subtracting meterStart on StartTransaction from meterStop on StopTransaction. Both are cumulative register readings in watt-hours, so the difference is the energy delivered during that session.

What is transactionData in OCPP StopTransaction?

Meter samples the CSMS may not have received, typically readings taken while the charger was offline. They must be merged with any MeterValues already received and de-duplicated on timestamp and measurand, otherwise energy is double-counted.

Why does the OCPP stop reason matter?

It is the best fleet-diagnostic signal in the protocol and is usually discarded. A healthy estate is dominated by EVDisconnected and Local. A charger model showing frequent Reboot has a firmware defect, and a site showing repeated PowerLoss has an electrical problem — neither appears in uptime metrics.

What should you do with a transaction that never receives a StopTransaction?

Age it out on a defined policy: close it using the last received meter sample, mark the record as estimated, and exclude it from partner settlement. Never silently invoice an estimated close, because you cannot evidence the energy.

Can a session be stopped with a different card than it was started with?

Yes, provided both credentials share a parentIdTag. This is what lets a driver start with an RFID card and stop from a mobile app.