微信咨询
产品经理为您提供专业解答
手机扫码加我微信
OR
手机号码:
15920323068
简电云 | 充电平台基于中电联协议互联互通的设计与实现
优匠科技 · Sep 23, 2026

国内充电运营平台接入第三方聚合平台、城市监管平台或其他运营商时,常会采用中电联充换电服务信息交换相关规范。它解决的不是充电桩与平台之间的通信,而是平台与平台之间如何交换场站、设备、状态和充电订单等信息。

这类项目真正困难的部分通常不是发送一个 HTTP 请求,而是统一协议版本、处理加密签名、建立可靠的业务状态机,并在双方数据口径不一致时保证订单可追溯。本文从工程落地角度给出一套实现方案。文中的地址、运营商编号和业务数据均为演示内容;不同标准版本、地方平台和运营商可能存在扩展,生产接入应以双方确认的接口清单和联调文档为准。

一、先划清协议边界

一套典型的充电业务会涉及三层通信:

代码语言:JavaScript
自动换行
AI代码解释
充电桩 <--设备协议--> 运营商平台 <--中电联信息交换协议--> 对接平台

设备协议负责启停充电、实时遥测和故障上报;中电联信息交换协议负责平台间的数据共享与业务协同。对接平台发起启动请求后,运营商平台仍需把请求转换成设备协议命令,再等待充电桩执行。因此,“接口受理成功”和“充电已经启动”是两个不同状态。

落地前应由双方冻结一份接入基线,至少包括:

项目

需要确认的内容

协议版本

标准版本、地方扩展版本、修订日期

运营商身份

OperatorID、平台编码及测试环境编码

接口范围

基础信息、状态、鉴权、启停、订单等

安全参数

签名密钥、数据密钥、初始向量及换钥方式

字段口径

时间、金额、电量、枪口编号、状态枚举

回调策略

地址、超时、重试次数、幂等规则

不要只写“按中电联协议接入”。同一接口在不同项目中可能存在字段增减、路径差异或枚举扩展,版本基线必须能够落到具体文档和联调样例。

二、总体架构

建议在现有充电业务之外增加独立的互联互通网关:

展开
代码语言:JavaScript
自动换行
AI代码解释
对接平台
   |
   v
接入网关:验签、解密、限流、审计
   |
   v
协议适配层:字段转换、版本适配、幂等控制
   |
   +--> 基础数据服务:场站、设备、价格
   +--> 状态服务:空闲、充电、离线、故障
   +--> 充电服务:鉴权、启动、停止、订单
   +--> 回调任务:结果通知、状态通知、订单通知

接入网关不直接操作充电桩。它先完成安全校验,再把标准报文转换成内部命令。这样既能隔离外部协议变化,也能避免在核心充电服务中散落大量外部字段判断。

每个合作方应维护独立配置,包括协议版本、密钥版本、回调地址、超时时间、启用接口和扩展字段。不要把合作方差异写成遍布代码的 if/else。

三、报文安全处理

常见协议实现会在 JSON 外层携带运营商标识、加密数据、时间戳、序列号和签名,结构类似:

展开
代码语言:JavaScript
自动换行
AI代码解释
{
  "OperatorID": "1000000001",
  "Data": "Base64EncodedCipherText",
  "TimeStamp": "20260923153045",
  "Seq": "0001",
  "Sig": "RequestSignature"}

其中 Data 是业务 JSON 加密后的 Base64 文本,Sig 用于验证请求来源和报文完整性。工程上应把处理顺序固定下来:

展开
代码语言:JavaScript
自动换行
AI代码解释
校验报文长度和必填字段
  -> 根据 OperatorID 加载协议配置与密钥版本
  -> 校验时间窗口和 Seq
  -> 按约定的原始字符串计算并校验 Sig
  -> Base64 解码并解密 Data
  -> 解析业务 JSON
  -> 执行业务幂等检查

签名串的字段顺序、字符编码、大小写以及加密算法参数必须严格按双方采用的协议版本实现。常见项目会使用共享密钥签名以及对称加密,但不能仅凭经验猜测算法、填充方式或初始向量。

建议使用成熟密码库,并注意以下细节:

  • 明确使用 UTF-8,禁止依赖操作系统默认编码;

  • 签名使用协议要求的原始值,不对 Data 做二次 Base64 或格式化;

  • 使用常量时间比较方法校验签名,减少时序差异;

  • 密钥放入密钥管理服务或受控配置中心,日志中不得输出明文密钥、解密后的用户标识或完整凭证;

  • 支持密钥版本和灰度换钥,在约定窗口内兼容新旧密钥;

  • 对时间戳设置合理窗口,并以 OperatorID + TimeStamp + Seq 等组合进行防重放控制。

