# 权益开放平台 OpenAPI v2 接入说明

本文档用于服务端对服务端接入，也适用于“单产品 H5 地址生成”场景。客户系统通过 API 请求中台，中台完成签名鉴权、商户授权、标准产品路由、服务访问地址生成、支付确认和订单查询。

## 1. 三种交付形态

| deliveryMode | 适用场景 | 返回结果 |
|---|---|---|
| api_open | 客户自己做前端/APP/小程序，只需要服务端接口 | JSON 订单结果 |
| h5_page | 客户只接一个产品，希望快速获得服务页面 | 服务访问地址 h5Url/url |
| sdk_widget | 客户接多产品权益商城/组件 | SDK 页面地址 sdkUrl |

说明：H5 是 SDK 的单产品拆分形态。客户仍然请求中国道 API；中国道校验授权并服务端签名请求上游 `endpointAccess`，再把上游返回的 `h5Url/url` 返回给客户。中国道不自建这些产品的 H5 页面。同一产品存在多个服务通道时，由后台智能路由选择具体服务通道，客户侧字段保持一致。

## 2. 基础地址

测试环境：

```text
http://49.233.179.102/prod-api/openapi/v2
```

正式环境以平台分配域名为准，例如：

```text
https://lukeydao.com/prod-api/openapi/v2
```

## 3. 签名请求头

所有接口均需携带：

```text
X-App-Id: 分配的 AppID
X-Timestamp: 当前毫秒时间戳
X-Nonce: 随机字符串
X-Sign: 签名
Content-Type: application/json
```

## 4. 签名算法

### 4.1 GET 请求

GET 没有 JSON body 时：

```text
bodyHash = 空字符串
signRaw = appId={appId}&timestamp={timestamp}&nonce={nonce}&bodyHash=&key={appSecret}
X-Sign = sha256(signRaw)
```

### 4.2 POST 请求

POST 请求先移除 body 中的 `sign` 字段，再按字段名排序后转紧凑 JSON，计算：

```text
bodyHash = sha256(sortedBodyJson)
signRaw = appId={appId}&timestamp={timestamp}&nonce={nonce}&bodyHash={bodyHash}&key={appSecret}
X-Sign = sha256(signRaw)
```

注意：数字字段建议传整数或字符串，避免不同语言把 `1.0` 与 `1` 序列化成不同结果。生产接入建议服务端固定 JSON 序列化规则。

## 5. 产品列表

```http
GET /products
```

返回当前 App 所属商户已授权的权益产品。

示例响应：

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": [
    {
      "productCode": "DirectchargeLitter",
      "interfaceTypeCode": "directcharge_litter_interface",
      "productName": "话费小额充值",
      "category": "充值缴费",
      "deliveryModes": ["api_open", "sdk_widget"],
      "pricingMode": "fixed",
      "priceDisplayType": "fixed",
      "quoteRequired": 0,
      "status": "ready"
    }
  ]
}
```


## 统一产品接口与智能路由

对外接入原则：下游客户只接中国道标准产品接口，不按服务通道分别适配。同一个产品即使存在多个服务通道，也保持统一请求字段、统一响应字段、统一订单状态、统一错误码和统一回调通知。

后台智能路由根据商户授权、产品配置、服务通道可用性、成本价、城市/资源覆盖、接口健康状态、履约成功率和风控策略，自动选择最合适的服务通道。下游文档不暴露服务方私有字段为必接字段，下游客户无需感知具体服务方。

| 标准产品 | 标准入口 | 后台路由能力 | 对外口径 |
| --- | --- | --- | --- |
| 电影票 | 中国道电影票标准接口 | 支持多服务通道路由 | 城市、影院、影片、场次、座位、报价、下单、查单字段保持统一；服务方差异由后台适配。 |
| 票务 | 中国道票务标准接口 | 支持当前及后续服务通道扩展 | 城市、航司/车次/票务资源、预订、查单、退款字段保持统一。 |
| 快递 | 中国道快递标准接口 | 支持当前及后续服务通道扩展 | 寄件、收件、重量、保价、价格、下单、轨迹字段保持统一。 |
| 打车 | 中国道打车标准接口 | 支持当前及后续服务通道扩展 | 起点、终点、车型、估价、下单、结算、查单字段保持统一。 |
| 生活服务 H5 | 中国道生活服务 H5 标准入口 | 支持多类生活服务通道路由 | 中国道校验商户授权后返回服务访问地址；客户只处理统一的跳转、订单、支付和回调结果。 |

内部系统可保留服务方名称用于成本、路由、运维和排障；开放平台、SDK 文档和商户接入文档统一使用“标准产品接口 / 服务通道 / 服务访问地址”等中性口径。

## H5 产品入口：返回服务访问地址

H5 类产品不是由中国道重新制作页面。标准链路是：商户/SDK 请求中国道接口，中国道校验授权、服务通道路由和服务端签名后，返回服务访问地址 `h5Url/url` 给商户。

```http
POST /openapi/v1/sdk/h5-access?merchantId=11
Content-Type: application/json
Origin: https://merchant.example.com
```

示例参数：

```json
{
  "merchantId": 11,
  "typeCode": "LifeServiceH5",
  "interfaceTypeCode": "life_service_h5",
  "phone": "13800138000",
  "staffPhone": "13800138000",
  "staffName": "张三",
  "userId": "merchant-user-001"
}
```

返回示例：

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "h5Url": "https://service.example.com/entry?...",
    "expireTime": "2026-07-06 10:30:00"
  },
  "requestId": "req_xxxxx"
}
```

