EV Цэнэглэгч — B2B Integration

REST API болон Webhook интеграцийн нэгдсэн гарын авлага

REST API v1 Webhook
🌐
Ерөнхий тохиргоо
Base URL
https://api.yourdomain.com
Content-Type
application/json
Протокол
REST over HTTPS — TLS 1.2+
🔐
Keycloak M2M токен (Client Credentials flow) ашигладаг. Токен дотроос org_id claim-ийг автоматаар уншиж, бүх хандалтыг тухайн байгууллагын өгөгдлөөр хязгаарладаг.
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
📌
REST API — /b2b/v1
Станц / Байршил
GET /b2b/v1/stations Байгууллагын бүх станцуудыг жагсаах
Токен дахь org_id-д харгалзах бүх цэнэглэх байршлуудыг буцаана. Дотооддоо хуудаслалт (page 1, limit 1000) ашиглах тул нэг дуудалтаар бүх станцыг авна.
Response
Алдаа
200 OK
[
  {
    "station_id":  "550e8400-e29b-41d4-a716-446655440000",
    "branch_no":   "B001",
    "name":        "ХУД Салбар",
    "address":     "Яармаг, Хан-Уул дүүрэг",
    "lat":         47.8864,
    "lng":         106.8236,
    "image":       "https://cdn.example.com/stations/hub.jpg",
    "created_at":  "2024-01-15T08:00:00Z"
  }
]
Статус Тайлбар
400 Токен дахь org_id UUID формат буруу
500 Станцын мэдээлэл татахад алдаа гарсан
GET /b2b/v1/stations/:station_id Станцын дэлгэрэнгүй мэдээлэл
UUID-аар тодорхой нэг станцын дэлгэрэнгүй мэдээлэл авна. Байгууллагын хамрах хүрээнд байгаа эсэхийг (FindByIDAndOrgID) автоматаар шалгана.
Path Params
Response
Алдаа
Параметр Төрөл Тайлбар
station_idrequired uuid Станцын UUID танигч
200 OK
{
  "station_id":    "550e8400-e29b-41d4-a716-446655440000",
  "branch_no":     "B001",
  "name":          "ХУД Салбар",
  "district_code": "HUD",
  "address":       "Яармаг, Хан-Уул дүүрэг",
  "lat":           47.8864,
  "lng":           106.8236,
  "image":         "https://cdn.example.com/stations/hub.jpg"
}
Статус Тайлбар
400 station_id UUID формат буруу
404 Станц олдсонгүй эсвэл байгууллагын хамрах хүрээнд байхгүй
Цэнэглэгч / Хошуу
GET /b2b/v1/charge-points Дэд бүтцийн мод бүтэц (Live)
Байгууллагын бүх станц → цэнэглэгч → хошуу гэсэн шатлалтай бүтцийг real-time холболтын төлөвтэй нь хамт буцаана.
Response
Алдаа
200 OK
[
  {
    "station_id":    "550e8400-e29b-41d4-a716-446655440000",
    "station_name":  "ХУД Салбар",
    "address":       "Яармаг, Хан-Уул дүүрэг",
    "lat":           47.8864,
    "lng":           106.8236,
    "image":         "https://cdn.example.com/stations/hub.jpg",
    "charge_points": [
      {
        "charge_point_id":    "CP001",
        "model":              "EC500",
        "vendor":             "ABB",
        "connection_status":  "Online",
        "connectors": [
          { "connector_id": 1, "status": "Available" },
          { "connector_id": 2, "status": "Charging"  }
        ],
        "last_seen": "2024-06-15T09:30:00Z"
      }
    ]
  }
]
ℹ️
connection_status: Online | Offline  •  status: Available | Charging | Faulted | Unavailable | Reserved
Статус Тайлбар
400 Токен дахь org_id UUID формат буруу
500 Дэд бүтцийн мэдээлэл татахад алдаа гарсан
GET /b2b/v1/charge-points/:charge_point_id/status Нэг цэнэглэгчийн төлөв
Тодорхой нэг цэнэглэгчийн холболтын болон ажиллагааны төлөвийг real-time авна. Байгууллагын хамрах хүрээнд байгаа эсэхийг (FindByCPIDAndOrgID) шалгана.
Path Params
Response
Алдаа
Параметр Төрөл Тайлбар
charge_point_idrequired string Цэнэглэгчийн танигч (жишээ: CP001)
200 OK
{
  "charge_point_id":    "CP001",
  "connection_status":  "Online",
  "operational_status": "Available",
  "last_seen":          "2024-06-15T09:30:00Z"
}
Статус Тайлбар
404 Цэнэглэгч олдсонгүй эсвэл байгууллагын хамрах хүрээнд байхгүй
Алсын Удирдлага
⚠️
Командууд Redis pub/sub-аар OCPP core системд дамждаг. HTTP 202 нь командыг хүлээн авсан гэсэн үг — цэнэглэгч гүйцэтгэсэн эсэхийг Webhook event-ээр мэдэгдэнэ.
POST /b2b/v1/remote-start Цэнэглэлт эхлүүлэх
Цэнэглэгч рүү OCPP RemoteStart команд илгээнэ. Амжилттай бол Pending статустай session үүсгэж session_id-г буцаана. Webhook transaction.started эвэнтийг энэ session-аар correlate хийнэ.
Request Body
Response
Алдаа
Талбар Төрөл Тайлбар
charge_point_idrequired string Цэнэглэгчийн ID
connector_idrequired string Хошууны дугаар — string хэлбэрээр ("1")
rfid_tagrequired string Гадны RFID / idToken — цэнэглэгч рүү ExternalTag-аар дамжина
{
  "charge_point_id": "CP001",
  "connector_id":    "1",
  "rfid_tag":        "04A2B3C4D5E6F7"
}
202 Accepted
{
  "session_id": "7a3f9e1c-4b2d-48a0-9c5e-1d2f3a4b5c6d",
  "status":     "PENDING"
}
ℹ️
session_id-г хадгалаарай. Цэнэглэгч хариулсны дараа transaction.started webhook ирнэ. BillType: "B2B", ChargingType: "b2b_remote" автоматаар тохируулагдана.
Статус Тайлбар
400 Шаардлагатай талбар дутуу эсвэл токен дахь org_id буруу
409 Validation амжилтгүй — хошуу ашиглагдаж байна эсвэл эрхгүй
500 Session үүсгэхэд эсвэл Redis publish-д алдаа гарсан
POST /b2b/v1/remote-stop Цэнэглэлт зогсоох
Явагдаж байгаа цэнэглэлтийг transaction_id-аар зогсооно. Байгууллагын харьяа цэнэглэгч мөн эсэхийг (FindByCPIDAndOrgID) шалгасны дараа OCPP RemoteStop командыг Redis-ээр дамжуулан илгээнэ.
Request Body
Response
Алдаа
Талбар Төрөл Тайлбар
charge_point_idrequired string Цэнэглэгчийн ID
transaction_idrequired string OCPP protocol transaction ID — webhook transaction.started-ээс авсан утга
{
  "charge_point_id": "CP001",
  "transaction_id":  "10294"
}
202 Accepted
{
  "status":  "Accepted",
  "message": "Remote stop command dispatched successfully to core system"
}
Статус Тайлбар
400 Шаардлагатай талбар дутуу эсвэл токен дахь org_id буруу
403 Цэнэглэгч олдсонгүй эсвэл байгууллагын хамрах хүрээнд байхгүй
500 Redis publish амжилтгүй — OCPP команд дамжуулах боломжгүй
🚫
Алдааны Код Лавлах
Статус Нэр Тайлбар
400 Bad Request Request body / параметр алдаатай, шаардлагатай талбар дутуу
401 Unauthorized Bearer токен байхгүй эсвэл хүчингүй (Keycloak шалгалт)
403 Forbidden Токен хүчинтэй боловч тухайн нөөцөд хандах эрхгүй
404 Not Found Хайсан нөөц олдсонгүй
409 Conflict Бизнесийн дүрмийн зөрчил (хошуу ашиглагдаж байна г.м.)
500 Internal Server Error Серверийн дотоод алдаа
Алдааны Response бүтэц
{ "error": "Human-readable error message" }
Webhook Events
Тохиргоо & Signature
Method
POST
Content-Type
application/json
Signature Header
X-CSMS-Signature
🔒
HMAC-SHA256 баталгаажуулалт: хүсэлт бүрийг манай системээс ирсэн эсэхийг шалгахын тулд raw body-г өөрийн Webhook Secret түлхүүрээр хэшлэж, X-CSMS-Signature header-тэй таарч байгааг заавал шалгана уу.
B2B интеграцийн дарааллын диаграм
3rd party CSMS Charge Point StatusNotification (*) webhook: status-changed (*) POST /remote-start 202 Accepted (409 if busy) RemoteStartTransaction.req StartTransaction.req webhook: transaction-started {txnId} MeterValues.req (*) webhook: meter-values (*) POST /remote-stop 202 Accepted RemoteStopTransaction.req StopTransaction.req webhook: transaction-stopped 3rd party CSMS Charge Point REST API Webhook OCPP (WebSocket)
Webhook endpoint тань 10 секундын дотор HTTP 2xx хариу буцаах ёстой (HTTP client timeout = 10s). Амжилтгүй бол asynq экспоненциал хойшлуулалттайгаар 5 удаа дахин оролдоно (MaxRetry: 5, Retention: 24h).
🔑
Event subscription шүүлтүүр: webhook нь зөвхөн external_systems.enabled_events тохиргоонд тухайн event нэр бүртгэгдсэн, байгууллага status = ACTIVE бөгөөд expire_date дуусаагүй тохиолдолд л илгээгдэнэ.
EVENT charger.status.changed Хошууны төлөв өөрчлөгдөх
Цэнэглэгч станцын хошууны төлөв өөрчлөгдөх бүрд бодит хугацаанд илгээгдэнэ. Цэнэглэлт эхлэх/дуусах, алдаа гарах, хошуу сул болох зэрэг бүх төлөвийн шилжилт энд орно.
Payload
Талбарууд
{
  "event":           "charger.status.changed",
  "charge_point_id": "CP-MONGOLIA-01",
  "timestamp":       1781440000,
  "data": {
    "connector_id": 1,
    "status":       "Charging",
    "error_code":   "NoError",
    "timestamp":    "2026-06-14T10:30:00Z"
  }
}
Талбар Төрөл Тайлбар
data.connector_id int Хошууны дугаар
data.status string Available | Preparing | Charging | Faulted | Unavailable | Reserved
data.error_code string OCPP алдааны код (NoError нь алдаагүй гэсэн үг)
data.timestamp ISO 8601 Цэнэглэгч дээрх үйл явдлын цаг
EVENT transaction.started Цэнэглэлт эхэлсэн
OCPP транзакци амжилттай үүсэх үед илгээгдэнэ. transaction_id-г хадгалаарай — цэнэглэлт зогсооход (remote-stop) болон transaction.stopped webhook-д шаардлагатай.
Payload
Талбарууд
{
  "event":           "transaction.started",
  "charge_point_id": "CP-MONGOLIA-01",
  "timestamp":       1781440100,
  "data": {
    "transaction_id": "10294",
    "connector_id":   1,
    "meter_start":    45120,
    "start_time":     "2026-06-14T10:31:00Z",
    "charging_type":  "remote"
  }
}
Талбар Төрөл Тайлбар
data.transaction_id string OCPP Transaction ID — remote-stop-д ашиглана
data.connector_id int Хошууны дугаар
data.meter_start float (Wh) Эхлэх үеийн тоолуурын утга (Ватт.цаг)
data.start_time ISO 8601 Цэнэглэлт эхэлсэн цаг
data.charging_type string remote | b2b_remote | rfid
EVENT meter.values.received Цэнэглэх явцын мэдээлэл
Цэнэглэх явцад цэнэглэгчээс тогтмол давтамжтайгаар (15–30 сек тутамд) ирдэг зарцуулсан кВт.цаг болон одоогийн мөнгөн дүнгийн мэдээлэл. Бодит цагийн дашбоард харуулах болон лимит хяналтанд ашиглана.
Payload
Талбарууд
{
  "event":           "meter.values.received",
  "charge_point_id": "CP-MONGOLIA-01",
  "timestamp":       1781440500,
  "data": {
    "transaction_id": "10294",
    "connector_id":   1,
    "consumed_kwh":   4.25,
    "duration_sec":   300,
    "timestamp":      "2026-06-14T10:36:00Z"
  }
}
Талбар Төрөл Тайлбар
data.consumed_kwh float Нийт зарцуулсан кВт.цаг
data.duration_sec int64 Цэнэглэлт эхэлснээс хойших секундийн тоо
data.transaction_id string? Холбогдох OCPP Transaction ID — omitempty, байхгүй ч байж болно
EVENT transaction.stopped Цэнэглэлт дуусгавар болсон
Цэнэглэлт ямар нэг шалтгаанаар зогсоогдож, санхүүгийн процесс хаагдах үед илгээгдэнэ. Энэ эвэнт ирснийхээ дараа тухайн транзакцийн эцсийн дүн тооцоологдсон гэж үзнэ.
Payload
Талбарууд
{
  "event":           "transaction.stopped",
  "charge_point_id": "CP-MONGOLIA-01",
  "timestamp":       1781442000,
  "data": {
    "transaction_id":   "10294",
    "connector_id":     1,
    "meter_stop":       65240,
    "energy_delivered": 20.12,
    "reason":           "Remote",
    "stop_time":        "2026-06-14T11:01:00Z"
  }
}
Талбар Төрөл Тайлбар
data.meter_stop float (Wh) Дуусах үеийн тоолуурын утга (Ватт.цаг)
data.energy_delivered float (kWh) Нийт дамжуулсан цахилгааны хэмжээ
data.reason string Remote | Local | EVDisconnected | PowerLoss | Other
data.stop_time ISO 8601 Цэнэглэлт зогссон цаг
energy_delivered = (meter_stopmeter_start) / 1000 — кВт.цагаар.