下面的 Java 伪代码强调处理边界,具体算法名称和签名拼接规则应来自已确认的协议版本:

展开
代码语言:JavaScript
自动换行
AI代码解释
public BusinessRequest decode(Envelope envelope) {
    PartnerConfig config = configService.require(envelope.operatorId());
    validateTimestamp(envelope.timeStamp(), config.allowedClockSkew());
    replayGuard.check(envelope.operatorId(), envelope.timeStamp(), envelope.seq());

    String signSource = config.signRule().build(envelope);
    byte[] expected = signer.sign(signSource, config.signSecret());
    if (!MessageDigest.isEqual(expected, decodeSignature(envelope.sig()))) {
        throw new ProtocolException("INVALID_SIGNATURE");
    }

    byte[] cipherText = Base64.getDecoder().decode(envelope.data());
    byte[] plainText = cipher.decrypt(cipherText, config.dataKey(), config.iv());
    return json.readValue(plainText, BusinessRequest.class);
}

响应也要经过相同版本的封装流程。即使业务失败,也应返回协议约定的结果码和加密数据,不能把内部异常堆栈直接暴露给调用方。

四、接口分组与数据同步

互联互通接口可以按数据变化频率分成三组。

1. 基础信息

场站、充电设备、充电接口和计费规则变化较慢,适合“全量初始化 + 增量更新 + 定期校准”。首次接入先完成分页全量同步,此后由变更通知驱动更新,每天再执行一次差异校准。

核心关联关系建议保留为:

代码语言:JavaScript
自动换行
AI代码解释
运营商 OperatorID
  -> 场站 StationID
    -> 设备 EquipmentID
      -> 充电接口 ConnectorID

外部 ID 应按字符串保存,不要转换成整数。数据库唯一键至少包含合作方和外部 ID,例如 (partner_id, connector_id),因为不同平台的编号空间未必全局唯一。

计费规则应按版本保存生效区间,不要覆盖历史记录。一笔订单最终使用哪个价格版本,应由启动时间和双方约定的计费规则确定,以便后续账单复核。

2. 设备状态

枪口状态变化频繁,通常采用主动通知,查询接口用于补偿。平台接到状态通知后,应比较事件时间或内部版本号,防止网络延迟导致旧状态覆盖新状态。

内部状态不要直接等同于某一家平台的枚举。可以先归一化为:

代码语言:JavaScript
自动换行
AI代码解释
UNKNOWN、OFFLINE、IDLE、OCCUPIED、CHARGING、FAULT、RESERVED

再通过版本适配器映射到对方协议值。对于无法精确映射的状态,按双方约定降级,并保留原始状态码用于排查。

3. 充电业务

充电业务通常包含设备鉴权、启动充电、停止充电、启动结果通知、停止结果通知和订单信息通知。它是异步流程,不适合用一次同步请求表达最终结果。

五、远程启动状态机

启动充电可以设计为以下状态机:

展开
代码语言:JavaScript
自动换行
AI代码解释
CREATED
  -> ACCEPTED
  -> COMMAND_SENT
  -> STARTED
  -> CHARGING
  -> STOPPING
  -> FINISHED异常分支:REJECTED、START_FAILED、TIMEOUT、CANCELLED

对接平台提交启动请求后,运营商平台完成参数与幂等校验,只返回“已受理”或“拒绝受理”。随后平台向设备下发启动命令,并通过结果通知告知最终启动结果。

一条请求至少应保留这些关联字段:

字段

用途

合作方请求号

接口幂等与问题定位

运营商订单号

运营商内部业务主键

对接平台订单号

双方订单关联

ConnectorID

目标充电接口

设备交易号

关联桩侧交易

当前状态与版本

防止乱序更新

原始请求摘要

审计与重复请求比对

幂等不能只根据“接口在几秒内重复”判断。相同业务请求号和相同业务内容应返回第一次处理结果;相同请求号但业务内容不同,应拒绝并记录冲突。回调也要携带稳定的事件 ID 或由业务主键、事件类型和状态版本生成幂等键。

六、异步通知与可靠性

生产环境中必须假设回调会超时、重复、乱序和短暂失败。可靠通知可以使用事务消息表或 Outbox 模式:业务状态与待发送事件在同一数据库事务中落库,再由独立任务投递。

