1944 lines
78 KiB
Markdown
1944 lines
78 KiB
Markdown
# 虚拟商品充值服务商系统 - 产品需求文档
|
||
|
||
## 接口与任务索引
|
||
|
||
### 对外提供的接口(被邮储银行调用)
|
||
|
||
| 接口名称 | 说明 | 文档位置 |
|
||
|---------|------|----------|
|
||
| 服务预约接口 | 接收预约请求,获取券码链接 | [3.1.1](#311-服务预约接口) |
|
||
| 服务取消接口 | 接收取消请求,作废券码 | [3.1.2](#312-服务取消接口) |
|
||
| 订单过期积分查询接口 | 查询过期幸福点信息 | [3.1.4](#314-订单过期积分查询接口) |
|
||
| 服务详情查询接口 | 获取券码链接展示服务详情 | [3.1.6](#316-服务详情查询接口) |
|
||
| 对账文件查询接口 | 查询可用的对账文件列表 | [3.4.3](#343-对账文件查询接口) |
|
||
| 对账文件下载接口 | 根据文件ID下载对账文件 | [3.4.4](#344-对账文件下载接口) |
|
||
| 批量补推接口 | 手动批量触发服务完成通知 | [3.4.5](#345-批量补推接口) |
|
||
|
||
### 调用下游的接口(调用邮储银行API)
|
||
|
||
| 接口名称 | 说明 | 文档位置 |
|
||
|---------|------|----------|
|
||
| 权益码有效性验证接口 | 验证权益码是否过期 | [3.1.1](#311-服务预约接口) |
|
||
| 服务预约接口 | 发起预约请求 | [3.1.1](#311-服务预约接口) |
|
||
| 预约服务状态查询接口 | 查询邮储侧服务状态 | [3.1.2](#312-服务取消接口) |
|
||
| 预约取消接口 | 发起取消请求 | [3.1.2](#312-服务取消接口) |
|
||
| 服务完成接口 | 通知邮储服务完成 | [3.1.3](#313-服务完成通知接口) |
|
||
| 过期积分查询接口 | 查询订单退还时已过期积分 | [3.1.4](#314-订单过期积分查询接口) |
|
||
|
||
### 调用上游的接口(调用蓝色兄弟API)
|
||
|
||
| 接口名称 | 说明 | 文档位置 |
|
||
|---------|------|----------|
|
||
| 券码获取接口 | 获取虚拟商品券码 | [3.2.1](#321-券码获取功能) |
|
||
| 券码查询接口 | 查询券码当前状态 | [3.2.2](#322-券码查询功能) |
|
||
| 券码作废接口 | 作废待使用/已过期券码 | [3.2.3](#323-券码作废功能) |
|
||
| 券码状态回调 | 接收券码状态变更通知 | [3.2.4](#324-券码状态回调接收) |
|
||
|
||
### 定时任务
|
||
|
||
| 任务名称 | 执行频率 | 说明 | 文档位置 |
|
||
|---------|----------|------|----------|
|
||
| 券码状态同步 | 每小时 | 主动查询券码状态,创建对应处理任务 | [6.2](#62-券码状态同步流程) |
|
||
| 通知任务重试 | 每5分钟 | 扫描失败任务,按退避策略重试 | [6.2.1](#621-通知任务执行流程) |
|
||
| 失败任务告警 | 每10分钟 | 扫描超过最大重试次数的任务,发送告警(不再本系统实现,外部有监控系统,在监控系统中实现) | [5.2.5](#525-数据一致性监控) |
|
||
|
||
### 异步通知任务
|
||
|
||
| 任务类型 | task_type | 触发来源 | 处理逻辑 |
|
||
|----------|-----------|----------|----------|
|
||
| 服务完成通知 | 1 | 回调/主动查询 | 调用邮储服务完成接口 → 订单状态改为300 |
|
||
| 过期处理 | 2 | 主动查询 | 调用邮储预约取消接口 → 订单状态改为500 |
|
||
| 作废补偿 | 3 | 主动查询 | 调用邮储预约取消接口 → 订单状态改为400 |
|
||
|
||
### 订单状态流转
|
||
|
||
```
|
||
100(未预约) → 200(已预约) → 300(已完成)→ 400(已取消) → 500(已过期)
|
||
```
|
||
|
||
---
|
||
|
||
## 1. 功能模块划分
|
||
|
||
### 1.1 模块结构
|
||
|
||
```
|
||
服务商系统
|
||
├── 接口服务模块(对接邮储银行服务开放平台)
|
||
│ ├── 服务预约接口
|
||
│ ├── 服务取消接口
|
||
│ ├── 服务完成通知接口
|
||
│ ├── 订单过期积分查询接口
|
||
│ └── 服务状态查询接口
|
||
├── 券码管理模块(对接蓝色兄弟营销开放API)
|
||
│ ├── 券码获取功能
|
||
│ ├── 券码查询功能
|
||
│ ├── 券码作废功能
|
||
│ └── 券码状态回调接收
|
||
├── 订单管理模块
|
||
│ ├── 订单创建
|
||
│ ├── 订单状态管理
|
||
│ ├── 订单查询
|
||
│ └── 订单对账
|
||
├── 对账管理模块
|
||
│ ├── 对账文件查询
|
||
│ ├── 对账文件下载
|
||
│ └── 对账数据核对
|
||
└── 安全与加密模块
|
||
├── SM2/SM4/AES加解密(邮储银行)
|
||
├── RSA/AES加解密(蓝色兄弟)
|
||
└── 签名验签
|
||
```
|
||
|
||
### 1.2 模块关系
|
||
|
||
| 模块 | 调用方/被调用方 | 内部依赖 | 说明 |
|
||
|------|----------------|---------|------|
|
||
| 接口服务模块 | 被下游邮储银行调用 | 订单管理模块、券码管理模块 | 接收邮储银行请求,转发至内部处理 |
|
||
| 券码管理模块 | 调用上游蓝色兄弟API | 订单管理模块 | 负责券码全生命周期管理 |
|
||
| 订单管理模块 | - | 券码管理模块、对账管理模块 | 核心业务数据管理 |
|
||
| 对账管理模块 | 调用下游邮储银行API | 订单管理模块 | 月度对账处理 |
|
||
| 安全与加密模块 | - | 所有模块 | 提供安全基础能力 |
|
||
|
||
---
|
||
|
||
## 2. 公共响应规范
|
||
|
||
### 2.1 响应结构
|
||
|
||
所有接口统一使用以下响应结构:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"msg": "成功",
|
||
"traceId": "请求追踪ID",
|
||
"data": {
|
||
// 业务数据
|
||
}
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| code | int | M | 公共响应码,0表示成功,非0表示失败 |
|
||
| msg | String | M | 响应描述信息,当code!=0时为错误信息 |
|
||
| traceId | String | M | 请求追踪ID,用于问题排查。生成规则:使用雪花算法或UUID确保全局唯一 |
|
||
| data | Object | C | 业务数据,成功时返回 |
|
||
|
||
### 2.3 时间格式规范
|
||
|
||
系统内部统一使用 `yyyyMMddHHmmss` 格式存储和传输时间字段。与上游蓝色兄弟系统交互时需进行格式转换(蓝色兄弟使用 `yyyy-MM-dd HH:mm:ss` 格式)。
|
||
|
||
### 2.2 公共响应码
|
||
|
||
| 响应码 | 描述 | 说明 |
|
||
|-------|------|------|
|
||
| 0 | 成功 | 业务处理成功 |
|
||
| 1 | 系统异常 | 系统内部错误,请稍后重试 |
|
||
| 2 | 参数错误 | 请求参数校验失败 |
|
||
| 3 | 签名错误 | 签名验证失败 |
|
||
| 4 | 业务错误 | 业务规则校验失败 |
|
||
|
||
---
|
||
|
||
## 3. 功能详细说明
|
||
|
||
### 3.1 接口服务模块
|
||
|
||
#### 3.1.1 服务预约接口
|
||
|
||
**功能描述**:接收邮储银行服务开放平台的预约请求,为客户预约虚拟商品充值服务
|
||
|
||
**业务规则**:
|
||
1. 查询数据库验证服务编码(type)是否存在(数据库中维护邮储服务编码与营销平台活动的映射关系)
|
||
- 如果不存在:返回"暂不支持此服务"
|
||
- 如果存在:获取对应的AES加密密钥(aes_key)和向量(aes_iv),用于后续解密
|
||
2. 使用从数据库查询到的aes_key和aes_iv对request进行AES解密,解析出type(服务编码)、code(权益码)、mac(客户id)
|
||
- 解密失败:返回"参数错误"
|
||
3. 基于权益码(code)获取分布式锁,防止重复请求:
|
||
- 获取锁成功:继续执行后续流程
|
||
- 获取锁失败:返回"请勿重复提交"
|
||
4. 对code(权益码)进行幂等验证:
|
||
- 若订单状态为「服务已预约(200)」,直接返回预约成功(与正常请求返回一致)
|
||
- 若订单状态为「服务未预约(100)」,继续执行后续流程(更新订单,不新增)
|
||
- 若订单状态为「服务已取消(400)」,返回"服务已取消"
|
||
- 若订单状态为「服务已完成(300)」,返回"服务已生效"
|
||
- 若订单状态为「服务已过期(500)」,返回"服务已过期"
|
||
5. 请求邮储服务开放平台「高端客户权益积分预约服务状态查询接口」验证权益码是否过期
|
||
如果过期:
|
||
1、CRM渠道返回 "二维码20分钟内有效,现已超时失效,请联系理财经理重新生成二维码!
|
||
2、手机银行渠道返回 "当前页面停置时间过长,请您重新进入该页面"
|
||
6. 创建/更新订单记录(订单状态:服务未预约)
|
||
7. 请求邮储服务开放平台接口发起预约:
|
||
- 预约成功或返回161010(交易已预约):继续执行步骤8
|
||
- 其他情况:订单状态保持「服务未预约(100)」,返回预约失败
|
||
8. 请求蓝色兄弟营销平台获取券码链接(使用相同交易号和参数请求):
|
||
- 请求成功:更新订单状态为「服务已预约(200)」,返回预约成功响应
|
||
- 请求异常:订单状态保持「服务未预约(100)」,返回预约失败
|
||
9. 释放分布式锁
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| type | String | M | 服务编码,用于查询数据库获取AES解密密钥 |
|
||
| request | String | M | AES加密字符串,解密后格式:type=服务编码&code=权益码&mac=加密后的客户id |
|
||
| channel | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| tranChnl | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| backUrl | String | C | 返回手机银行的地址,可为空 |
|
||
| instType | String | M | 客户自营代理属性:01-自营,02-代理 |
|
||
| provinceInstNo | String | M | 客户归属一分机构号 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| url | String | M | 蓝色兄弟营销平台的兑换地址 |
|
||
| tranChnl | String | M | 渠道标识 |
|
||
| instType | String | M | 客户自营代理属性 |
|
||
| backUrl | String | C | 返回手机银行的地址 |
|
||
|
||
**验收标准**:
|
||
- [ ] 入参type(服务编码)为必填字段,缺失时返回"参数错误"
|
||
- [ ] 根据入参type查询数据库获取对应的aes_key和aes_iv
|
||
- [ ] 服务编码(type)不存在时,返回"暂不支持此服务"(在AES解密之前校验)
|
||
- [ ] 使用数据库查询到的aes_key和aes_iv能正确解密AES加密的request参数
|
||
- [ ] 能正确解析解密后的参数(type、code、mac)
|
||
- [ ] 幂等验证:相同权益码(code)状态为「服务已预约(200)」时,直接返回预约成功
|
||
- [ ] 幂等验证:相同权益码(code)状态为「服务未预约(100)」时,继续执行后续流程
|
||
- [ ] 幂等验证:相同权益码(code)状态为「已取消(400)」时,返回"服务已取消"
|
||
- [ ] 幂等验证:相同权益码(code)状态为「已完成(300)」时,返回"服务已生效"
|
||
- [ ] 幂等验证:相同权益码(code)状态为「已过期(500)」时,返回"服务已过期"
|
||
- [ ] 权益码过期且渠道为CRM(41)时,返回"二维码20分钟内有效,现已超时失效,请联系理财经理重新生成二维码"
|
||
- [ ] 权益码过期且渠道为手机银行(12)时,返回"当前页面停置时间过长,请您重新进入该页面"
|
||
- [ ] 订单创建/更新时初始状态为「服务未预约(100)」
|
||
- [ ] 邮储预约成功或返回161010(交易已预约)时,继续获取券码
|
||
- [ ] 邮储预约失败时,订单状态保持「服务未预约(100)」,返回预约失败
|
||
- [ ] 蓝色兄弟券码获取成功后,订单状态更新为「服务已预约(200)」
|
||
- [ ] 蓝色兄弟券码获取异常时,订单状态保持「服务未预约(100)」,返回预约失败
|
||
- [ ] 预约成功后返回蓝色兄弟兑换地址(url)
|
||
- [ ] 响应正确透传tranChnl、instType、backUrl字段
|
||
- [ ] 并发请求时,基于权益码获取分布式锁,获取失败返回"请勿重复提交"
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.1.1-001 | 正常预约成功 | 服务编码存在、权益码有效、订单不存在 | type=有效服务编码, request=有效加密参数, channel=12 | code=0, 返回url、tranChnl、instType、backUrl |
|
||
| TC-3.1.1-002 | 必填参数缺失-type | - | 不传type | code=2, msg="参数错误" |
|
||
| TC-3.1.1-003 | 服务编码不存在 | 数据库无该服务编码映射 | type=999999 | code=4, msg="暂不支持此服务"(在AES解密前返回) |
|
||
| TC-3.1.1-004 | AES解密失败-密钥不匹配 | 服务编码存在但request用其他密钥加密 | type=有效服务编码, request=用错误密钥加密 | code=2, msg="参数错误" |
|
||
| TC-3.1.1-005 | AES解密失败-格式错误 | 服务编码存在 | type=有效服务编码, request=无效加密字符串 | code=2, msg="参数错误" |
|
||
| TC-3.1.1-006 | 参数解析失败-解密后缺少type | 服务编码存在,AES解密成功 | request解密后无type字段 | code=2, msg="参数错误" |
|
||
| TC-3.1.1-007 | 参数解析失败-解密后缺少code | 服务编码存在,AES解密成功 | request解密后无code字段 | code=2, msg="参数错误" |
|
||
| TC-3.1.1-008 | 幂等-已预约状态 | 订单状态=200(已预约) | 相同权益码再次请求 | code=0, 返回原预约成功响应 |
|
||
| TC-3.1.1-009 | 幂等-未预约状态 | 订单状态=100(未预约) | 相同权益码再次请求 | 继续执行流程,最终返回预约结果 |
|
||
| TC-3.1.1-010 | 幂等-已完成状态 | 订单状态=300(已完成) | 相同权益码再次请求 | code=4, msg="服务已生效" |
|
||
| TC-3.1.1-011 | 幂等-已取消状态 | 订单状态=400(已取消) | 相同权益码再次请求 | code=4, msg="服务已取消" |
|
||
| TC-3.1.1-011a | 幂等-已过期状态 | 订单状态=500(已过期) | 相同权益码再次请求 | code=4, msg="服务已过期" |
|
||
| TC-3.1.1-012 | 权益码过期-CRM渠道 | 邮储返回权益码已过期 | channel=41 | code=4, msg含"二维码20分钟内有效" |
|
||
| TC-3.1.1-013 | 权益码过期-手机银行 | 邮储返回权益码已过期 | channel=12 | code=4, msg含"当前页面停置时间过长" |
|
||
| TC-3.1.1-014 | 权益码过期-电话银行 | 邮储返回权益码已过期 | channel=17 | code=4, msg含"当前页面停置时间过长" |
|
||
| TC-3.1.1-015 | 邮储预约成功 | 权益码有效 | 正常请求 | 继续调用蓝色兄弟获取券码 |
|
||
| TC-3.1.1-016 | 邮储返回已预约(161010) | 权益码有效 | 正常请求 | 继续调用蓝色兄弟获取券码 |
|
||
| TC-3.1.1-017 | 邮储预约失败 | 邮储返回其他错误 | 正常请求 | code!=0, 订单状态=100 |
|
||
| TC-3.1.1-018 | 券码获取成功 | 邮储预约成功 | 正常请求 | code=0, 订单状态=200, 返回url |
|
||
| TC-3.1.1-019 | 券码获取失败 | 蓝色兄弟返回异常 | 正常请求 | code!=0, 订单状态=100 |
|
||
| TC-3.1.1-020 | 券码获取超时 | 蓝色兄弟接口超时 | 正常请求 | code!=0, 订单状态=100 |
|
||
| TC-3.1.1-021 | backUrl为空 | backUrl参数未传 | backUrl=空 | code=0, 响应中backUrl为空 |
|
||
| TC-3.1.1-022 | 必填参数缺失-channel | - | 不传channel | code=2, msg="参数错误" |
|
||
| TC-3.1.1-023 | 必填参数缺失-tranChnl | - | 不传tranChnl | code=2, msg="参数错误" |
|
||
| TC-3.1.1-024 | 必填参数缺失-instType | - | 不传instType | code=2, msg="参数错误" |
|
||
| TC-3.1.1-025 | 邮储服务不可用 | 邮储平台异常 | 正常请求 | code=1, msg="系统异常" |
|
||
| TC-3.1.1-026 | 蓝色兄弟服务不可用 | 蓝色兄弟平台异常 | 正常请求 | code=1, 订单状态=100 |
|
||
| TC-3.1.1-027 | 并发幂等测试 | 同一权益码 | 同时发起多个请求 | 仅一个成功创建订单,其他返回幂等结果 |
|
||
| TC-3.1.1-028 | 并发锁竞争-获取锁失败 | 同一权益码并发请求 | 第二个请求 | code=1, msg="请勿重复提交" |
|
||
| TC-3.1.1-029 | 不同服务编码使用不同密钥 | 数据库存在多个服务编码配置 | type=服务A, request=用服务A密钥加密 | code=0, 使用服务A的aes_key/aes_iv解密成功 |
|
||
|
||
---
|
||
|
||
#### 3.1.2 服务取消接口
|
||
|
||
**功能描述**:接收邮储银行服务开放平台的取消请求,取消已预约的服务
|
||
|
||
**业务规则**:
|
||
1. 对request进行AES解密,解析出type(服务编码)、code(权益码)、mac(客户id)
|
||
2. 基于权益码(code)获取分布式锁,防止重复请求:
|
||
- 获取锁成功:继续执行后续流程
|
||
- 获取锁失败:返回"请勿重复提交"
|
||
3. 检查订单状态必须是已预约状态才能取消:
|
||
- 如果是已取消状态,直接返回取消成功
|
||
- 如果是已过期状态,返回"服务已过期"
|
||
- 其他非已预约状态,提示"服务已生效无法取消"
|
||
4. 调用高端客户权益积分预约服务状态查询接口查询状态:
|
||
- 如果不是已预约状态且不是已取消状态,提示"服务已生效,无法取消"
|
||
- 如果是已取消状态,直接返回取消成功
|
||
5. 调用蓝色兄弟作废接口发起作废:
|
||
- 只有当业务码返回作废成功才算成功
|
||
- 其他情况(如HTTP响应超时)均视为作废失败
|
||
- 作废失败后调用蓝色兄弟券码查询接口查询券码状态,如果是已作废则按作废成功处理,否则提示"服务取消失败,请重试"
|
||
6. 调用邮储接口发起预约取消,业务码明确返回取消成功才算成功,否则提示"服务取消失败"
|
||
7. 订单状态更新为"已取消"(400)
|
||
8. 释放分布式锁
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| type | String | M | 服务编码,用于查询数据库获取AES解密密钥 |
|
||
| request | String | M | AES加密字符串,解密后格式:type=服务编码&code=权益码&mac=加密后的客户id |
|
||
| channel | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| tranChnl | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| backUrl | String | C | 返回手机银行的地址,可为空 |
|
||
| instType | String | M | 客户自营代理属性:01-自营,02-代理 |
|
||
| provinceInstNo | String | M | 客户归属一分机构号 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| tranChnl | String | M | 渠道标识 |
|
||
| instType | String | M | 客户自营代理属性 |
|
||
| backUrl | String | C | 返回手机银行的地址 |
|
||
|
||
**验收标准**:
|
||
- [ ] 入参type(服务编码)为必填字段,缺失时返回“参数错误”
|
||
- [ ] 根据入参type查询数据库获取对应的aes_key和aes_iv
|
||
- [ ] 服务编码(type)不存在时,返回“暂不支持此服务”(在AES解密之前校验)
|
||
- [ ] 使用数据库查询到的aes_key和aes_iv能正确解密AES加密的request参数
|
||
- [ ] 正确解析AES加密的request参数,提取type、code、mac字段
|
||
- [ ] 本地订单状态为已取消时,直接返回取消成功
|
||
- [ ] 本地订单状态为已过期时,返回"服务已过期"
|
||
- [ ] 本地订单状态非已预约且非已取消且非已过期时,返回"服务已生效无法取消"
|
||
- [ ] 调用邮储预约服务状态查询接口,非已预约且非已取消状态时返回"服务已生效,无法取消"
|
||
- [ ] 调用邮储预约服务状态查询接口,已取消状态时直接返回取消成功
|
||
- [ ] 蓝色兄弟作废接口返回作废成功时正常处理
|
||
- [ ] 蓝色兄弟作废接口超时或失败后,查询券码状态为已作废时按成功处理
|
||
- [ ] 蓝色兄弟作废接口失败且券码状态非已作废时返回"服务取消失败,请重试"
|
||
- [ ] 邮储预约取消接口返回成功时正常处理
|
||
- [ ] 邮储预约取消接口返回失败时提示"服务取消失败"
|
||
- [ ] 取消成功后订单状态更新为400
|
||
- [ ] 并发请求时,基于权益码获取分布式锁,获取失败返回"请勿重复提交"
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.1.2-001 | 正常取消成功 | 订单状态=已预约(200),邮储状态=已预约,蓝色兄弟作废成功,邮储取消成功 | request=有效加密参数 | code=0, 订单状态=400 |
|
||
| TC-3.1.2-002 | AES解密失败 | 服务编码存在 | type=有效服务编码, request=无效加密字符串 | code=2, msg="参数错误" |
|
||
| TC-3.1.2-002a | 必填参数缺失-type | - | 不传type | code=2, msg="参数错误" |
|
||
| TC-3.1.2-002b | 服务编码不存在 | 数据库无该服务编码映射 | type=999999 | code=4, msg="暂不支持此服务" |
|
||
| TC-3.1.2-003 | 本地订单状态已取消 | 订单状态=已取消(400) | request=有效加密参数 | code=0, 直接返回取消成功 |
|
||
| TC-3.1.2-004 | 本地订单状态非已预约 | 订单状态=已完成(300) | request=有效加密参数 | code=4, msg="服务已生效无法取消" |
|
||
| TC-3.1.2-004a | 本地订单状态已过期 | 订单状态=已过期(500) | request=有效加密参数 | code=4, msg="服务已过期" |
|
||
| TC-3.1.2-005 | 本地订单不存在 | 订单不存在 | request=有效加密参数 | code=1, msg="订单不存在" |
|
||
| TC-3.1.2-006 | 邮储查询状态-已取消 | 订单状态=已预约(200),邮储状态=已取消 | request=有效加密参数 | code=0, 直接返回取消成功 |
|
||
| TC-3.1.2-007 | 邮储查询状态-已生效 | 订单状态=已预约(200),邮储状态=已生效 | request=有效加密参数 | code=1, msg="服务已生效,无法取消" |
|
||
| TC-3.1.2-008 | 蓝色兄弟作废成功 | 邮储状态=已预约,蓝色兄弟作废返回成功 | request=有效加密参数 | 继续执行邮储取消流程 |
|
||
| TC-3.1.2-009 | 蓝色兄弟作废超时后查询已作废 | 蓝色兄弟作废超时,券码查询状态=已作废(3) | request=有效加密参数 | 按作废成功处理,继续执行 |
|
||
| TC-3.1.2-010 | 蓝色兄弟作废失败后查询已作废 | 蓝色兄弟作废返回失败,券码查询状态=已作废(3) | request=有效加密参数 | 按作废成功处理,继续执行 |
|
||
| TC-3.1.2-011 | 蓝色兄弟作废失败且券码未作废 | 蓝色兄弟作废失败,券码查询状态=未作废 | request=有效加密参数 | code=1, msg="服务取消失败,请重试" |
|
||
| TC-3.1.2-012 | 邮储预约取消成功 | 蓝色兄弟作废成功,邮储取消返回成功 | request=有效加密参数 | code=0, 订单状态=400 |
|
||
| TC-3.1.2-013 | 邮储预约取消失败 | 蓝色兄弟作废成功,邮储取消返回失败 | request=有效加密参数 | code=1, msg="服务取消失败" |
|
||
| TC-3.1.2-014 | 邮储预约取消超时 | 蓝色兄弟作废成功,邮储取消超时 | request=有效加密参数 | code=1, msg="服务取消失败" |
|
||
| TC-3.1.2-015 | 幂等性测试-已取消订单 | 订单状态=已取消(400) | 重复发起取消请求 | code=0, 直接返回取消成功 |
|
||
| TC-3.1.2-016 | 并发锁竞争-获取锁失败 | 同一权益码并发请求 | 第二个请求 | code=1, msg="请勿重复提交" |
|
||
|
||
---
|
||
|
||
#### 3.1.3 服务完成通知接口
|
||
|
||
**功能描述**:接收蓝色兄弟券码核销回调,主动通知邮储银行服务完成
|
||
|
||
**业务规则**:
|
||
1. 接收蓝色兄弟券码状态变更回调
|
||
2. 当券码状态变为"已核销"(2)时
|
||
3. 调用邮储银行服务完成接口
|
||
4. 更新订单状态为"已完成"(300)
|
||
5. 服务完成状态更新需在T+2日内完成
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| rightsCode | String | M | 兑换预约码 |
|
||
| serviceType | String | M | 服务类型编码 |
|
||
| providerCode | String | M | 服务厂商编号 |
|
||
| completionTime | String | M | 实际完成时间,格式:yyyyMMddHHmmss |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| - | - | - | 无业务数据,仅返回公共响应 |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确接收蓝色兄弟回调通知
|
||
- [ ] 回调验签通过后正确响应"ok"
|
||
- [ ] 服务完成通知在T+2日内发送
|
||
- [ ] 已取消订单不允许完成(161014)
|
||
- [ ] 完成成功后订单状态为300
|
||
|
||
---
|
||
|
||
#### 3.1.4 订单过期积分查询接口
|
||
|
||
**功能描述**:查询订单退还时已过期的幸福点信息,用于取消前提醒客户
|
||
|
||
**业务规则**:
|
||
1. 验证服务编码(type),查询数据库获取AES解密密钥
|
||
2. 服务编码不存在返回“暂不支持此服务”
|
||
3. 解密request参数获取服务编码、权益码、客户ID
|
||
4. 调用邮储「高端客户权益订单退还时已过期积分查询」接口
|
||
5. 返回邮储接口查询结果(总幸福点、过期幸福点、提醒信息)
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| type | String | M | 服务编码,用于查询数据库获取AES解密密钥 |
|
||
| request | String | M | AES加密字符串,解密后格式:type=服务编码&code=权益码&mac=加密后的客户id |
|
||
| channel | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| tranChnl | String | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| backUrl | String | C | 返回手机银行的地址,可为空 |
|
||
| instType | String | M | 客户自营代理属性:01-自营,02-代理 |
|
||
| provinceInstNo | String | M | 客户归属一分机构号 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| tranIntglNum | int | C | 交易总幸福点 |
|
||
| ovdueIntglNum | int | C | 已过期的幸福点 |
|
||
| noticeMsg | String | C | 提醒信息文本 |
|
||
|
||
**验收标准**:
|
||
- [ ] 入参type(服务编码)为必填字段,缺失时返回“参数错误”
|
||
- [ ] 根据入参type查询数据库获取对应的aes_key和aes_iv
|
||
- [ ] 服务编码(type)不存在时,返回“暂不支持此服务”(在AES解密之前校验)
|
||
- [ ] 使用数据库查询到的aes_key和aes_iv能正确解密AES加密的request参数
|
||
- [ ] 调用邮储过期积分查询接口成功时,正确返回查询结果
|
||
- [ ] 调用邮储过期积分查询接口失败时,返回错误提示
|
||
- [ ] 调用邮储过期积分查询接口超时时,返回“查询失败,请重试”
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.1.4-001 | 正常查询成功 | 邮储接口返回成功 | type=有效服务编码, request=有效加密参数 | code=0, 返回tranIntglNum、ovdueIntglNum、noticeMsg |
|
||
| TC-3.1.4-002 | 必填参数缺失-type | - | 不传type | code=2, msg="参数错误" |
|
||
| TC-3.1.4-003 | 服务编码不存在 | 数据库无该服务编码映射 | type=999999 | code=4, msg="暂不支持此服务" |
|
||
| TC-3.1.4-004 | AES解密失败 | 服务编码存在 | type=有效服务编码, request=无效加密字符串 | code=2, msg="参数错误" |
|
||
| TC-3.1.4-005 | 邮储接口返回失败 | AES解密成功,邮储接口返回失败 | type=有效服务编码, request=有效加密参数 | code=1, msg=邮储返回的错误信息 |
|
||
| TC-3.1.4-006 | 邮储接口调用超时 | AES解密成功,邮储接口超时5s | type=有效服务编码, request=有效加密参数 | code=1, msg="查询失败,请重试" |
|
||
| TC-3.1.4-007 | 无过期积分 | 邮储接口返回ovdueIntglNum=0 | type=有效服务编码, request=有效加密参数 | code=0, ovdueIntglNum=0 |
|
||
|
||
---
|
||
|
||
#### 3.1.5 服务状态查询接口(内部接口)
|
||
|
||
**功能描述**:调用邮储「高端客户权益积分预约服务状态查询接口」,根据权益码查询邮储侧的服务预约状态。用于服务取消、服务预约等流程中验证邮储侧订单状态。
|
||
|
||
**说明**:此接口为内部调用邮储接口,非对外提供的接口。
|
||
|
||
**业务规则**:
|
||
1. 根据权益码查询订单
|
||
2. 返回当前服务状态
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| rightsCode | String | M | 兑换权益码 |
|
||
| tranChnl | String | M | 渠道标识 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| serviceState | String | M | 预约服务状态码:100-未预约,200-已预约,300-已完成,400-已取消,500-已过期 |
|
||
| serviceStateMsg | String | M | 预约服务状态描述 |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确查询订单状态
|
||
- [ ] 状态码与状态描述一致
|
||
|
||
---
|
||
|
||
#### 3.1.6 服务详情查询接口
|
||
|
||
**功能描述**:提供给邮储银行跳转服务详情页面,根据参数获取上游券码链接展示服务详情
|
||
|
||
**业务规则**:
|
||
1. 验证服务编码(type),查询数据库获取AES解密密钥
|
||
2. 服务编码不存在返回“暂不支持此服务”
|
||
3. 解密request参数获取服务编码、权益码、客户ID
|
||
4. 根据权益码查询订单获取券码链接
|
||
5. 返回券码链接用于页面展示
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| type | String | M | 服务编码,用于查询数据库获取AES解密密钥 |
|
||
| request | String | M | AES加密字符串,解密后格式:type=服务编码&code=权益码&mac=加密后的客户id |
|
||
| channel | String | M | 渠道标识:12-手机银行 17-电话银行 41-CRM零售 |
|
||
| tranChnl | String | M | 交易渠道:12-手机银行 17-电话银行 41-CRM零售 |
|
||
| backUrl | String | M | 返回手机银行的地址,用于客户返回操作 |
|
||
| instType | String | O | 机构类型:01-自营 02-代理(积分系统计划2026年0107上线) |
|
||
| provinceInstNo | String | O | 客户归属一分机构号(积分系统计划2026年0107上线) |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| codeUrl | String | M | 券码链接,用于展示服务详情 |
|
||
| backUrl | String | M | 返回手机银行的地址 |
|
||
|
||
**验收标准**:
|
||
- [ ] 入参type(服务编码)为必填字段,缺失时返回“参数错误”
|
||
- [ ] 根据入参type查询数据库获取对应的aes_key和aes_iv
|
||
- [ ] 服务编码(type)不存在时,返回“暂不支持此服务”(在AES解密之前校验)
|
||
- [ ] 使用数据库查询到的aes_key和aes_iv能正确解密AES加密的request参数
|
||
- [ ] 能正确查询订单获取券码链接
|
||
- [ ] 权益码不存在时返回错误提示
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.1.6-001 | 正常查询成功 | 订单存在且有券码链接 | type=有效服务编码, request=有效加密参数 | code=0, 返回codeUrl和backUrl |
|
||
| TC-3.1.6-002 | 必填参数缺失-type | - | 不传type | code=2, msg="参数错误" |
|
||
| TC-3.1.6-003 | 服务编码不存在 | 数据库无该服务编码映射 | type=999999 | code=4, msg="暂不支持此服务" |
|
||
| TC-3.1.6-004 | AES解密失败 | 服务编码存在 | type=有效服务编码, request=无效加密字符串 | code=2, msg="参数错误" |
|
||
| TC-3.1.6-005 | 权益码不存在 | AES解密成功,订单不存在 | request解密后code不存在 | code=1, msg="订单不存在" |
|
||
|
||
---
|
||
|
||
### 3.2 券码管理模块
|
||
|
||
#### 3.2.1 券码获取功能
|
||
|
||
**功能描述**:调用蓝色兄弟API获取虚拟商品券码
|
||
|
||
**业务规则**:
|
||
1. 生成唯一外部业务号(out_biz_no)
|
||
2. 构造请求参数并AES加密
|
||
3. 使用RSA私钥签名
|
||
4. 调用获取券码接口
|
||
5. 保存券码信息与订单关联
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| out_biz_no | String | M | 外部业务号,长度2~32位,幂等 |
|
||
| activity_no | String | M | 活动编号,长度32位内 |
|
||
| number | int | M | 数量,只支持1 |
|
||
| account | String | N | 账号 |
|
||
| notify_url | String | N | 回调通知地址 |
|
||
|
||
**输出**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| out_biz_no | String | M | 外部业务号 |
|
||
| trade_no | String | M | 交易号 |
|
||
| key | String | N | key码 |
|
||
| url | String | N | 短链接 |
|
||
| status | uint8 | M | 状态:1-正常,2-已核销,3-已作废 |
|
||
| valid_begin_time | String | M | key码有效期开始 |
|
||
| valid_end_time | String | M | key码有效期结束 |
|
||
| usable_num | uint32 | M | 可兑换次数 |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确加密业务参数(AES)
|
||
- [ ] 能正确签名请求(RSA)
|
||
- [ ] 幂等请求返回相同结果
|
||
- [ ] 获取成功后保存券码信息
|
||
|
||
---
|
||
|
||
#### 3.2.2 券码查询功能
|
||
|
||
**功能描述**:查询已获取券码的当前状态
|
||
|
||
**业务规则**:
|
||
1. 支持通过外部业务号或交易号查询
|
||
2. 返回券码完整状态信息
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| out_biz_no | String | C | 外部业务号,与trade_no二选一 |
|
||
| trade_no | String | C | 交易号,优先使用 |
|
||
|
||
**输出**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| status | uint8 | M | 状态:1-正常,2-已核销,3-已作废,4-已过期 |
|
||
| usage_num | uint32 | M | 已兑换次数 |
|
||
| usage_time | String | N | 最后一次核销时间 |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确查询券码状态
|
||
- [ ] 状态信息完整准确
|
||
|
||
---
|
||
|
||
#### 3.2.3 券码作废功能
|
||
|
||
**功能描述**:作废待使用或已过期的券码
|
||
|
||
**业务规则**:
|
||
1. 只能作废待使用(1)、已过期(4)状态的券码
|
||
2. 已核销券码不允许作废
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| out_biz_no | String | C | 外部业务号,与trade_no二选一 |
|
||
| trade_no | String | C | 交易号,优先使用 |
|
||
|
||
**验收标准**:
|
||
- [ ] 正常状态券码能成功作废
|
||
- [ ] 已核销券码作废返回错误
|
||
- [ ] 作废成功后券码状态为3
|
||
|
||
---
|
||
|
||
#### 3.2.4 券码状态回调接收
|
||
|
||
**功能描述**:接收蓝色兄弟的券码状态变更通知
|
||
|
||
**业务规则**:
|
||
1. 验证回调签名
|
||
2. 解析回调数据
|
||
3. 更新本地券码状态
|
||
4. 当status=2(已核销)时触发服务完成通知
|
||
5. 响应httpCode=200和字符串"ok"
|
||
|
||
**回调重试策略**:
|
||
- 首次间隔120s
|
||
- 第二次间隔240s
|
||
- 第三次间隔360s
|
||
- 大于5分钟后间隔5分钟
|
||
- 大于10分钟后间隔10分钟
|
||
- 超过120分钟后不再重试
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确验证回调签名
|
||
- [ ] 状态更新及时准确
|
||
- [ ] 核销状态触发服务完成通知
|
||
- [ ] 响应格式正确(httpCode=200, body="ok")
|
||
|
||
---
|
||
|
||
### 3.3 订单管理模块
|
||
|
||
#### 3.3.1 订单创建
|
||
|
||
**功能描述**:创建权益服务订单
|
||
|
||
**业务规则**:
|
||
1. 生成唯一订单号
|
||
2. 关联权益码、券码、客户信息
|
||
3. 初始状态为"服务未预约"(100),预约成功后更新为"服务已预约"(200)
|
||
|
||
**验收标准**:
|
||
- [ ] 订单号全局唯一
|
||
- [ ] 订单信息完整
|
||
|
||
---
|
||
|
||
#### 3.3.2 订单状态管理
|
||
|
||
**功能描述**:管理订单全生命周期状态流转
|
||
|
||
**状态定义**:
|
||
| 状态码 | 状态名称 | 说明 |
|
||
|-------|---------|------|
|
||
| 100 | 服务未预约 | 已兑换但未预约 |
|
||
| 200 | 服务已预约 | 已预约待使用 |
|
||
| 300 | 服务已完成 | 券码已核销 |
|
||
| 400 | 服务已取消 | 用户主动取消 |
|
||
| 500 | 服务已过期 | 超过90天未预约 |
|
||
|
||
**状态流转规则**:
|
||
- 200(已预约) → 300(已完成):券码核销
|
||
- 200(已预约) → 400(已取消):用户取消
|
||
- 300(已完成) 和 400(已取消) 为终态,不可变更
|
||
|
||
**验收标准**:
|
||
- [ ] 状态流转符合规则
|
||
- [ ] 终态不可变更
|
||
- [ ] 状态变更有日志记录
|
||
|
||
---
|
||
|
||
#### 3.3.3 订单查询
|
||
|
||
**功能描述**:支持多维度订单查询
|
||
|
||
**查询维度**:
|
||
- 按权益码查询
|
||
- 按订单号查询
|
||
- 按客户信息查询
|
||
- 按状态查询
|
||
- 按时间范围查询
|
||
|
||
**验收标准**:
|
||
- [ ] 支持所有查询维度
|
||
- [ ] 查询结果准确
|
||
|
||
---
|
||
|
||
### 3.4 对账管理模块
|
||
|
||
#### 3.4.1 对账文件查询
|
||
|
||
**功能描述**:查询邮储银行生成的对账文件列表
|
||
|
||
**业务规则**:
|
||
1. 每月3号查询上月对账文件
|
||
2. 只包含服务完成(300)状态的订单
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| accountingDate | String | M | 会计日期,YYYYMMDD |
|
||
| fileIntfcName | String | M | 文件接口名 |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确查询对账文件列表
|
||
- [ ] 返回文件ID、名称等完整信息
|
||
|
||
---
|
||
|
||
#### 3.4.2 对账文件下载
|
||
|
||
**功能描述**:下载对账文件内容
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| fileId | String | M | 文件唯一标识 |
|
||
| fileIntfcName | String | M | 文件接口名 |
|
||
| sm4Key | String | M | 对账文件SM4加密密钥 |
|
||
|
||
**对账文件内容**:
|
||
| 字段 | 说明 |
|
||
|-----|------|
|
||
| 统计月份 | YYYYMMDD |
|
||
| 一分机构序号 | - |
|
||
| 一分机构名称 | - |
|
||
| 网点机构属性 | 01-自营,02-代理 |
|
||
| 积分客户服务编码 | - |
|
||
| 服务内容 | - |
|
||
| 预约时间 | - |
|
||
| 实际完成时间 | - |
|
||
| 权益兑换码 | - |
|
||
|
||
**验收标准**:
|
||
- [ ] 能正确解密对账文件
|
||
- [ ] 能解析对账文件内容
|
||
- [ ] 与本地订单数据核对
|
||
|
||
---
|
||
|
||
#### 3.4.3 对账文件查询接口
|
||
|
||
**功能描述**:查询可用的对账文件列表,用于管理员或运营人员获取本地处理后的对账文件信息
|
||
|
||
**接口信息**:
|
||
- 请求方式:POST
|
||
- 接口路径:/api/v1/reconciliation/files
|
||
|
||
**业务规则**:
|
||
1. 每月3号生成上月服务状态为「服务已完成(300)」的权益订单对账文件
|
||
2. 对账月份规则:服务完成时间所在月份为对账月份
|
||
- 例如:服务完成时间 202512210000,对账月份为 2025年12月,对账文件在 2026年1月3日生成
|
||
3. 对账文件名称格式:`RIGHTS_SERVICE_CHK_{providerCode}`
|
||
- 例如:`RIGHTS_SERVICE_CHK_A101`
|
||
4. 返回文件ID、文件名称等信息
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 长度 | 必填 | 说明 |
|
||
|-----|------|-----|-----|------|
|
||
| accountingDate | String | 8 | M | 会计日期,格式:YYYYMMDD,例如:20251201 |
|
||
| fileIntfcName | String | 64 | M | 文件接口名,固定值,如:RIGHTS_SERVICE_CHK_A101 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| fileList | Object[] | M | 对账文件列表 |
|
||
| fileList[].fileId | String | M | 文件唯一标识,用于下载接口 |
|
||
| fileList[].fileName | String | M | 文件名称 |
|
||
| fileList[].fileSize | long | M | 文件大小(字节) |
|
||
| fileList[].createTime | String | M | 文件创建时间 yyyyMMddHHmmss |
|
||
|
||
**验收标准**:
|
||
- [ ] POST请求能正确查询对账文件列表
|
||
- [ ] accountingDate参数校验:格式必须为YYYYMMDD
|
||
- [ ] fileIntfcName参数校验:必须为有效的文件接口名
|
||
- [ ] 返回文件ID、文件名称等完整信息
|
||
- [ ] 对账月份不存在数据时返回空列表
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.4.3-001 | 正常查询对账文件 | 2025年12月有已完成订单 | accountingDate=20251201, fileIntfcName=RIGHTS_SERVICE_CHK_A101 | code=0, 返回文件列表 |
|
||
| TC-3.4.3-002 | 会计日期格式错误 | - | accountingDate=2025-12-01 | code=2, msg="参数错误" |
|
||
| TC-3.4.3-003 | 文件接口名不存在 | - | fileIntfcName=INVALID_NAME | code=4, msg="文件接口名不存在" |
|
||
| TC-3.4.3-004 | 对账月份无数据 | 2025年11月无已完成订单 | accountingDate=20251101 | code=0, fileList=[] |
|
||
| TC-3.4.3-005 | 缺少必填参数 | - | 不传accountingDate | code=2, msg="参数错误" |
|
||
|
||
---
|
||
|
||
#### 3.4.4 对账文件下载接口
|
||
|
||
**功能描述**:根据文件ID下载对账文件,用于管理员或运营人员获取具体的对账文件内容
|
||
|
||
**接口信息**:
|
||
- 请求方式:POST
|
||
- 接口路径:/api/v1/reconciliation/download
|
||
|
||
**业务规则**:
|
||
1. 根据文件ID和文件接口名查询对账文件
|
||
2. 验证下载密码,密码错误拒绝下载
|
||
3. 文件格式为CSV,编码UTF-8-BOM(兼容Excel中文显示)
|
||
4. 直接返回文件流
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 长度 | 必填 | 说明 |
|
||
|-----|------|-----|-----|------|
|
||
| fileId | String | 32 | M | 文件唯一标识,从查询接口获取 |
|
||
| fileIntfcName | String | 64 | M | 文件接口名,固定值,如:RIGHTS_SERVICE_CHK_A101 |
|
||
| password | String | 32 | M | 下载密码,用于验证下载权限 |
|
||
|
||
**输出**:
|
||
直接返回文件流,Content-Type: text/csv,Content-Disposition: attachment; filename="RIGHTS_SERVICE_CHK_A101_202512.csv"
|
||
|
||
**对账文件内容字段**:
|
||
| 序号 | 字段名 | 说明 |
|
||
|-----|-------|------|
|
||
| 1 | 统计月份 | YYYYMM |
|
||
| 2 | 一分机构序号 | province_inst_no |
|
||
| 3 | 一分机构名称 | 根据机构号映射 |
|
||
| 4 | 网点机构属性 | 01-自营,02-代理 |
|
||
| 5 | 积分客户服务编码 | type字段 |
|
||
| 6 | 服务内容 | 服务名称 |
|
||
| 7 | 预约时间 | appointment_time,格式:yyyyMMddHHmmss |
|
||
| 8 | 实际完成时间 | key_usage_time,格式:yyyyMMddHHmmss |
|
||
| 9 | 权益兑换码 | code字段 |
|
||
| 10 | 订单号 | order_no |
|
||
| 11 | 券码状态 | key_status:1-正常,2-已核销,3-已作废,4-已过期 |
|
||
|
||
**验收标准**:
|
||
- [ ] POST请求能正确下载对账文件
|
||
- [ ] fileId、fileIntfcName、password都为必填参数
|
||
- [ ] 密码验证失败时返回错误提示
|
||
- [ ] 文件ID不存在时返回错误提示
|
||
- [ ] 文件名格式正确:RIGHTS_SERVICE_CHK_{providerCode}_{reconMonth}.csv
|
||
- [ ] 文件内容编码为UTF-8-BOM(兼容Excel中文显示)
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.4.4-001 | 正常下载对账文件 | 文件存在,密码正确 | fileId=有效ID, fileIntfcName=RIGHTS_SERVICE_CHK_A101, password=正确密码 | 返回CSV文件流,文件名正确 |
|
||
| TC-3.4.4-002 | 密码错误 | 文件存在 | fileId=有效ID, password=错误密码 | code=3, msg="密码错误" |
|
||
| TC-3.4.4-003 | 文件ID不存在 | - | fileId=无效ID | code=4, msg="文件不存在" |
|
||
| TC-3.4.4-004 | 文件ID为空 | - | fileId= | code=2, msg="参数错误" |
|
||
| TC-3.4.4-005 | 缺少password参数 | - | 不传password | code=2, msg="参数错误" |
|
||
|
||
---
|
||
|
||
#### 3.4.5 批量补推接口
|
||
|
||
**功能描述**:手动批量触发服务完成通知,用于处理蓝色兄弟已核销但邮储银行未收到服务完成通知的订单
|
||
|
||
**接口信息**:
|
||
- 请求方式:POST
|
||
- 接口路径:/api/v1/reconciliation/batch-repush
|
||
|
||
**业务规则**:
|
||
1. 查询本地订单状态为「服务已预约(200)」且券码状态为「已核销(2)」的订单
|
||
2. 批量创建服务完成通知任务(task_type=1)
|
||
3. 支持按时间范围、权益码列表筛选
|
||
4. 单次补推数量限制:最多100笔
|
||
5. 幂等处理:已存在相同类型的待处理任务时跳过
|
||
|
||
**输入**:
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| codes | String[] | C | 权益码列表,最多100个,与时间范围二选一 |
|
||
| startTime | String | C | 开始时间,格式:yyyyMMddHHmmss,与codes二选一 |
|
||
| endTime | String | C | 结束时间,格式:yyyyMMddHHmmss,与codes二选一 |
|
||
| dryRun | boolean | C | 是否试运行,默认false。true时只返回待补推订单列表,不实际创建任务 |
|
||
|
||
**输出**(data字段内容):
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|-----|------|-----|------|
|
||
| totalCount | int | M | 符合条件的订单总数 |
|
||
| createdCount | int | M | 新创建的任务数(dryRun=true时为0) |
|
||
| skippedCount | int | M | 跳过的订单数(已有待处理任务) |
|
||
| orders | Object[] | C | 订单列表(dryRun=true时返回) |
|
||
| orders[].orderNo | String | M | 订单号 |
|
||
| orders[].code | String | M | 权益码 |
|
||
| orders[].status | int | M | 订单状态 |
|
||
| orders[].keyStatus | int | M | 券码状态 |
|
||
| orders[].keyUsageTime | String | C | 核销时间 |
|
||
| orders[].hasTask | boolean | M | 是否已有待处理任务 |
|
||
|
||
**验收标准**:
|
||
- [ ] 只处理本地status=200(已预约)且key_status=2(已核销)的订单
|
||
- [ ] 权益码列表和时间范围必须二选一
|
||
- [ ] 权益码列表最多100个,超过返回"单次补推数量不能超过100笔"
|
||
- [ ] 时间范围查询结果超过100笔时返回"符合条件的订单超过100笔,请缩小时间范围或使用权益码列表"
|
||
- [ ] 幂等处理:订单已有task_type=1且status!=2(已完成)的任务时跳过
|
||
- [ ] dryRun=true时只查询不创建任务
|
||
- [ ] 创建的任务trigger_source=2(主动查询/手动触发)
|
||
- [ ] 补推成功后返回创建的任务数和跳过的订单数
|
||
|
||
**测试用例**:
|
||
|
||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||
|---------|---------|---------|---------|----------|
|
||
| TC-3.4.4-001 | 按权益码批量补推 | 3笔订单status=200,key_status=2 | codes=["code1","code2","code3"] | code=0, createdCount=3 |
|
||
| TC-3.4.4-002 | 按时间范围批量补推 | 2笔订单符合条件 | startTime=20251201000000, endTime=20251231235959 | code=0, createdCount=2 |
|
||
| TC-3.4.4-003 | 试运行模式 | 2笔订单符合条件 | codes=["code1","code2"], dryRun=true | code=0, createdCount=0, orders返回2笔 |
|
||
| TC-3.4.4-004 | 权益码超过100个 | - | codes=[101个权益码] | code=2, msg="单次补推数量不能超过100笔" |
|
||
| TC-3.4.4-005 | 时间范围结果超100笔 | 150笔订单符合条件 | startTime/endTime | code=4, msg="符合条件的订单超过100笔" |
|
||
| TC-3.4.4-006 | 参数缺失 | - | 不传codes和时间范围 | code=2, msg="参数错误:权益码列表和时间范围必须二选一" |
|
||
| TC-3.4.4-007 | 幂等-已有待处理任务 | code1已有task_type=1,status=0的任务 | codes=["code1"] | code=0, createdCount=0, skippedCount=1 |
|
||
| TC-3.4.4-008 | 订单状态不符合 | 订单status=300(已完成) | codes=["code1"] | code=0, totalCount=0 |
|
||
| TC-3.4.4-009 | 券码状态不符合 | 订单key_status=1(正常) | codes=["code1"] | code=0, totalCount=0 |
|
||
| TC-3.4.4-010 | 混合场景 | 2笔符合,1笔已有任务,1笔状态不符 | codes=[4个权益码] | code=0, totalCount=2, createdCount=1, skippedCount=1 |
|
||
|
||
---
|
||
|
||
### 3.5 安全与加密模块
|
||
|
||
#### 3.5.1 邮储银行加解密(SM2/SM4/AES)
|
||
|
||
**功能描述**:实现与邮储银行通信的加解密
|
||
|
||
**服务预约请求AES解密规则**:
|
||
- 算法/模式/填充:AES/CBC/PKCS5Padding
|
||
- Key长度:16位
|
||
- IV长度:16位
|
||
- 编码方式:Base64
|
||
- 解密后格式:type=服务编码&code=权益码&mac=加密后的客户id
|
||
|
||
**服务开放平台SM4加密规则**:
|
||
1. 随机生成SM4 key
|
||
2. 使用SM4 key对请求报文加密(CBC模式)
|
||
3. 使用邮储银行公钥SM2加密SM4 key
|
||
|
||
**服务开放平台签名规则**:
|
||
1. 拼接:request + encryptKey + accessToken
|
||
2. 使用SM3计算摘要
|
||
3. 使用私钥SM2加密摘要
|
||
|
||
**验收标准**:
|
||
- [ ] AES解密正确(服务预约请求)
|
||
- [ ] SM4加解密正确
|
||
- [ ] SM2加解密正确
|
||
- [ ] SM3签名验签正确
|
||
|
||
---
|
||
|
||
#### 3.5.2 蓝色兄弟加解密(RSA/AES)
|
||
|
||
**功能描述**:实现与蓝色兄弟通信的加解密
|
||
|
||
**业务参数加密规则**:
|
||
1. 业务参数去掉"零"值
|
||
2. 按字母排序转成JSON字符串
|
||
3. 使用应用key进行AES加密
|
||
|
||
**签名规则**:
|
||
1. 拼接:appId + timestamp + ciphertext
|
||
2. 使用私钥RSA签名
|
||
|
||
**验收标准**:
|
||
- [ ] AES加解密正确
|
||
- [ ] RSA签名验签正确
|
||
- [ ] 回调验签正确
|
||
|
||
---
|
||
|
||
## 4. 数据需求
|
||
|
||
### 4.1 数据实体
|
||
|
||
#### 4.1.1 订单表(ycjfsc_order)
|
||
|
||
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|
||
|-------|------|-----|-----|------|
|
||
| id | bigint | 20 | M | 主键 |
|
||
| order_no | varchar | 32 | M | 系统内部订单号 |
|
||
| code | varchar | 32 | M | 权益码(邮储订单号) |
|
||
| out_trade_no | varchar | 32 | N | 请求上游营销平台的交易号 |
|
||
| partner_tx_sri_no | varchar | 24 | M | 请求邮储服务平台的流水号 |
|
||
| type | varchar | 6 | M | 服务编码 |
|
||
| provider_code | varchar | 4 | M | 服务商编号(邮储分配的固定值) |
|
||
| status | int | 3 | M | 内部订单状态:100未预约 200已预约 300已完成 400已取消 500已过期 |
|
||
| appointment_time | datetime | - | N | 预约成功时间 |
|
||
| mac | varchar | 40 | N | 加密后的客户id |
|
||
| channel | varchar | 4 | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| tran_chnl | varchar | 4 | M | 渠道标识:12-手机银行,17-电话银行,41-CRM零售 |
|
||
| back_url | varchar | 256 | N | 返回手机银行的地址 |
|
||
| inst_type | varchar | 2 | M | 客户自营代理属性:01-自营,02-代理 |
|
||
| province_inst_no | varchar | 20 | M | 客户归属一分机构号 |
|
||
| key_code | varchar | 64 | N | 券码 |
|
||
| url | varchar | 125 | N | 短链接 |
|
||
| key_status | int | 1 | N | 券码状态:0-待生成 1-正常,2-已核销,3-已作废,4-已过期 |
|
||
| key_issue_time | datetime | - | N | key码发放成功时间 |
|
||
| activity_no | varchar | 32 | N | 活动编号 |
|
||
| key_valid_begin_time | datetime | - | N | 券码有效期开始 |
|
||
| key_valid_end_time | datetime | - | N | 券码有效期结束 |
|
||
| key_usage_time | datetime | - | N | 核销时间 |
|
||
| key_discard_time | datetime | - | N | 作废时间 |
|
||
| update_time | datetime | - | M | 更新时间 |
|
||
| create_time | datetime | - | M | 创建时间 |
|
||
|
||
|
||
#### 4.1.3 通知任务表(ycjfsc_notify_task)
|
||
|
||
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|
||
|-------|------|-----|-----|------|
|
||
| id | bigint | 20 | M | 主键 |
|
||
| order_no | varchar | 32 | M | 关联订单号 |
|
||
| code | varchar | 32 | M | 权益码 |
|
||
| task_type | int | 1 | M | 任务类型:1-服务完成通知 2-过期处理 3-作废补偿 |
|
||
| trigger_source | int | 1 | M | 触发来源:1-回调通知 2-主动查询 |
|
||
| status | int | 1 | M | 任务状态:0-待执行 1-执行中 2-已完成 3-失败 |
|
||
| retry_count | int | 3 | M | 重试次数,默认0 |
|
||
| max_retry | int | 3 | M | 最大重试次数,默认8 |
|
||
| next_retry_time | datetime | - | N | 下次重试时间 |
|
||
| error_msg | varchar | 512 | N | 失败原因 |
|
||
| create_time | datetime | - | M | 创建时间 |
|
||
| update_time | datetime | - | M | 更新时间 |
|
||
|
||
**任务类型说明:**
|
||
|
||
| task_type | 说明 | 处理逻辑 |
|
||
|-----------|------|----------|
|
||
| 1 | 服务完成通知 | 调用邮储服务完成接口 → 订单状态改为300 |
|
||
| 2 | 过期处理 | 调用邮储预约取消接口 → 订单状态改为500 |
|
||
| 3 | 作废补偿 | 调用邮储预约取消接口 → 订单状态改为400 |
|
||
|
||
#### 4.1.4 对账记录表(ycjfsc_reconciliation)
|
||
|
||
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|
||
|-------|------|-----|-----|------|
|
||
| id | bigint | 20 | M | 主键 |
|
||
| recon_month | varchar | 6 | M | 对账月份YYYYMM |
|
||
| file_id | varchar | 32 | M | 文件ID |
|
||
| file_name | varchar | 128 | M | 文件名 |
|
||
| recon_status | int | 1 | M | 对账状态:0-待对账,1-已对账,2-有差异 |
|
||
| total_count | int | 10 | M | 总记录数 |
|
||
| match_count | int | 10 | M | 匹配记录数 |
|
||
| diff_count | int | 10 | M | 差异记录数 |
|
||
| create_time | datetime | - | M | 创建时间 |
|
||
| update_time | datetime | - | M | 更新时间 |
|
||
|
||
#### 4.1.5 服务编码映射表(ycjfsc_service_activity_mapping)
|
||
|
||
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|
||
|-------|------|-----|-----|------|
|
||
| id | bigint | 20 | M | 主键 |
|
||
| service_type | varchar | 6 | M | 邮储服务编码 |
|
||
| service_name | varchar | 64 | M | 服务名称 |
|
||
| activity_no | varchar | 32 | M | 营销平台活动编号 |
|
||
| activity_name | varchar | 64 | N | 活动名称 |
|
||
| aes_key | varchar | 32 | M | AES加密密钥(16位) |
|
||
| aes_iv | varchar | 32 | M | AES加密向量(16位) |
|
||
| create_time | datetime | - | M | 创建时间 |
|
||
| update_time | datetime | - | M | 更新时间 |
|
||
|
||
### 4.2 数据规则
|
||
|
||
1. **订单号生成规则(order_no)**:
|
||
- 格式:`{YYMMDDHHmmss}{machineId}{sequence}`
|
||
- 长度:20位
|
||
- 结构:
|
||
- 时间戳(12位):YYMMDDHHmmss,例如 `260313142530`
|
||
- 机器ID(2位):`01-99`,支持多实例部署
|
||
- 序列号(6位):`000001-999999`,每秒重置
|
||
- 示例:`26031314253001000001`
|
||
- 特点:按时间排序、可读性强、全局唯一
|
||
|
||
2. **外部业务号生成规则(out_biz_no)**:
|
||
- 用途:调用蓝色兄弟接口的幂等标识
|
||
- 格式:`{order_no}{service_type}`
|
||
- 长度:26位(在蓝色兄弟2~32位限制内)
|
||
- 结构:
|
||
- 订单号(20位):上述order_no
|
||
- 服务类型(6位):邮储服务编码,例如 `310001`
|
||
- 示例:`26031314253001000001310001`
|
||
- 特点:包含业务信息、可追溯、幂等
|
||
|
||
3. **合作方交易流水号生成规则(partner_tx_sri_no)**:
|
||
- 用途:调用邮储服务开放平台接口
|
||
- 格式:`{tranChnl}{YYYYMMDD}{sequence}`
|
||
- 长度:18位(邮储接口规范要求)
|
||
- 结构:
|
||
- 渠道号(2位):12-手机银行,17-电话银行,41-CRM零售
|
||
- 日期(8位):YYYYMMDD,例如 `20260313`
|
||
- 序列号(8位):`00000001-99999999`,每日重置
|
||
- 示例:`122026031300000001`
|
||
- 特点:符合邮储规范、包含渠道信息
|
||
3. **状态流转**:
|
||
- 100(未预约) → 200(已预约):预约成功
|
||
- 200(已预约) → 300(已完成):券码核销
|
||
- 200(已预约) → 400(已取消):用户取消
|
||
- 200(已预约) → 500(已过期):券码过期(根据上游券码状态决定)
|
||
4. **数据保留**:订单数据保留至少2年
|
||
|
||
---
|
||
|
||
## 5. 非功能性需求
|
||
|
||
### 5.1 性能要求
|
||
|
||
#### 5.1.1 响应时间要求
|
||
|
||
| 接口类型 | P95 | P99 | 说明 |
|
||
|---------|-----|-----|------|
|
||
| 服务预约接口 | < 300ms | < 500ms | 含上游券码获取 |
|
||
| 服务取消接口 | < 200ms | < 400ms | 含上游券码作废 |
|
||
| 服务状态查询接口 | < 100ms | < 200ms | 优先读缓存 |
|
||
| 券码状态回调接口 | < 100ms | < 200ms | 快速响应后异步处理 |
|
||
|
||
#### 5.1.2 并发处理能力
|
||
|
||
| 指标 | 要求 | 说明 |
|
||
|-----|------|------|
|
||
| 日常TPS | ≥ 100 | 正常业务峰值 |
|
||
| 峰值TPS | ≥ 500 | 活动期间峰值 |
|
||
| 单机QPS | ≥ 200 | 支持水平扩展 |
|
||
|
||
#### 5.1.3 缓存设计
|
||
|
||
**缓存策略**:
|
||
|
||
| 缓存对象 | 缓存类型 | 过期策略 | 更新策略 | 说明 |
|
||
|---------|---------|---------|---------|------|
|
||
| 服务编码映射表 | 本地缓存 + Redis | 本地5分钟,Redis 30分钟 | 配置变更主动刷新 | 高频读取,变更少 |
|
||
| 订单信息 | Redis | 24小时 | 状态变更时更新 | 按权益码缓存 |
|
||
| 券码信息 | Redis | 跟随订单 | 状态变更时更新 | 与订单关联存储 |
|
||
| 邮储AccessToken | Redis | 有效期前5分钟刷新 | 定时刷新 | 避免过期 |
|
||
|
||
**缓存Key设计**:
|
||
|
||
```
|
||
# 服务编码映射
|
||
ycjfsc:service:mapping:{serviceType}
|
||
|
||
# 订单缓存(按权益码)
|
||
ycjfsc:order:code:{rightsCode}
|
||
|
||
# 订单缓存(按订单号)
|
||
ycjfsc:order:no:{orderNo}
|
||
|
||
# AccessToken
|
||
ycjfsc:token:psbc
|
||
```
|
||
|
||
**缓存穿透防护**:
|
||
- 空值缓存:查询不存在的数据时缓存空值,过期时间60秒
|
||
- 布隆过滤器:权益码存在性预判(可选)
|
||
|
||
#### 5.1.4 高质量代码实现要求
|
||
|
||
1. **连接池管理**:HTTP客户端、数据库、Redis均需配置合理的连接池
|
||
2. **超时控制**:所有外部调用设置合理超时(连接超时3s,读超时10s)
|
||
3. **熔断降级**:上游服务异常时快速失败,避免雪崩
|
||
4. **异步处理**:非核心链路异步化(如日志记录、监控上报)
|
||
5. **批量操作**:对账等批量场景使用批量查询/更新
|
||
|
||
---
|
||
|
||
### 5.2 数据一致性要求
|
||
|
||
#### 5.2.1 核心一致性场景
|
||
|
||
**场景描述**:蓝色兄弟券码已核销(用户已完成充值兑换),必须通知邮储银行服务完成,否则会造成资金损失。
|
||
|
||
**风险点**:
|
||
- 回调通知邮储失败
|
||
- 回调成功但本地状态更新失败
|
||
- 系统宕机导致通知丢失
|
||
|
||
#### 5.2.2 一致性保障机制
|
||
|
||
**机制一:异步消息 + 最终一致**
|
||
|
||
```
|
||
1. 接收蓝色兄弟核销回调
|
||
2. 记录核销时间,创建通知任务(task_type=1)
|
||
3. 立即响应蓝色兄弟"ok"(快速响应,避免超时)
|
||
4. 异步处理:
|
||
- 调用邮储服务完成接口
|
||
- 成功:更新订单状态为「已完成」(300),任务状态为已完成(2)
|
||
- 失败:任务状态为失败(3),等待重试机制处理
|
||
```
|
||
|
||
**说明**:不使用本地事务,通过重试+补偿+对账三重机制保证最终一致性。订单状态统一使用100/200/300/400/500五个状态,通知处理过程通过通知任务表(ycjfsc_notify_task)进行管理。
|
||
|
||
**机制二:消息重试策略**
|
||
|
||
| 重试次数 | 间隔时间 | 累计时间 |
|
||
|---------|---------|----------|
|
||
| 第1次 | 10秒 | 10秒 |
|
||
| 第2次 | 30秒 | 40秒 |
|
||
| 第3次 | 1分钟 | 1分40秒 |
|
||
| 第4次 | 5分钟 | 6分40秒 |
|
||
| 第5次 | 10分钟 | 16分40秒 |
|
||
| 第6次 | 30分钟 | 46分40秒 |
|
||
| 第7次 | 1小时 | 1小时46分40秒 |
|
||
| 第8次 | 2小时 | 3小时46分40秒 |
|
||
| 第9次及以后 | 2小时 | 每2小时重试一次 |
|
||
|
||
超过72小时仍失败,任务标记为“已放弃”状态,不再自动重试,等待告警通知后人工介入处理。
|
||
|
||
**机制三:定时补偿任务**
|
||
|
||
| 任务 | 执行频率 | 处理逻辑 |
|
||
|-----|---------|----------|
|
||
| 券码状态同步 | 每小时 | 扫描状态=200(已预约)的订单,查询蓝色兄弟券码状态:已核销(2)→创建服务完成任务,已作废(3)→创建作废补偿任务,已过期(4)→创建过期处理任务 |
|
||
| 通知任务重试 | 每5分钟 | 扫描状态=3(失败)且未超过最大重试次数的任务,按退避策略重试 |
|
||
| 失败任务告警 | 每10分钟 | 扫描超过最大重试次数的任务,发送告警通知 |
|
||
|
||
**机制四:对账兜底**
|
||
|
||
- 每日凌晨对账:比对本地「已核销」订单与邮储「已完成」状态
|
||
- 发现不一致:自动重新发起服务完成通知
|
||
- 月度对账:与邮储对账文件核对,确保无遗漏
|
||
|
||
#### 5.2.3 订单状态说明
|
||
|
||
| 状态码 | 状态名称 | 说明 |
|
||
|-------|---------|------|
|
||
| 100 | 服务未预约 | 已兑换但未预约 |
|
||
| 200 | 服务已预约 | 已预约待使用 |
|
||
| 300 | 服务已完成 | 券码已核销且已通知邮储 |
|
||
| 400 | 服务已取消 | 用户主动取消 |
|
||
| 500 | 服务已过期 | 超过有效期未使用 |
|
||
|
||
#### 5.2.4 幂等性设计
|
||
|
||
| 接口/操作 | 幂等键 | 幂等策略 |
|
||
|----------|-------|----------|
|
||
| 服务预约 | 权益码(code) | 相同权益码重复请求返回相同结果(内部统一使用code字段,调用邮储接口时映射为rightsCode) |
|
||
| 服务取消 | 权益码(rightsCode) | 已取消订单重复请求直接返回成功 |
|
||
| 服务完成通知 | 权益码(rightsCode) | 已完成订单重复请求直接返回成功 |
|
||
| 券码获取 | 外部业务号(out_biz_no) | 相同业务号返回相同券码 |
|
||
| 回调处理 | 交易号(trade_no) | 相同交易号仅处理一次 |
|
||
|
||
#### 5.2.5 数据一致性监控
|
||
|
||
**告警指标**:
|
||
|
||
| 指标 | 阈值 | 告警级别 |
|
||
|-----|------|----------|
|
||
| 待执行任务积压 | > 10笔 | P2 |
|
||
| 失败任务超过最大重试 | > 0笔 | P1 |
|
||
| 任务执行失败率 | > 1% | P2 |
|
||
| 对账差异 | > 0笔 | P1 |
|
||
|
||
---
|
||
|
||
### 5.3 可用性要求
|
||
|
||
| 指标 | 要求 |
|
||
|-----|------|
|
||
| 系统可用性 | ≥ 99.9% |
|
||
| 单点故障 | 无单点,支持多实例部署 |
|
||
| 故障恢复 | RTO < 5分钟,RPO = 0 |
|
||
|
||
---
|
||
|
||
### 5.4 安全要求
|
||
|
||
1. **传输安全**:所有外部通信使用HTTPS
|
||
2. **数据脱敏**:日志中客户敏感信息脱敏处理
|
||
3. **密钥管理**:加密密钥通过配置中心管理,定期轮换
|
||
4. **访问控制**:接口签名验证,防止非法调用
|
||
|
||
---
|
||
|
||
## 6. 流程图
|
||
|
||
### 6.1 服务预约流程
|
||
|
||
```plantuml
|
||
@startuml 服务预约流程
|
||
skinparam ActivityDiamondFontSize 12
|
||
skinparam ActivityFontSize 12
|
||
|
||
start
|
||
|
||
:根据入参type(服务编码)\n查询数据库;
|
||
|
||
if (服务编码是否存在?) then (不存在)
|
||
:返回"暂不支持此服务";
|
||
stop
|
||
else (存在)
|
||
:获取对应的aes_key和aes_iv;
|
||
endif
|
||
|
||
:使用aes_key和aes_iv\n对request进行AES解密;
|
||
|
||
if (解密成功?) then (否)
|
||
:返回"参数错误";
|
||
stop
|
||
endif
|
||
|
||
:解析 type(服务编码)、code(权益码)、mac(客户id);
|
||
|
||
:基于权益码(code)获取分布式锁;
|
||
|
||
if (获取锁成功?) then (否)
|
||
:返回"请勿重复提交";
|
||
stop
|
||
endif
|
||
|
||
:defer 释放分布式锁;
|
||
note right: 使用defer机制确保锁在流程结束时释放
|
||
|
||
:查询订单状态(幂等验证);
|
||
|
||
if (订单状态?) then (服务已预约 200)
|
||
:返回预约成功;
|
||
stop
|
||
elseif (服务已取消 400) then
|
||
:返回"服务已取消";
|
||
stop
|
||
elseif (服务已完成 300) then
|
||
:返回"服务已生效";
|
||
stop
|
||
elseif (服务已过期 500) then
|
||
:返回"服务已过期";
|
||
stop
|
||
else (服务未预约 100 或 订单不存在)
|
||
endif
|
||
|
||
:请求邮储服务开放平台\n验证权益码有效性;
|
||
|
||
if (权益码是否过期?) then (过期)
|
||
if (渠道类型?) then (CRM渠道)
|
||
:返回"二维码20分钟内有效,\n现已超时失效,请联系理财经理\n重新生成二维码";
|
||
else (手机银行渠道)
|
||
:返回"当前页面停置时间过长,\n请您重新进入该页面";
|
||
endif
|
||
stop
|
||
else (未过期)
|
||
endif
|
||
|
||
:创建/更新订单记录\n(状态: 服务未预约 100);
|
||
|
||
:请求邮储服务开放平台\n发起预约;
|
||
|
||
if (预约结果?) then (成功 或 161010已预约)
|
||
:请求蓝色兄弟营销平台\n获取券码链接;
|
||
|
||
if (获取券码结果?) then (成功)
|
||
:更新订单状态为\n「服务已预约 200」;
|
||
:返回预约成功\n(包含券码链接url);
|
||
stop
|
||
else (异常)
|
||
:订单状态保持\n「服务未预约 100」;
|
||
:返回预约失败;
|
||
stop
|
||
endif
|
||
else (其他情况)
|
||
:订单状态保持\n「服务未预约 100」;
|
||
:返回预约失败;
|
||
stop
|
||
endif
|
||
|
||
@enduml
|
||
```
|
||
|
||
**流程步骤说明:**
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|-----|------|------|
|
||
| 1 | 验证服务编码 | 根据入参type查询数据库,获取对应的aes_key和aes_iv |
|
||
| 2 | AES解密 | 使用数据库查询到的aes_key和aes_iv对request进行解密,解析出type、code、mac |
|
||
| 3 | 获取分布式锁 | 基于权益码(code)获取锁,防止重复请求 |
|
||
| 4 | defer释放锁 | 使用defer机制注册锁释放,确保流程结束时自动释放 |
|
||
| 5 | 幂等验证 | 根据订单状态决定后续流程:已预约→返回成功,已取消→返回"服务已取消",已完成→返回"服务已生效",已过期→返回"服务已过期" |
|
||
| 6 | 验证权益码 | 调用邮储平台验证权益码有效性(前置校验,5s超时) |
|
||
| 7 | 创建/更新订单 | 订单状态设为「服务未预约(100)」|
|
||
| 8 | 发起预约 | 调用邮储平台发起预约(5s超时) |
|
||
| 9 | 获取券码 | 调用蓝色兄弟获取券码链接(幂等,5s超时),更新最终状态 |
|
||
|
||
---
|
||
|
||
### 6.2 券码状态同步流程
|
||
|
||
```plantuml
|
||
@startuml 券码状态同步流程
|
||
start
|
||
|
||
:定时任务触发(每小时);
|
||
|
||
:扫描状态=200(已预约)的订单;
|
||
|
||
while (遍历订单?) is (有)
|
||
:请求蓝色兄弟查询券码状态;
|
||
note right: 5s超时
|
||
|
||
if (券码状态?) then (已核销 2)
|
||
:检查是否已有通知任务;
|
||
if (任务存在?) then (否)
|
||
:创建通知任务\n(type=1 服务完成);
|
||
endif
|
||
elseif (已作废 3) then
|
||
:检查是否已有通知任务;
|
||
if (任务存在?) then (否)
|
||
:创建通知任务\n(type=3 作废补偿);
|
||
endif
|
||
elseif (已过期 4) then
|
||
:检查是否已有通知任务;
|
||
if (任务存在?) then (否)
|
||
:创建通知任务\n(type=2 过期处理);
|
||
endif
|
||
else (正常 1)
|
||
:跳过,等待用户使用;
|
||
endif
|
||
endwhile (无)
|
||
|
||
stop
|
||
|
||
@enduml
|
||
```
|
||
|
||
**流程步骤说明:**
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|-----|------|------|
|
||
| 1 | 定时触发 | 每小时执行一次 |
|
||
| 2 | 扫描订单 | 查询状态=200(已预约)的订单 |
|
||
| 3 | 查询券码状态 | 调用蓝色兄弟券码查询接口(5s超时) |
|
||
| 4 | 创建任务 | 根据券码状态创建对应类型的通知任务(幂等检查) |
|
||
|
||
**券码状态与任务类型映射:**
|
||
|
||
| 券码状态 | 任务类型 | 处理逻辑 |
|
||
|----------|----------|----------|
|
||
| 已核销(2) | 服务完成通知(1) | 调用邮储服务完成接口 → 订单状态改为300 |
|
||
| 已作废(3) | 作废补偿(3) | 调用邮储预约取消接口 → 订单状态改为400 |
|
||
| 已过期(4) | 过期处理(2) | 调用邮储预约取消接口 → 订单状态改为500 |
|
||
| 正常(1) | - | 跳过,等待用户使用 |
|
||
|
||
### 6.2.1 通知任务执行流程
|
||
|
||
```plantuml
|
||
@startuml 通知任务执行流程
|
||
start
|
||
|
||
:定时任务触发(每5分钟);
|
||
|
||
:扫描状态=0(待执行)或\n状态=3(失败)且未超过最大重试次数的任务;
|
||
|
||
while (遍历任务?) is (有)
|
||
:更新任务状态为执行中(1);
|
||
|
||
if (任务类型?) then (type=1 服务完成)
|
||
:调用邮储服务完成接口;
|
||
elseif (type=2 过期处理) then
|
||
:调用邮储预约取消接口;
|
||
else (type=3 作废补偿)
|
||
:调用邮储预约取消接口;
|
||
endif
|
||
note right: 5s超时
|
||
|
||
if (执行成功?) then (是)
|
||
:更新任务状态为已完成(2);
|
||
:更新订单状态;
|
||
note right: type=1→300, type=2→500, type=3→400
|
||
else (否)
|
||
:retry_count++;
|
||
if (retry_count > max_retry?) then (是)
|
||
:任务状态保持失败(3);
|
||
:记录错误信息,等待告警;
|
||
else (否)
|
||
:更新任务状态为失败(3);
|
||
:设置下次重试时间(指数退避);
|
||
endif
|
||
endif
|
||
endwhile (无)
|
||
|
||
stop
|
||
|
||
@enduml
|
||
```
|
||
|
||
**重试策略(指数退避):**
|
||
|
||
| 重试次数 | 间隔 | 累计时间 |
|
||
|----------|------|----------|
|
||
| 第1次 | 10秒 | 10秒 |
|
||
| 第2次 | 30秒 | 40秒 |
|
||
| 第3次 | 1分钟 | 1分40秒 |
|
||
| 第4次 | 5分钟 | 6分40秒 |
|
||
| 第5次 | 10分钟 | 16分40秒 |
|
||
| 第6次 | 30分钟 | 46分40秒 |
|
||
| 第7次 | 1小时 | 1小时46分40秒 |
|
||
| 第8次 | 2小时 | 3小时46分40秒 |
|
||
|
||
超过8次仍失败,任务保持失败状态,等待告警通知后人工介入处理。
|
||
|
||
---
|
||
|
||
### 6.3 服务取消流程
|
||
|
||
```plantuml
|
||
@startuml 服务取消流程
|
||
start
|
||
|
||
:接收取消请求;
|
||
|
||
:AES解密request;
|
||
note right: 解析type、code、mac
|
||
|
||
if (解密成功?) then (否)
|
||
:返回参数错误;
|
||
stop
|
||
endif
|
||
|
||
:基于权益码(code)获取分布式锁;
|
||
|
||
if (获取锁成功?) then (否)
|
||
:返回"请勿重复提交";
|
||
stop
|
||
endif
|
||
|
||
:defer 释放分布式锁;
|
||
note right: 使用defer机制确保锁在流程结束时释放
|
||
|
||
:查询本地订单;
|
||
|
||
if (订单存在?) then (否)
|
||
:返回订单不存在;
|
||
stop
|
||
endif
|
||
|
||
if (订单状态=已取消?) then (是)
|
||
:返回取消成功;
|
||
stop
|
||
endif
|
||
|
||
if (订单状态=已过期?) then (是)
|
||
:返回"服务已过期";
|
||
stop
|
||
endif
|
||
|
||
if (订单状态=已预约?) then (否)
|
||
:返回"服务已生效无法取消";
|
||
stop
|
||
endif
|
||
|
||
:调用邮储预约服务状态查询接口;
|
||
note right: 5s超时
|
||
|
||
if (邮储状态=已取消?) then (是)
|
||
:更新本地订单状态为已取消;
|
||
:返回取消成功;
|
||
stop
|
||
endif
|
||
|
||
if (邮储状态=已预约?) then (否)
|
||
:返回"服务已生效,无法取消";
|
||
stop
|
||
endif
|
||
|
||
:调用蓝色兄弟作废接口;
|
||
note right: 5s超时
|
||
|
||
if (作废成功?) then (否)
|
||
:调用蓝色兄弟券码查询接口;
|
||
if (券码状态=已作废?) then (否)
|
||
:返回"服务取消失败,请重试";
|
||
stop
|
||
endif
|
||
endif
|
||
|
||
:调用邮储预约取消接口;
|
||
note right: 5s超时
|
||
|
||
if (取消成功?) then (否)
|
||
:返回"服务取消失败";
|
||
stop
|
||
endif
|
||
|
||
:更新订单状态为已取消(400);
|
||
:返回取消成功;
|
||
|
||
stop
|
||
|
||
@enduml
|
||
```
|
||
|
||
**流程步骤说明:**
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|-----|------|------|
|
||
| 1 | AES解密 | 对request进行AES解密,解析出type、code、mac |
|
||
| 2 | 获取分布式锁 | 基于权益码(code)获取锁,防止重复请求 |
|
||
| 3 | defer释放锁 | 使用defer机制注册锁释放,确保流程结束时自动释放 |
|
||
| 4 | 本地订单校验 | 查询订单是否存在,已取消直接返回成功,已过期返回"服务已过期",非已预约返回失败 |
|
||
| 5 | 邮储状态查询 | 调用邮储预约服务状态查询接口(5s超时),确认可取消 |
|
||
| 6 | 蓝色兄弟作废 | 调用作废接口(5s超时),失败时查询券码状态确认 |
|
||
| 7 | 邮储预约取消 | 调用邮储预约取消接口(5s超时),确认取消成功 |
|
||
| 8 | 更新订单状态 | 更新本地订单状态为已取消(400) |
|
||
|
||
---
|
||
|
||
### 6.4 月度对账流程
|
||
|
||
```plantuml
|
||
@startuml 月度对账流程
|
||
start
|
||
|
||
:定时任务触发(每月3号);
|
||
|
||
:查询上月status=300(已完成)的订单;
|
||
note right: 对账月份=服务完成时间所在月
|
||
|
||
if (有订单数据?) then (无)
|
||
:跳过,不生成对账文件;
|
||
stop
|
||
endif
|
||
|
||
:生成对账文件;
|
||
note right: RIGHTS_SERVICE_CHK_{providerCode}_{reconMonth}.csv
|
||
|
||
:调用邮储对账文件查询接口;
|
||
note right: 5s超时
|
||
|
||
if (获取文件列表成功?) then (否)
|
||
:记录错误,等待重试;
|
||
stop
|
||
endif
|
||
|
||
:调用邮储对账文件下载接口;
|
||
note right: 5s超时
|
||
|
||
if (下载成功?) then (否)
|
||
:记录错误,等待重试;
|
||
stop
|
||
endif
|
||
|
||
:SM4解密对账文件;
|
||
|
||
:解析对账文件内容;
|
||
|
||
while (遍历邮储对账记录?) is (有)
|
||
:根据权益码查询本地订单;
|
||
|
||
if (本地订单存在?) then (否)
|
||
:记录差异-本地缺失;
|
||
elseif (状态一致?) then (否)
|
||
:记录差异-状态不一致;
|
||
:创建服务完成通知任务;
|
||
else (是)
|
||
:标记为已对账;
|
||
endif
|
||
endwhile (无)
|
||
|
||
:保存对账结果;
|
||
|
||
if (有差异?) then (是)
|
||
:发送告警通知;
|
||
endif
|
||
|
||
:生成对账报告;
|
||
|
||
stop
|
||
|
||
@enduml
|
||
```
|
||
|
||
**流程步骤说明**:
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|-----|------|------|
|
||
| 1 | 定时触发 | 每月3号执行 |
|
||
| 2 | 查询本地订单 | 查询上月status=300(已完成)的订单 |
|
||
| 3 | 生成对账文件 | 生成CSV格式对账文件 |
|
||
| 4 | 获取邮储对账文件 | 调用邮储查询和下载接口(5s超时) |
|
||
| 5 | SM4解密 | 使用SM4密钥解密对账文件 |
|
||
| 6 | 数据核对 | 逐笔对比邮储和本地数据 |
|
||
| 7 | 差异处理 | 本地缺失或状态不一致时创建补推任务 |
|
||
| 8 | 生成报告 | 保存对账结果,有差异时发送告警 |
|
||
|
||
**对账月份规则**:
|
||
|
||
| 服务完成时间 | 对账月份 | 对账文件生成时间 | 对账文件名 |
|
||
|--------------|---------|--------------|----------|
|
||
| 202512210000 | 202512 | 2026年1月3日 | RIGHTS_SERVICE_CHK_A101_202512.csv |
|
||
| 202601010000 | 202601 | 2026年2月3日 | RIGHTS_SERVICE_CHK_A101_202601.csv |
|
||
|
||
### 6.4.1 批量补推流程
|
||
|
||
```plantuml
|
||
@startuml 批量补推流程
|
||
start
|
||
|
||
:接收补推请求;
|
||
|
||
if (参数校验?) then (失败)
|
||
:返回参数错误;
|
||
stop
|
||
endif
|
||
|
||
if (传入codes?) then (是)
|
||
if (codes数量>100?) then (是)
|
||
:返回"单次补推不能超过100笔";
|
||
stop
|
||
endif
|
||
:按权益码列表查询订单;
|
||
else (否)
|
||
:按时间范围查询订单;
|
||
if (结果数量>100?) then (是)
|
||
:返回"符合条件订单超过100笔";
|
||
stop
|
||
endif
|
||
endif
|
||
|
||
:筛选status=200且key_status=2的订单;
|
||
|
||
if (dryRun=true?) then (是)
|
||
:返回待补推订单列表;
|
||
stop
|
||
endif
|
||
|
||
while (遍历订单?) is (有)
|
||
:检查是否已有待处理任务;
|
||
|
||
if (已有任务?) then (是)
|
||
:skippedCount++;
|
||
else (否)
|
||
:创建服务完成通知任务;
|
||
note right: task_type=1\ntrigger_source=2
|
||
:createdCount++;
|
||
endif
|
||
endwhile (无)
|
||
|
||
:返回补推结果;
|
||
note right: totalCount, createdCount, skippedCount
|
||
|
||
stop
|
||
|
||
@enduml
|
||
```
|
||
|
||
**流程步骤说明**:
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|-----|------|------|
|
||
| 1 | 参数校验 | codes和时间范围必须二选一 |
|
||
| 2 | 数量校验 | 单次最多处理100笔 |
|
||
| 3 | 查询订单 | 筛选status=200且key_status=2的订单 |
|
||
| 4 | 试运行判断 | dryRun=true时只查询不创建任务 |
|
||
| 5 | 幂等检查 | 已有待处理任务的订单跳过 |
|
||
| 6 | 创建任务 | task_type=1, trigger_source=2 |
|
||
| 7 | 返回结果 | 包含创建数量和跳过数量 |
|
||
|
||
---
|
||
|
||
### 6.5 错误处理流程
|
||
|
||
TODO
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### 附录A:专业术语说明
|
||
|
||
#### A.1 下游系统(邮储银行服务开放平台)
|
||
|
||
| 术语 | 英文 | 说明 |
|
||
|-----|------|------|
|
||
| 幸福点 | Happiness Points | 邮储银行高端客户积分,可兑换权益服务 |
|
||
| 权益码 | Rights Code | 客户兑换权益服务后获得的唯一标识码,格式如:16800G-VN4724-NX874-30VHR |
|
||
| 服务开放平台 | Open Platform | 邮储银行对外开放的API服务平台 |
|
||
| SM2 | SM2 | 国密非对称加密算法,用于密钥交换和数字签名 |
|
||
| SM3 | SM3 | 国密哈希算法,用于消息摘要 |
|
||
| SM4 | SM4 | 国密对称加密算法,用于报文加密 |
|
||
| 业务主ID | busiMainId | 请求的业务唯一标识,规则:渠道号(2位)+日期(8位)+序列号(8位) |
|
||
| 对账 | Reconciliation | 每月核对服务商与银行之间的交易数据一致性 |
|
||
| T+2 | T+2 | 服务完成后2个工作日内需完成状态同步 |
|
||
| 高端客户 | VIP Customer | 邮储银行AUM(资产管理规模)≥50万的客户 |
|
||
| AUM | Assets Under Management | 资产管理规模 |
|
||
|
||
#### A.2 服务商系统(当前系统)
|
||
|
||
| 术语 | 英文 | 说明 |
|
||
|-----|------|------|
|
||
| 合作方交易流水号 | partnerTxSriNo | 服务商生成的交易唯一标识,规则:渠道号(2位)+日期(8位)+序列号(8位) |
|
||
| 订单号 | Order No | 服务商系统内部订单唯一标识 |
|
||
| 服务状态 | Service Status | 订单服务状态:100-未预约,200-已预约,300-已完成,400-已取消,500-已过期 |
|
||
|
||
#### A.3 上游系统(蓝色兄弟营销开放API)
|
||
|
||
| 术语 | 英文 | 说明 |
|
||
|-----|------|------|
|
||
| 蓝色兄弟 | LSB (Lan Se Xiong Di) | 第三方虚拟商品供应商,提供券码服务 |
|
||
| 券码 | Coupon Key | 蓝色兄弟平台生成的虚拟商品兑换码 |
|
||
| RSA | RSA | 非对称加密算法,用于蓝色兄弟接口签名 |
|
||
| AES | AES | 对称加密算法,用于蓝色兄弟业务参数加密 |
|
||
| 外部业务号 | out_biz_no | 调用蓝色兄弟API的幂等标识,长度2~32位 |
|
||
| 交易号 | trade_no | 蓝色兄弟返回的平台交易唯一标识 |
|
||
| 活动编号 | activity_no | 蓝色兄弟平台的营销活动唯一标识 |
|
||
| 券码状态 | Key Status | 券码状态:1-正常,2-已核销,3-已作废,4-已过期 |
|
||
|
||
---
|
||
|
||
### 附录B:接口业务响应码
|
||
|
||
#### B.1 下游系统(邮储银行服务开放平台)响应码
|
||
|
||
**公共响应码**:
|
||
|
||
| 响应码 | 描述 | 处理建议 |
|
||
|-------|------|----------|
|
||
| 000000 | 交易成功 | - |
|
||
| 900000 | 未知系统异常 | 稍后重试或联系技术支持 |
|
||
| 900001 | 非法参数 | 检查请求参数格式 |
|
||
| 900002 | 必填参数缺失 | 补充必填参数 |
|
||
| 900005 | 签名错误 | 检查签名算法和密钥 |
|
||
| 900006 | 请求非法 | 检查请求格式 |
|
||
| 900008 | 幂等错误 | 检查流水号是否重复 |
|
||
| 900011 | 签名验证失败 | 检查签名和公钥 |
|
||
| 990172 | 系统繁忙 | 稍后重试 |
|
||
| 990272 | 系统繁忙 | 稍后重试 |
|
||
| 990772 | 系统繁忙 | 稍后重试 |
|
||
|
||
**权益积分业务响应码**:
|
||
|
||
| 响应码 | 描述 | 处理建议 |
|
||
|-------|------|----------|
|
||
| 161006 | 交易数据不存在 | 检查权益码或流水号 |
|
||
| 161008 | 未知渠道错误 | 检查渠道标识 |
|
||
| 161014 | 服务已完成或取消,不允许再操作 | 业务状态已终结 |
|
||
| 161016 | 无权益服务可操作 | 检查订单状态 |
|
||
| 161024 | 服务未预约,不允许完成或取消操作 | 需先完成预约 |
|
||
| 161026 | 兑换权益码已失效 | 权益码超过20分钟有效期 |
|
||
| 161027 | 兑换权益码错误 | 检查权益码格式 |
|
||
| 161033 | 实际完成时间不满足对账规范 | 检查completionTime格式 |
|
||
| 727101 | 系统异常,请稍后重试 | 稍后重试 |
|
||
| 727102 | 未查询到当前分类的积分信息 | 检查查询条件 |
|
||
| 729006 | 未找到原交易 | 检查原交易流水号 |
|
||
| 729011 | 客户名称不能为空 | 补充客户名称 |
|
||
| 729012 | 客户证件类型不能为空 | 补充证件类型 |
|
||
| 729013 | 证件号码不能为空 | 补充证件号码 |
|
||
| 729024 | 证件号码格式不正确 | 检查证件号码格式 |
|
||
| 729033 | 客户编号格式不正确 | 检查客户编号格式 |
|
||
| 720502 | 原交易流水号不能为空 | 补充原交易流水号 |
|
||
| 720503 | 原交易流水号格式不正确 | 检查流水号格式 |
|
||
| 729809 | 系统繁忙,请稍后再试 | 稍后重试 |
|
||
| 729909 | 不能为空 | 补充必填字段 |
|
||
| 729910 | 格式不正确 | 检查字段格式 |
|
||
| 729917 | 长度不符合要求 | 检查字段长度 |
|
||
| 729918 | 不能包含特殊字符 | 移除特殊字符 |
|
||
| 729922 | 查询结束时间不得小于查询开始时间 | 调整时间范围 |
|
||
| 729928 | 查询起始日期必须在12个月内 | 调整查询日期 |
|
||
|
||
**文件接口响应码**:
|
||
|
||
| 响应码 | 描述 | 处理建议 |
|
||
|-------|------|----------|
|
||
| 062005 | 查询失败,请稍后再试 | 稍后重试 |
|
||
| 063001 | 系统繁忙,请稍后再试 | 稍后重试 |
|
||
|
||
---
|
||
|
||
#### B.2 上游系统(蓝色兄弟营销开放API)响应码
|
||
|
||
**公共响应码**:
|
||
|
||
| code | reason | 描述 | 处理建议 |
|
||
|------|--------|------|----------|
|
||
| 200 | - | 成功 | - |
|
||
| 400 | SIGNATURE_FAIL | 签名错误 | 检查签名密钥和算法 |
|
||
| 400 | SDK_INI_FAIL | SDK错误 | 检查应用配置信息 |
|
||
| 400 | PARAM_FAIL | 参数错误 | 检查业务参数 |
|
||
| 400 | PARAM_DECRYPT_FAIL | 参数解密错误 | 检查加密方式 |
|
||
| 500 | PANIC | 系统错误 | 联系平台处理 |
|
||
|
||
**业务响应码**:
|
||
|
||
| code | reason | 描述 | 处理建议 |
|
||
|------|--------|------|----------|
|
||
| 401 | ACTIVITY_NOT_AUTH | 活动未授权 | 检查活动授权状态 |
|
||
| 401 | MERCHANT_NOT_EXIST | 客户不存在 | 检查客户是否存在 |
|
||
| 401 | MERCHANT_NOT_AUTH | 客户冻结 | 检查客户授权状态 |
|
||
| 401 | MERCHANT_APP_INCOMPLETE | 客户应用配置未完善 | 完善应用配置 |
|
||
| 401 | MERCHANT_APP_NOT_AUTH | 应用不存在 | 检查应用授权状态 |
|
||
| 403 | ACTIVITY_EXPIRE | 活动已结束 | 检查活动有效期 |
|
||
| 403 | ACTIVITY_NOT_AUTH | 活动状态异常 | 检查活动状态(作废/待审核/驳回/暂停/失效/编辑中) |
|
||
| 403 | ACTIVITY_OUT_OF_STOCK | 活动库存不足 | 联系平台补充库存 |
|
||
| 404 | KEY_NOT_EXIST | 券码不存在 | 检查券码或交易号 |
|
||
| 404 | ACTIVITY_NOT_EXIST | 活动不存在 | 检查活动编号 |
|
||
| 404 | MERCHANT_NOT_EXIST | 客户不存在 | 检查app_id |
|
||
| 404 | MERCHANT_APP_NOT_EXIST | 客户应用不存在 | 检查app_id |
|
||
| 404 | MERCHANT_ORDER_NOT_EXIST | 订单记录不存在 | 检查交易号/外部业务号 |
|
||
| 404 | MERCHANT_APP_INCOMPLETE | 客户应用信息未完善 | 完善应用信息 |
|
||
| 503 | KEY_CREATE_FAIL | 券码创建失败 | 稍后重试或联系平台 |
|
||
| 503 | MERCHANT_ORDER_CREATE_FAIL | 订单创建失败 | 稍后重试或联系平台 |
|
||
| 503 | MERCHANT_ORDER_DISCARD_FAIL | 订单作废失败 | 稍后重试或联系平台 |
|
||
| 503 | MERCHANT_ORDER_DISCARD_MQ_FAIL | 订单作废消息失败 | 稍后重试或联系平台 |
|
||
|
||
---
|
||
|
||
#### B.3 服务商系统(当前系统)内部错误码
|
||
|
||
| 错误码 | 描述 | 处理建议 |
|
||
|-------|------|----------|
|
||
| SYS_001 | 系统内部错误 | 检查系统日志,联系技术支持 |
|
||
| SYS_002 | 数据库操作异常 | 检查数据库连接和SQL |
|
||
| SYS_003 | 外部服务调用超时 | 检查网络连接,稍后重试 |
|
||
| BIZ_001 | 订单不存在 | 检查订单号是否正确 |
|
||
| BIZ_002 | 订单状态不允许此操作 | 检查当前订单状态 |
|
||
| BIZ_003 | 券码获取失败 | 检查上游服务状态 |
|
||
| BIZ_004 | 券码作废失败 | 检查券码当前状态 |
|
||
| BIZ_005 | 服务完成通知失败 | 检查下游服务状态,稍后重试 |
|
||
|
||
---
|
||
|
||
### 附录C:服务类型与厂商编码
|
||
|
||
#### C.1 服务类型编码
|
||
|
||
| 服务类型 | 名称 | 类别 |
|
||
|---------|------|------|
|
||
| 210001 | 口腔护理 | 健康服务 |
|
||
| 210002 | 三个月血糖管理 | 健康服务 |
|
||
| 210003 | 三个月血压管理 | 健康服务 |
|
||
| 210004 | 三个月体重管理 | 健康服务 |
|
||
| 220001 | 高铁贵宾厅 | 出行服务 |
|
||
| 220002 | 机场贵宾厅 | 出行服务 |
|
||
| 220003 | 洗车 | 出行服务 |
|
||
| 310001 | 喜马拉雅VIP巅峰会员季卡 | 虚拟会员 |
|
||
| 310002 | 知乎会员季卡 | 虚拟会员 |
|
||
| 1200 | 机场快速通道 | 出行服务 |
|
||
| 1400 | 专车服务(舒适型30公里) | 出行服务 |
|
||
| 1410 | 专车服务(商务型30公里) | 出行服务 |
|
||
| 1420 | 专车服务(舒适型50公里) | 出行服务 |
|
||
| 1430 | 专车服务(商务型50公里) | 出行服务 |
|
||
| 1500 | 代驾服务(20公里及以内) | 出行服务 |
|
||
|
||
#### C.2 服务厂商编号
|
||
|
||
| 编号 | 名称 |
|
||
|-----|------|
|
||
| A101 | 盛大 |
|
||
| B101 | 元化 |
|
||
|
||
#### C.3 渠道标识
|
||
|
||
| 渠道标识 | 名称 |
|
||
|---------|------|
|
||
| 12 | 手机银行 |
|
||
| 17 | 电话银行 |
|
||
| 18 | 微信银行 |
|
||
| 36 | you生活 |
|
||
| 46 | 北京分行 |
|