客户只需要将用户跳转至 `h5Url/url`，并根据中国道统一订单状态和异步通知处理后续业务；不需要自行对接具体服务方页面或解析服务方私有参数。

## 服务通道接入状态

新增服务能力统一进入中国道后台服务通道路由池。对下游仍按中国道标准产品接口输出，不要求客户直接适配任何服务方私有字段。

- 电影票：API 标准产品，已接入城市、影院、影片、场次、座位、订单参数映射。
- 票务：API 标准产品，按中国道票务标准字段输出。
- 快递：API 标准产品，按中国道快递标准字段输出。
- 企业打车：H5 / API 标准产品，按中国道打车标准字段输出。
- 开放能力总入口：内部调试能力，仅用于内部接入验证；状态变更动作禁止通过公开查询入口直接触发。

## 6. 创建订单 / 生成 H5 地址

```http
POST /order/create
```

通用参数：

| 字段 | 必填 | 说明 |
|---|---|---|
| productCode | 是 | 产品编码，如 DirectchargeLitter |
| deliveryMode | 否 | api_open / h5_page / sdk_widget，默认 api_open |
| outOrderNo | 是 | 客户系统订单号，幂等字段 |
| amount | 视产品 | 固定价产品可传金额；动态报价产品以 quoteId/锁价为准 |
| phone/account/mobile | 视产品 | 用户账号、手机号或充值账号 |
| merchantMemberId/customerId/userId | 否 | 客户侧用户标识 |
| notifyUrl/callbackUrl | 否 | 单笔订单通知地址；未传时使用商户配置 |
| bizParams | 否 | 产品业务参数对象 |

### 6.1 API 模式示例

```json
{
  "productCode": "DirectchargeLitter",
  "deliveryMode": "api_open",
  "outOrderNo": "C202606270001",
  "amount": 1,
  "phone": "13800138000",
  "bizParams": {
    "operator": "mobile",
    "province": "北京",
    "city": "北京"
  }
}
```

返回：

```json
{
  "code": 200,
  "data": {
    "orderNo": "V2202606271602274917",
    "outOrderNo": "C202606270001",
    "productCode": "DirectchargeLitter",
    "deliveryMode": "api_open",
    "status": "WAIT_PAY",
    "amount": "1.00"
  }
}
```

### 6.2 H5 模式示例

```json
{
  "productCode": "DirectchargeLitter",
  "deliveryMode": "h5_page",
  "outOrderNo": "H5202606270001",
  "amount": 1,
  "phone": "13800138000"
}
```

返回：

```json
{
  "code": 200,
  "data": {
    "orderNo": "V2202606271713226658",
    "productCode": "DirectchargeLitter",
    "deliveryMode": "h5_page",
    "status": "WAIT_PAY",
    "amount": "1.00",
    "h5Url": "https://平台域名/sdk/commercial-v2/index.html?merchantId=11&productCode=DirectchargeLitter&deliveryMode=h5_page&orderNo=V2202606271713226658",
    "entryType": "platform_h5"
  }
}
```

客户应将用户跳转到 `h5Url`。后续页面由中台承载并继续完成授权、订单、服务入口与状态控制。

## 7. 支付确认

```http
POST /order/pay-confirm
```

客户系统确认自己已经完成收款后调用。调用后中台才会进入余额校验、上游履约、成功/失败状态推进。

请求：

```json
{
  "orderNo": "V2202606271602274917"
}
```

注意：该接口会触发真实履约。测试环境请先使用低金额订单，并按产品规则处理失败/关闭/退款。

## 8. 查单

```http
GET /order/query?orderNo=平台订单号
```

H5 订单查单会继续返回 `h5Url`，便于客户系统重新打开入口。

## 9. 状态说明

| 状态 | 含义 |
|---|---|
| WAIT_PAY | 已创建，等待客户确认收款 |
| PAID / PROCESSING | 已确认收款，履约处理中 |
| SUCCESS | 履约成功 |
| CLOSED | 已关闭 |
| FAILED | 履约失败 |

## 10. 通知地址

订单履约成功、失败、退款等结果会按以下优先级通知：

1. 订单创建时传入的 `notifyUrl` / `callbackUrl`
2. 商户 SDK 配置中的 `notifyUrl`
3. 若均未配置，则不发送下游通知，只保留平台订单状态

商户应对 `orderNo/outOrderNo/event/status` 做幂等处理。

## 11. 当前产品接入状态说明

当前 v2 接入层已支持通用产品列表、建单、H5 地址生成、查单。不同产品的真实履约参数仍按产品能力区分：

- 固定价产品：可直接按金额/账号建单。
- H5 产品：推荐使用 `deliveryMode=h5_page` 获取服务访问地址；中国道负责授权、签名、参数组装和智能路由。
- 动态报价产品：需先完成报价/锁价参数模板后再开放正式下单。
- 高风险履约产品：需逐产品跑 `create → pay-confirm → 履约结果 → query → notify` 验收后再正式开放。