展开
代码语言:JavaScript
自动换行
AI代码解释
CREATE TABLE interop_outbox (
    id              BIGINT PRIMARY KEY,
    partner_id      VARCHAR(32) NOT NULL,
    event_type      VARCHAR(48) NOT NULL,
    business_key    VARCHAR(96) NOT NULL,
    state_version   BIGINT NOT NULL,
    payload_json    TEXT NOT NULL,
    status          VARCHAR(16) NOT NULL,
    retry_count     INT NOT NULL,
    next_retry_at   TIMESTAMP NOT NULL,
    created_at      TIMESTAMP NOT NULL,
    UNIQUE (partner_id, event_type, business_key, state_version)
);

仅在收到对方明确的成功响应后,任务才进入 SUCCESS。网络超时不能解释成业务失败,因为对方可能已经处理成功。重试采用指数退避并设置上限,超过上限进入人工处理队列;不能无限快速重试。

建议分别记录三种时间:业务事件发生时间、平台收到事件时间、通知成功时间。这样才能识别设备延迟、内部积压和外部接口延迟。

七、订单和金额校验

订单是双方最容易产生分歧的数据。平台应同时保留原始订单、归一化订单和计费明细,不要只保存一个最终金额。

金额优先使用最小货币单位的整数,电量使用 BigDecimal 并明确精度和舍入规则。例如:

展开
代码语言:JavaScript
自动换行
AI代码解释
record ChargeOrder(
    String startChargeSeq,
    String connectorId,
    Instant startTime,
    Instant endTime,
    BigDecimal totalPower,
    long electricityFeeFen,
    long serviceFeeFen,
    long totalFeeFen
) {}

入库前至少校验:

  • 结束时间不早于开始时间;

  • 总电量不为负数,并与分时电量之和在约定误差内一致;

  • 总金额与电费、服务费及其他约定费用之和一致;

  • 订单中的枪口、设备和场站关系能够匹配;

  • 同一订单的后续版本只能按状态机前进,不能覆盖已经确认的终态。

若双方因精度、计费时点或价格版本产生差异,应进入对账异常表,保留双方原值和差异原因,不能直接修改原始报文“抹平”差额。

八、错误码、日志与监控

协议错误和业务错误应分开处理。签名错误、解密失败、JSON 格式错误属于协议层错误;枪口不存在、设备离线、订单已结束属于业务层错误。内部异常先映射成稳定的对外错误码,再记录内部错误详情。

日志建议包含:

代码语言:JavaScript
自动换行
AI代码解释
traceId、partnerId、interfaceName、requestId、businessKey、
timestamp、duration、resultCode、retryCount、payloadHash

手机号、车牌、用户令牌、密钥和解密后的完整业务报文不应写入普通日志。确需保存原始报文时,应加密存储、限制访问并设置保留期限。

监控至少覆盖接口成功率、签名失败数、解密失败数、时间戳超限数、回调积压量、重试次数、启动成功率、启动耗时、状态延迟和订单差异数。按合作方和接口分别统计,整体平均值往往会掩盖单一通道故障。

九、联调与上线检查

上线前建议按以下顺序验证:

  1. 用双方确认的固定报文完成加密、解密和签名互验;

  2. 同步一个测试场站,核对场站、设备、枪口和价格层级;

  3. 验证状态通知的重复、乱序、离线恢复和补偿查询;

  4. 完成启动、启动失败、主动停止、设备停止和超时等完整流程;

  5. 核对跨时段计费、零电量订单、异常结束和重复订单;

  6. 模拟回调超时、返回失败和网络恢复,确认重试不会制造重复业务;

  7. 检查日志脱敏、密钥权限、限流和告警是否生效。

正式切换时可以先开放少量测试枪,再逐步扩大场站范围。双方应约定故障联系人、问题报文留存方式以及状态和订单的补偿时间窗口。

总结

中电联协议的互联互通实现,本质上是一个跨平台的分布式业务系统。HTTP、JSON、加密和签名只是入口,真正决定稳定性的,是清晰的版本基线、可靠的异步状态机、严格的幂等设计以及可复核的订单数据。

一个可维护的实现应把安全封装、协议适配和内部业务分层;基础信息采用全量与增量结合,状态通知配合查询补偿,启停充电采用异步结果通知,订单保留原文与版本。只有把超时、重复、乱序和差异对账当作正常情况设计,平台间互联互通才能从“接口调通”走向长期稳定运行。

说明:本文用于介绍通用工程方法,不替代标准原文、双方签署的接口文档及安全规范。示例标识、地址和数据均为虚构内容。

共享充电 选择优匠
共享充电整体解决方案服务商
在线咨询
微信咨询