Why init is a separate step
A reasonable question: if select gives a price and confirm creates the order, what is init for?
It exists because a price is not a contract. Between knowing the cost and committing to it, three things have to be settled: who is buying, how they will pay, and what happens if it goes wrong. Collapsing that into confirm means the driver agrees to terms they were never shown.
On an open network the parties have no bilateral contract covering each transaction. The terms returned in on_init are the disclosure that makes the subsequent confirm meaningful — and, when a dispute arises months later, the record of what was offered.
The request
The BAP sends the order back with billing and customer details attached:
POST https://cpo.electreefi.in/beckn/init
{
"context": {
"domain": "ev-charging:uei", "action": "init", "version": "1.1.0",
"bap_id": "emsp.example.com", "bap_uri": "https://emsp.example.com/beckn",
"bpp_id": "cpo.electreefi.in", "bpp_uri": "https://cpo.electreefi.in/beckn",
"transaction_id": "txn-4471", "message_id": "msg-9023",
"timestamp": "2026-08-11T09:00:26Z", "ttl": "PT30S"
},
"message": {
"order": {
"provider": { "id": "EFI" },
"items": [{ "id": "EVSE-014-02",
"quantity": { "selected": { "measure": { "value": "25", "unit": "kWh" } } } }],
"billing": {
"name": "Example Mobility Services",
"email": "billing@emsp.example.com",
"tax_id": "07AAACE1234F1Z5"
},
"fulfillments": [{
"id": "FUL-1",
"customer": {
"person": { "name": "Driver 88231" },
"contact": { "phone": "+919136075015" }
},
"stops": [{ "type": "START",
"time": { "timestamp": "2026-08-11T09:12:00Z" } }]
}]
}
}
}The response: terms made explicit
POST https://emsp.example.com/beckn/on_init
{
"context": { "...": "same transaction_id", "action": "on_init",
"message_id": "msg-9023" },
"message": {
"order": {
"provider": { "id": "EFI" },
"items": [{ "id": "EVSE-014-02" }],
"quote": {
"price": { "currency": "INR", "value": "535.93" },
"breakup": [
{ "title": "Energy (25 kWh @ 18.50)",
"price": { "currency": "INR", "value": "462.50" } },
{ "title": "Service fee", "price": { "currency": "INR", "value": "10.00" } },
{ "title": "GST (18%)", "price": { "currency": "INR", "value": "63.43" } }
]
},
"payments": [{
"id": "PAY-1",
"type": "PRE-FULFILLMENT",
"status": "NOT-PAID",
"collected_by": "BAP",
"params": { "amount": "535.93", "currency": "INR" }
}],
"cancellation_terms": [{
"fulfillment_state": { "descriptor": { "code": "RESERVED" } },
"cancellation_fee": { "percentage": "0" },
"external_ref": {
"mimetype": "text/html",
"url": "https://cpo.electreefi.in/terms/cancellation"
}
}]
}
}
}
Payment type is a commercial decision
type | Means | Fits |
|---|---|---|
PRE-FULFILLMENT | Pay before charging starts | Walk-up and prepaid customers; caps the BPP's credit risk |
ON-FULFILLMENT | Pay as the service is delivered | Rare in EV charging — the amount is not final until the end |
POST-FULFILLMENT | Pay after completion | Contracted eMSP customers, settled between companies |
collected_by decides who takes the money — BAP or BPP. For an eMSP with an existing billing relationship, BAP collection and POST-FULFILLMENT is the natural pairing: the driver pays their own provider on their normal cycle, and the two companies settle separately.
Because the true amount is only known at the end, PRE-FULFILLMENT in practice means authorising a maximum and settling down to the actual on completion. Design for that reconciliation up front — retrofitting a refund path is unpleasant.
Cancellation terms are a promise
cancellation_terms binds a fee to a fulfilment state. Free to cancel while merely reserved; chargeable once charging has begun; and so on. Two rules follow:
- Show them before confirm, not after. A cancellation fee first revealed at cancel time is the fastest route to a chargeback.
- Store what was returned, verbatim. The terms in force are the ones sent at init for this transaction, not whatever the BPP publishes today. Same discipline as embedding a tariff snapshot in an OCPI CDR.
Production lessons
- Persist the full
on_initpayload. It is the evidence of what was offered. Disputes are settled from it. - Compare the init quote against the select quote. They should match. A BPP that quietly re-prices between the two steps is a partner problem worth catching in certification.
- Never confirm without a successful init. Skipping it means agreeing to terms nobody read.
- Minimise personal data. Send a reference and a contact channel, not a customer profile.
- Handle missing
cancellation_termsconservatively. Absent terms are not the same as free cancellation — treat them as unknown and say so. - Respect
ttl. A lateon_initshould be discarded rather than presented as current.
Frequently asked questions
It attaches billing and customer details to the draft order and asks the BPP to state its terms — payment type, who collects, and cancellation terms. It is the disclosure step that makes the subsequent confirm meaningful, since on an open network the two parties have no bilateral contract covering each transaction.
init produces a fully specified draft order with terms attached but creates nothing; either side can still walk away. confirm commits it, creating a real order with an ID and a fulfilment state.
PRE-FULFILLMENT (pay before service), ON-FULFILLMENT (pay during) and POST-FULFILLMENT (pay after). For EV charging, POST-FULFILLMENT with collected_by set to BAP suits eMSPs with an existing billing relationship, since the final amount is only known once charging ends.
Because it records the terms that applied to this specific transaction. The cancellation terms and quote in force are the ones returned at init, not whatever the BPP publishes later. It is the evidence a dispute is settled from.