Tariff and Cost Section — Migration Guide
This document covers all differences in the Tariff and Cost functional block between OCPP 2.0.1 (Edition 4) and OCPP 2.1 (Edition 2).
Created by tzi.app — your guide to migrating from OCPP 2.0.1 to OCPP 2.1.
1. Summary of Changes
OCPP 2.1 introduces Local Cost Calculation as a second cost calculation model alongside the existing Central Cost Calculation. This
is the single largest change in Section I and brings 6 new use case flows (I07–I12), 5
new message pairs, a rich structured tariff data model
(TariffType),
and a new payment settlement flow
(NotifySettlement).
Change Overview at a Glance
| Area | 2.0.1 | 2.1 | Impact |
|---|---|---|---|
| Cost calculation models | Central only | Central + Local | Major — new architecture option |
| Use case flows | I01–I06 | I01–I12 + NotifySettlement | 6 new flows + 1 new payment flow |
| Messages | 4 message pairs | 9 message pairs | 5 new message pairs |
| Tariff data model | None (text-only) | TariffType structured object | Major — new data structures |
| Configuration variables | 3 | 10+ | 7+ new variables |
| MessageContentType.content max length | 512 chars | 1024 chars | Field size increase |
| MessageFormatEnumType values | ASCII, HTML, URI, UTF8 | + QRCODE | New enum value |
| IdTokenType.idToken max length | 36 chars | 255 chars | Field size increase |
2. New Cost Calculation Model: Local Cost Calculation
In 2.0.1, the CSMS always calculates costs centrally and sends results to the Charging Station. In 2.1, the Charging Station can calculate costs locally using structured tariff data provided by the CSMS.
| Aspect | Central Cost Calculation (2.0.1 & 2.1) | Local Cost Calculation (2.1 only) |
|---|---|---|
| Who calculates cost | CSMS | Charging Station |
| Tariff delivery format | Human-readable text (personalMessage) | Structured TariffType object |
| Running cost updates | CSMS sends CostUpdatedRequest or totalCost in TransactionEventResponse | CS sends costDetails in TransactionEventRequest |
| Final cost | CSMS returns totalCost in TransactionEventResponse | CS sends costDetails in TransactionEventRequest (eventType=Ended) |
CSMS Impact
- The CSMS must be able to build and send
TariffTypestructures if local cost calculation is used. - The CSMS must be able to receive and process
costDetailsfrom the Charging Station for invoicing/CDR generation. - The
HandleFailedTariffconfiguration variable determines fallback behavior when a CS cannot process a tariff.
3. New Use Case Flows (I07–I12 + NotifySettlement)
These flows are entirely new in OCPP 2.1 and do not exist in 2.0.1.
| Flow | Name | Direction | Purpose |
|---|---|---|---|
| I07 | Set Default Tariff | CSMS → CS | Install a default tariff on the CS for local cost calculation |
| I08 | Receive Driver Tariff | CSMS → CS | Provide a driver-specific tariff for local cost calculation (in AuthorizeResponse) |
| I09 | Get Tariffs | CSMS → CS | Query installed tariffs on the CS |
| I10 | Clear Tariffs | CSMS → CS | Remove default tariffs from the CS |
| I11 | Change Transaction Tariff | CSMS → CS | Change the tariff of an ongoing transaction |
| I12 | Cost Details of Transaction | CS → CSMS | Receive detailed cost breakdown from the CS |
| Notify | Payment Settlement | CS → CSMS | Receive payment settlement information from a payment terminal |
4. New Messages
4.1 New Message Pairs
| Message | Direction | Related Flow |
|---|---|---|
SetDefaultTariffRequest / SetDefaultTariffResponse | CSMS → CS | I07 |
GetTariffsRequest / GetTariffsResponse | CSMS → CS | I09 |
ClearTariffsRequest / ClearTariffsResponse | CSMS → CS | I10 |
ChangeTransactionTariffRequest / ChangeTransactionTariffResponse | CSMS → CS | I11 |
NotifySettlementRequest / NotifySettlementResponse | CS → CSMS | Settlement |
4.2 SetDefaultTariffRequest (New)
Installs a default tariff on the CS. Supports per-EVSE or global (evseId=0) installation.
{
"evseId": 0, // 0 = all EVSEs, >0 = specific EVSE
"tariff": { /* TariffType */ }
}Response statuses: Accepted, Rejected, TooManyElements, ConditionNotSupported, DuplicateTariffId
4.3 GetTariffsRequest (New)
Queries installed tariffs and their EVSE/driver assignments.
{ "evseId": 0 } // 0 = all EVSEsResponse statuses: Accepted, Rejected, NoTariff
4.4 ClearTariffsRequest (New)
Removes default tariffs. Can target specific tariff IDs and/or specific EVSEs.
{
"tariffIds": ["Default01"], // Optional. Omit to clear all.
"evseId": 1 // Optional. Omit to clear from all EVSEs.
}Response statuses per tariff: Accepted, Rejected, NoTariff
4.5 ChangeTransactionTariffRequest (New)
Changes the tariff for an active transaction. The currency must match the current tariff.
{
"transactionId": "1234",
"tariff": { /* TariffType */ }
}Response statuses: Accepted, Rejected, TooManyElements, ConditionNotSupported, TxNotFound, NoCurrencyChange
4.6 NotifySettlementRequest (New)
Sent by the CS when a payment terminal completes a settlement.
{
"pspRef": "PSP-123456", // Payment reference
"status": "Settled", // Settled | Canceled | Rejected | Failed
"settlementAmount": 15.75,
"settlementTime": "2024-01-15T15:00:00Z",
"transactionId": "tx-123", // Optional
"receiptId": "REC-001", // Optional
"receiptUrl": "https://...", // Optional
"vatCompany": { /* AddressType */ },// Optional
"vatNumber": "NL123456789B01" // Optional
}Response (optional fields): receiptUrl, receiptId
5. New Data Structures
5.1 TariffType (Core Structured Tariff)
This is the central new data structure. It replaces text-only tariff communication with a machine-readable format for local cost calculation.
{
"tariffId": "string", // REQUIRED. Max 60 chars. Unique identifier.
"currency": "string", // REQUIRED. ISO 4217 (e.g. "EUR")
"validFrom": "date-time", // Optional. UTC. When absent, immediately active.
"description": [/* MessageContentType[] */], // Optional. Human-readable, max 10 items.
"energy": { /* TariffEnergyType */ },
"chargingTime": { /* TariffTimeType */ },
"idleTime": { /* TariffTimeType */ },
"fixedFee": { /* TariffFixedType */ },
"reservationTime": { /* TariffTimeType */ },
"reservationFixed": { /* TariffFixedType */ },
"minCost": { /* PriceType */ },
"maxCost": { /* PriceType */ }
}Key rule: tariffId uniquely identifies a tariff. Updated tariffs must use a new tariffId.
5.2 TariffConditionsType (New)
Allows conditional pricing based on time-of-day, day-of-week, power levels, energy consumed, etc. All fields are optional; multiple conditions combine with logical AND. Only the first matching price element in a list is used.
Key condition fields:
startTimeOfDayendTimeOfDaydayOfWeekvalidFromDatevalidToDateevseKindminEnergymaxEnergyminCurrentmaxCurrentminPowermaxPowerminTimemaxTimeminChargingTimemaxChargingTimeminIdleTimemaxIdleTime5.3 TaxRateType (New)
Supports multi-level stacked taxes (e.g., federal + state).
{ "type": "vat", "tax": 10.0, "stack": 0 }Tax application order: stack=0 taxes on net price → stack=1 taxes on
result → stack=2, etc.
5.4 CostDetailsType (New)
Detailed cost breakdown sent by the CS in TransactionEventRequest. Includes:
- totalCost — Breakdown by category (fixed, energy, chargingTime, idleTime, reservationTime, reservationFixed) with tax details
- totalUsage — Consumption metrics (Wh, seconds)
- chargingPeriods — Time-segmented cost records (present in final Ended message only)
- failureToCalculate / failureReason — Error handling fields
5.5 TransactionLimitType (New)
Allows the CSMS to set limits on a transaction via TransactionEventResponse:
{ "maxCost": 50.00, "maxEnergy": 30000, "maxTime": 7200, "maxSoC": 80 }6. Changes to Existing Flows
Show EV Driver-Specific Tariff Information
| Aspect | 2.0.1 | 2.1 | Change Type |
|---|---|---|---|
personalMessage.content max length | 512 chars | 1024 chars | Increased |
personalMessage.format options | ASCII, HTML, URI, UTF8 | + QRCODE | New value |
AuthorizeResponse.tariff field | Not present | New optional TariffType field | Added |
idToken.idToken max length | 36 chars | 255 chars | Increased |
CSMS action: If using local cost calculation, the CSMS can
now also include a structured tariff field in the AuthorizeResponse (this is Flow I08, delivered via the same message as I01).
Show EV Driver Running Total Cost During Charging
| Aspect | 2.0.1 | 2.1 | Change Type |
|---|---|---|---|
Central cost calc via CostUpdatedRequest | Supported | Supported (unchanged) | No change |
Central cost calc via TransactionEventResponse.totalCost | Supported | Supported | No change |
Local cost calc via costDetails in TransactionEventRequest | Not available | New (I12) | Added |
CSMS action: No breaking changes for central cost
calculation. If switching to local cost calculation, cost updates now come from the CS in TransactionEventRequest instead of being sent to the CS.
Show EV Driver Final Total Cost After Charging
| Aspect | 2.0.1 | 2.1 | Change Type |
|---|---|---|---|
TransactionEventResponse.totalCost | Supported | Supported (unchanged) | No change |
TransactionEventRequest.costDetails | Not available | New — CS can send full cost breakdown | Added |
TransactionEventRequest.transactionInfo.tariffId | Not available | New — identifies which tariff was used | Added |
CSMS action: When using local cost calculation, the CSMS
receives costDetails in the TransactionEventRequest (eventType=Ended) and should use it for invoice/CDR generation. The totalCost field in TransactionEventResponse still applies for central cost calculation.
Fallback Tariff Information & Fallback Total Cost Message
No breaking changes. Behavior is the same in both versions.
Update Tariff Information During Transaction
| Aspect | 2.0.1 | 2.1 | Change Type |
|---|---|---|---|
updatedPersonalMessage in TransactionEventResponse | Supported | Supported (unchanged) | No change |
updatedPersonalMessageExtra in TransactionEventResponse | Not available | New — array of MessageContentType for additional languages (max 4) | Added |
| Structured tariff change during transaction | Not available | New — ChangeTransactionTariffRequest (I11) | Added |
CSMS action: The updatedPersonalMessageExtra field allows sending updated tariff text in multiple languages
simultaneously. Previously, only one language was possible per response. For
local cost calculation, use ChangeTransactionTariffRequest (I11) instead of text-based updates.
7. Changes to Existing Data Types
7.1 MessageContentType
| Field | 2.0.1 | 2.1 | Change |
|---|---|---|---|
content max length | 512 chars | 1024 chars | Doubled |
format enum values | ASCII, HTML, URI, UTF8 | ASCII, HTML, URI, UTF8, QRCODE | New value |
7.2 IdTokenType
| Field | 2.0.1 | 2.1 | Change |
|---|---|---|---|
idToken max length | 36 chars | 255 chars | Increased |
type enum values | Central, eMAID, ISO14443, ISO15693, KeyCode, Local, MacAddress, NoAuthorization | Same + max 20 chars string | No change to core values |
7.3 TransactionEventRequest
| Field | 2.0.1 | 2.1 | Change |
|---|---|---|---|
costDetails | Not present | New optional CostDetailsType | Added |
transactionInfo.tariffId | Not present | New optional string (max 60 chars) | Added |
7.4 TransactionEventResponse
| Field | 2.0.1 | 2.1 | Change |
|---|---|---|---|
updatedPersonalMessageExtra | Not present | New optional MessageContentType[] (max 4) | Added |
transactionLimit | Not present | New optional TransactionLimitType | Added |
7.5 AuthorizeResponse
| Field | 2.0.1 | 2.1 | Change |
|---|---|---|---|
tariff | Not present | New optional TariffType | Added (for local cost calc) |
7.6 New triggerReason Values for TransactionEventRequest
| Value | 2.0.1 | 2.1 | Description |
|---|---|---|---|
| RunningCost | No | Yes | CS sending a running cost update (local calc) |
| TariffChanged | No | Yes | Tariff was changed via ChangeTransactionTariffRequest |
| TariffNotAccepted | No | Yes | EV Driver rejected the offered tariff |
| CostLimitReached | No | Yes | Transaction cost limit reached |
8. New Configuration Variables
| Variable | Component | Description |
|---|---|---|
Enabled[Tariff] | TariffCostCtrlr | Enable/disable local cost calculation on CS |
Interval[Tariff] | TariffCostCtrlr | Frequency (seconds) for monitoring current/power/energy variations for tariff calculation |
MaxElements[Tariff] | TariffCostCtrlr | Maximum supported complexity (number of elements) of a tariff |
Enabled[Cost] | TariffCostCtrlr | Enable/disable sending intermediate running cost updates |
Interval[Cost] | TariffCostCtrlr | Frequency (seconds) for sending running cost updates |
ConditionsSupported | TariffCostCtrlr | Whether CS supports TariffConditionsType (true/false) |
HandleFailedTariff | TariffCostCtrlr | Behavior when tariff processing fails: Deauthorize, UseDefault, or CentralCost |
Existing variables unchanged: Currency, TariffFallbackMessage, TotalCostFallbackMessage
9. Migration Checklist
Mandatory (to comply with 2.1 schema changes)
- Update MessageContentType.content max validation from 512 → 1024 chars
- Support QRCODE in MessageFormatEnumType validation
- Update IdTokenType.idToken max validation from 36 → 255 chars
- Handle new optional costDetails field in incoming TransactionEventRequest
- Handle new optional transactionInfo.tariffId field in incoming TransactionEventRequest
- Support new triggerReason values: RunningCost, TariffChanged, TariffNotAccepted, CostLimitReached
- Support new optional tariff field in outgoing AuthorizeResponse
- Support new optional updatedPersonalMessageExtra field in outgoing TransactionEventResponse
- Support new optional transactionLimit field in outgoing TransactionEventResponse
Required for Local Cost Calculation support
- Implement TariffType data model and all sub-types
- Implement SetDefaultTariffRequest sending + response handling (I07)
- Implement AuthorizeResponse.tariff delivery for driver-specific tariffs (I08)
- Implement GetTariffsRequest sending + response handling (I09)
- Implement ClearTariffsRequest sending + response handling (I10)
- Implement ChangeTransactionTariffRequest sending + response handling (I11)
- Implement CostDetailsType parsing from TransactionEventRequest for invoicing/CDR (I12)
- Handle HandleFailedTariff configuration and its three modes
- Configure new TariffCostCtrlr variables on Charging Stations
Required for Payment Settlement support
- Implement NotifySettlementRequest handler
- Build NotifySettlementResponse with optional receipt URL/ID
- Handle all settlement statuses: Settled, Canceled, Rejected, Failed
No Changes Required
- I04 (Fallback Tariff Information) — unchanged
- I05 (Fallback Total Cost Message) — unchanged
- CostUpdatedRequest/Response — unchanged
- Currency, TariffFallbackMessage, TotalCostFallbackMessage configuration variables — unchanged