API cutover: charger management and billing support
Agreed boundary, September 23: the shared API provides charger management and billing support. Ivora Host, driver checkout, the operator console and future applications consume that contract for those capabilities. Each application owns its product workflows and user experience.
This is the target cutover boundary. The compatibility routes described below are still running; this decision does not claim their migration is complete.
Ownership
| Layer | Responsibility |
|---|---|
| Charger management API | Tenant inventory, locations, stations/EVSEs/connectors, connection credentials, state, charger commands, operation results and charger display desired state |
| Billing support API | Trusted charging usage, tariff versions and snapshots, cost calculation, immutable bills, session/payment references and settlement status |
| Payment adapters | Optional processor authorization, capture, release, refund and provider reconciliation through the payment contract |
| Consuming application and its database | Host/guest accounts and access rules, bookings, free-charging eligibility/passwords, onboarding progress, business profiles, QR cards, branding, checkout UI and settlement timing |
| CSMS engine | OCPP connections, protocol handling, device state, charging transactions and metering |
Tenant assignment, scoped credentials, authorization, idempotency, audit and developer/agent documentation support both API areas. The API enforces tenant and resource boundaries; an application's backend enforces each host or guest's rights within its fleet. Fleet-wide keys must stay on that backend.
Billing support means charging usage and financial records. Booking charges, subscriptions, commissions and payout policy remain application concerns. Processor-specific execution stays in its adapter or the application's payment integration. Applications may use the managed Stripe adapter or their own processor with external sessions; a browser redirect or an external settlement report is not independent proof of payment.
The following diagram shows the target ownership boundary, not a declaration that every first-party client has completed migration.
Diagram source
flowchart TB
Apps[Host, driver, console and other applications] --> App[Application workflows and user authorization]
App --> Chargers[Charger management API]
App --> Billing[Billing support API]
Chargers --> Core[CSMS protocol engine and meters]
Core -->|Trusted usage| Billing
Billing --> Managed[Optional payment adapter]
App --> External[Application-owned processor]
External -->|Backend reports outcomes| BillingA new booking or QR feature should change the application. Add a shared API capability when it provides reusable charger management or billing behavior. Change CSMS core when protocol/device support requires it. This keeps new products from repeatedly changing charging infrastructure.
Charger displays follow this rule. Keeping a QR on a charger's own screen, across reboots and vendor dialects, is reusable charger behavior, so the API owns that desired state. The URL, printed card and destination page stay with the application.
Existing contracts and cutover gaps
Source review on September 23 found the following implemented preproduction contracts. The API reference remains authoritative for schemas.
| Area | Available contract | Remaining cutover work |
|---|---|---|
| Access | Automatic tenant assignment, /v1/access and tenant-bound keys | Preserve application-user checks when migrating callers |
| Inventory | Tenant locations, stations, station location update and offline credential setup | Host retirement/linking and remaining console workflows still depend on compatibility interfaces; identify and implement their reusable resource operations |
| Charger operation | Tenant station commands, transactions and operation polling | Migrate remaining direct console/core calls; verify physical charging and failure cases |
| Charger displays | Per-EVSE display desired state with Ivora-managed adapters (deployed to preproduction 2026-09-28) | Deploy; accept on physical Renova, Sinexcel and single-EVSE OCPP 2.0.1/2.1 chargers without a vendor adapter (QR image load, QR and price text cycling, clear and re-show around a session); turn off the legacy payment service's display writes per environment |
| Billing | Tenant tariffs, bills, bill start and finalization | Core tariffs do not publish to the separate legacy checkout catalog; reconcile catalog mapping and legacy billing versions before switching existing sessions |
| Payments | /payment/{service}/v1/tenants/{tenant_id}/payments, the tenant payment account and external charging-sessions with optional settlement reports | Signed settlement callbacks and self-service adapter registration remain incomplete; external reports remain application assertions |
| Application experience | Host owns its charger registry, QR generation, business profiles, complimentary eligibility, driver presentation and paid checkout orchestration; its backend uses only the shared API | Move each tenant's stations from the legacy driver checkout to Host (paid sessions are direct charges on the tenant's payment account); retire the legacy driver reads once issued sessions expire |
The /v1/host inventory routes were retired on 2026-09-25 (Ivora Host now
consumes the tenant contract). Preproduction still serves /v1/driver reads and
legacy payment flows with compatibility behavior for existing Ivora experiences;
production serves neither. Their presence on the preproduction API hostname does
not make all of their behavior part of the long-term shared contract. Stripe
account setup is part of the shared contract in both environments as the tenant
payment account. Classify each operation:
- Move reusable inventory, charging and billing behavior into tenant resources.
- Keep Host setup completion, business profiles, public catalog presentation, free-access policy and driver UI/session orchestration in the application.
- Keep reusable merchant/provider operations in the payment adapter; Host owns the onboarding experience and its application return flow.
Retain compatibility until consumers migrate and issued sessions can still be read, stopped and settled on their original ledger. Do not create a second bill or settlement for an existing session. Host QR image rendering, business-profile routes and free-charge policy/checkout routes have been removed from the unified API; charger display state is a separate charger capability. Legacy product columns remain for rollback, but preproduction Host profile and policy reads/writes use its own application database. This does not mean every Host workflow has moved.
Acceptance for the cutover
- Inventory the charger-management and billing actions used by each first-party application. Map each to a documented reusable API contract and resolve the missing resource operations before changing its caller.
- Route those actions through the same tenant contract available to another application. Their consumers must no longer depend on core SQL/Hasura, raw OCPP or private legacy billing interfaces. Adapters may retain such internals.
- Demonstrate tenant denial, application-user denial and safe retries, plus an authorized test flow from provisioning through start, usage, stop and billing. A 202 dispatch response alone does not establish charging success.
- Verify settlement through the selected managed or external path, including failed/unknown outcomes, duplicate requests and recovery. Preserve meter units, immutable amounts, settlement ownership and financial history.
- Keep app-specific workflows in the application and maintain compatibility for existing sessions. Record which callers/routes remain before declaring the cutover complete.
Physical end-to-end acceptance and complete Host/console migration remain open. API operation/billing/key storage is currently single-worker SQLite; PostgreSQL repositories and durable reconciliation are needed before multiple replicas. Ivora's own applications adopt this contract in preproduction first; production cutover follows one tenant at a time.