मुख्य सामग्रीमा जानुहोस्
Sajilo Charge

← सबै SDK हरू

Connect your chargers with Laravel

A composer package with auto-discovery — one artisan command scaffolds everything, you edit one file.
Works with Laravel 10 / 11 / 12 · PHP ≥ 8.1

sajilocharge-ocpi-laravel.zip v0.1.0 · Laravel 10 / 11 / 12 · PHP ≥ 8.1 · OCPI 2.2.1

⬇ Download SDK
AI एजेन्टसँग बनाउँदै? Point it at https://sajilocharge.com/developers/ocpi/ai/ — this whole tutorial in machine-readable form.

How a roaming charge flows

Sajilo Charge driver       Sajilo Charge hub                 Your Laravel backend
      │ taps "Start" ────▶ POST /commands/START_SESSION ──▶ onStartSession(charge)
      │                                                      your CSMS starts the charger
      │   charging…   ◀── PUT  sessions push ◀───────────── setActive() / meter(kwh)
      │ taps "Stop"  ────▶ POST /commands/STOP_SESSION ───▶ onStopSession(charge)
      │ wallet debited ◀── POST cdrs ◀──────────────────────  complete(kwh, cost)
      │                    monthly netting ─────────────────▶ you get paid

1.Install the SDK

One download, one package-manager command.

composer config repositories.sajilocharge '{"type": "artifact", "url": "./vendor-zips"}'
mkdir -p vendor-zips
curl -Lo vendor-zips/sajilocharge-ocpi-laravel.zip \
  https://sajilocharge.com/static/downloads/sajilocharge-ocpi-laravel.zip
composer require sajilocharge/ocpi-laravel

2.Configure and mount

Tell the SDK who you are and where your server is publicly reachable. This mounts the three /ocpi endpoints the hub calls on you — everything else is outbound from your side.

php artisan sajilocharge:install   # config + migrations + handlers stub

# .env
SAJILOCHARGE_PARTY_ID=ABC            # your 3-char party id
SAJILOCHARGE_COUNTRY_CODE=NP
SAJILOCHARGE_NAME="ABC Charging Pvt. Ltd."
SAJILOCHARGE_BASE_URL=https://csms.example.com
SAJILOCHARGE_HANDLERS=App\Ocpi\OcpiHandlers

3.Wire your two charger callbacks

Every remote-start request becomes a RoamingCharge handed to your code. You implement exactly two methods; keep them fast and do the charger work asynchronously.

// app/Ocpi/OcpiHandlers.php — generated for you; fill two TODOs
public function onStartSession(RoamingCharge $charge): bool
{
    // $charge->location_id / $charge->evse_uid say which charger
    MyCsms::remoteStart($charge->evse_uid, ref: $charge->id);
    return true;   // accepted; queue the real work
}

public function onStopSession(RoamingCharge $charge): bool
{
    MyCsms::remoteStop(ref: $charge->id);
    return true;
}

4.Drive the charge lifecycle

From your CSMS events, three calls push the matching OCPI Session objects — and the final CDR that bills the driver — to the hub. The CDR is idempotent: it goes out exactly once per charge.

$charge = RoamingCharge::find($ref);
$charge->setActive();                  // energy started flowing
$charge->meter(4.2);                   // periodic session kWh
$charge->complete(18.5, 462.50);       // NPR; issues the CDR
The CDR is the bill. The complete call is idempotent and sends exactly one CDR per charge — that CDR debits the driver's wallet and credits your settlement ledger. Send it as soon as the session ends.

5.Join the network

Request a one-shot registration token from partners@sajilocharge.com. Deploy first — the hub calls your /ocpi endpoints back during the handshake — then run the join. Tokens rotate on every re-registration; the registration token dies on first use.

php artisan sajilocharge:join --token=<registration-token>
php artisan sajilocharge:status      # → Status: ACTIVE

6.Publish your stations

Locations upsert by id — re-push whenever anything changes, keep live EVSE status fresh, and (optionally) verify drivers in real time for RFID or local starts.

use SajiloCharge\Ocpi\Facades\SajiloCharge;

SajiloCharge::pushLocation([
    'id' => 'LOC-KTM-01',
    'name' => 'ABC Hub Thamel',
    'address' => 'Thamel Marg 12',
    'city' => 'Kathmandu',
    'coordinates' => ['latitude' => '27.7154', 'longitude' => '85.3123'],
    'publish' => true,
    'evses' => [['uid' => 'EVSE-01', 'status' => 'AVAILABLE',
                 'connectors' => [['id' => '1', 'standard' => 'IEC_62196_T2',
                                   'format' => 'SOCKET', 'power_type' => 'AC_3_PHASE']]]],
]);

// live availability + optional driver check
SajiloCharge::updateEvse('LOC-KTM-01', 'EVSE-01', ['status' => 'CHARGING']);
SajiloCharge::authorize($tokenUid);  // ALLOWED | NO_CREDIT | BLOCKED

Money and settlement

  • All amounts are NPR; costs are VAT-exclusive.
  • Each CDR credits your inter-party ledger at the hub; settlement is monthly netting minus the hub clearing fee.
  • Disputes: the hub's CDR dispute endpoint or partners@sajilocharge.com — open disputes pause netting for that CDR.

Troubleshooting

  • Join fails with "could not fetch endpoints" — your base URL isn't publicly reachable, or the OCPI routes aren't mounted. The hub must be able to call you back during the handshake.
  • 401 on hub calls — the connection was re-registered somewhere else; join again with a fresh registration token.
  • Session push returns "No matching session" — push only charges the hub initiated, after START_SESSION was accepted.
  • Rate limits — the hub throttles per-party (default 300 req/min); meter updates every 30–60 s are plenty.

Other stacks

Django (Django ≥ 4.2 · Python ≥ 3.10) · Node.js (Node ≥ 18 · Express ≥ 4) · Spring Boot (Spring Boot 3.2+ · Java 17+)

Sajilo Charge Laravel SDK v0.1.0 · OCPI 2.2.1 · Questions: partners@sajilocharge.com