docs(api): 完善邮储银行服务平台接口文档与设计方案

- 统一接口公共响应规范,定义code/msg/traceId/data字段及响应码说明
- 详细补充服务预约接口请求解密、业务流程及幂等设计
- 更新服务取消、完成通知、订单查询等接口数据结构与响应字段
- 修订加密解密方案,新增预约请求AES解密规则
- 规范数据库表结构,调整订单表、券码表及新增服务编码映射表
- 明确高性能响应时间、并发指标及缓存设计策略
- 增加数据一致性保障方案,包括本地事务和异步消息机制
- 描述幂等设计、数据一致性监控与告警指标
- 补充系统可用性、安全要求及异常处理流程
- 规划流程图和用户故事章节,完善整体设计文档结构
This commit is contained in:
zhouyonggao 2026-03-13 11:10:01 +08:00
parent 05268a1895
commit b1fac44487
1 changed files with 307 additions and 356 deletions

View File

@ -44,50 +44,93 @@
---
## 2. 功能详细说明
## 2. 公共响应规范
### 2.1 接口服务模块
### 2.1 响应结构
#### 2.1.1 服务预约接口
所有接口统一使用以下响应结构:
```json
{
"code": 0,
"msg": "成功",
"traceId": "请求追踪ID",
"data": {
// 业务数据
}
}
```
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| code | int | M | 公共响应码0表示成功非0表示失败 |
| msg | String | M | 响应描述信息当code!=0时为错误信息 |
| traceId | String | M | 请求追踪ID用于问题排查 |
| data | Object | C | 业务数据,成功时返回 |
### 2.2 公共响应码
| 响应码 | 描述 | 说明 |
|-------|------|------|
| 0 | 成功 | 业务处理成功 |
| 1 | 系统异常 | 系统内部错误,请稍后重试 |
| 2 | 参数错误 | 请求参数校验失败 |
| 3 | 签名错误 | 签名验证失败 |
| 4 | 业务错误 | 业务规则校验失败 |
---
## 3. 功能详细说明
### 3.1 接口服务模块
#### 3.1.1 服务预约接口
**功能描述**:接收邮储银行服务开放平台的预约请求,为客户预约虚拟商品充值服务
**业务规则**
1. 解密请求报文,验证签名
2. 校验权益码有效性20分钟有效期
3. 调用蓝色兄弟API获取券码
4. 创建订单记录,状态设为"已预约"(200)
5. 返回预约成功响应
1. 对request进行AES解密解析出type(服务编码)、code(权益码)、mac(客户id)
2. 对code(权益码)进行幂等验证:
- 若订单状态为「服务已预约(200)」,直接返回预约成功(与正常请求返回一致)
- 若订单状态为「服务未预约(100)」,继续执行后续流程(更新订单,不新增)
- 若订单状态为其他状态,返回服务已预约
3. 查询数据库验证服务编码(type)是否存在(数据库中维护邮储服务编码与营销平台活动的映射关系)
4. 请求邮储服务开放平台接口验证权益码是否过期
5. 创建/更新订单记录(订单状态:服务未预约)
6. 请求邮储服务开放平台接口发起预约:
- 预约成功或返回161010(交易已预约)继续执行步骤7
- 其他情况:订单状态保持「服务未预约(100)」,返回预约失败
7. 请求蓝色兄弟营销平台获取券码链接(使用相同交易号和参数请求):
- 请求成功:更新订单状态为「服务已预约(200)」,返回预约成功响应
- 请求异常:订单状态保持「服务未预约(100)」,返回预约失败
**输入**
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| rightsCode | String | M | 兑换预约码格式16800G-VN4724-NX874-30VHR |
| serviceType | String | M | 服务类型编码 |
| providerCode | String | M | 服务厂商编号 |
| custName | String | C | 客户名称(电话银行渠道可选) |
| personalCertTypeCode | String | C | 证件类型 |
| personalCertNo | String | C | 证件号码 |
| 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字段内容
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| respCode | String | M | 返回码000000表示成功 |
| respMsg | String | M | 返回信息 |
| rightsCode | String | C | 兑换预约码 |
| tradeRespCode | String | M | 业务响应码 |
| tradeRespMsg | String | M | 业务响应码描述 |
| url | String | M | 蓝色兄弟营销平台的兑换地址 |
| tranChnl | String | M | 渠道标识 |
| instType | String | M | 客户自营代理属性 |
| backUrl | String | C | 返回手机银行的地址 |
**验收标准**
- [ ] 能正确解密SM4加密的请求报文
- [ ] 能正确验证SM2签名
- [ ] 权益码超过20分钟返回失效错误(161026)
- [ ] 预约成功后订单状态为200
- [ ] 预约成功后能获取到蓝色兄弟券码
- [ ] 能正确解密AES加密的request参数
- [ ] 能正确解析解密后的参数type、code、mac
- [ ] 预约成功后返回蓝色兄弟兑换地址(url)
- [ ] 响应正确透传tranChnl、instType、backUrl
---
#### 2.1.2 服务取消接口
#### 3.1.2 服务取消接口
**功能描述**:接收邮储银行服务开放平台的取消请求,取消已预约的服务
@ -104,23 +147,21 @@
| serviceType | String | M | 服务类型编码 |
| providerCode | String | M | 服务厂商编号 |
**输出**
**输出**data字段内容
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| respCode | String | M | 返回码 |
| respMsg | String | M | 返回信息 |
| tradeRespCode | String | M | 业务响应码 |
| tradeRespMsg | String | M | 业务响应码描述 |
**验收标准**
- [ ] 非"已预约"状态订单返回错误(161024)
- [ ] 非“已预约”状态订单返回错误(161024)
- [ ] 已完成订单不允许取消(161014)
- [ ] 取消成功后蓝色兄弟券码状态为已作废(3)
- [ ] 取消成功后订单状态为400
---
#### 2.1.3 服务完成通知接口
#### 3.1.3 服务完成通知接口
**功能描述**:接收蓝色兄弟券码核销回调,主动通知邮储银行服务完成
@ -139,11 +180,10 @@
| providerCode | String | M | 服务厂商编号 |
| completionTime | String | M | 实际完成时间格式yyyyMMddHHmmss |
**输出**
**输出**data字段内容
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| respCode | String | M | 返回码 |
| respMsg | String | M | 返回信息 |
| - | - | - | 无业务数据,仅返回公共响应 |
**验收标准**
- [ ] 能正确接收蓝色兄弟回调通知
@ -154,7 +194,7 @@
---
#### 2.1.4 订单过期积分查询接口
#### 3.1.4 订单过期积分查询接口
**功能描述**:查询订单退还时已过期的幸福点信息,用于取消前提醒客户
@ -173,11 +213,9 @@
| paperType | String | C | 证件类型 |
| paperId | String | C | 证件号码 |
**输出**
**输出**data字段内容
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| respCode | String | M | 返回码 |
| respMsg | String | M | 返回信息 |
| tranIntglNum | int | C | 交易总幸福点 |
| ovdueIntglNum | int | C | 已过期的幸福点 |
| noticeMsg | String | C | 提醒信息文本 |
@ -189,7 +227,7 @@
---
#### 2.1.5 服务状态查询接口
#### 3.1.5 服务状态查询接口
**功能描述**:根据权益码查询服务预约状态
@ -203,11 +241,9 @@
| rightsCode | String | M | 兑换权益码 |
| tranChnl | String | M | 渠道标识 |
**输出**
**输出**data字段内容
| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| respCode | String | M | 返回码 |
| respMsg | String | M | 返回信息 |
| serviceState | String | M | 预约服务状态码100-未预约200-已预约300-已完成400-已取消500-已过期 |
| serviceStateMsg | String | M | 预约服务状态描述 |
@ -217,9 +253,9 @@
---
### 2.2 券码管理模块
### 3.2 券码管理模块
#### 2.2.1 券码获取功能
#### 3.2.1 券码获取功能
**功能描述**调用蓝色兄弟API获取虚拟商品券码
@ -259,7 +295,7 @@
---
#### 2.2.2 券码查询功能
#### 3.2.2 券码查询功能
**功能描述**:查询已获取券码的当前状态
@ -286,7 +322,7 @@
---
#### 2.2.3 券码作废功能
#### 3.2.3 券码作废功能
**功能描述**:作废待使用或已过期的券码
@ -307,7 +343,7 @@
---
#### 2.2.4 券码状态回调接收
#### 3.2.4 券码状态回调接收
**功能描述**:接收蓝色兄弟的券码状态变更通知
@ -334,9 +370,9 @@
---
### 2.3 订单管理模块
### 3.3 订单管理模块
#### 2.3.1 订单创建
#### 3.3.1 订单创建
**功能描述**:创建权益服务订单
@ -351,7 +387,7 @@
---
#### 2.3.2 订单状态管理
#### 3.3.2 订单状态管理
**功能描述**:管理订单全生命周期状态流转
@ -376,7 +412,7 @@
---
#### 2.3.3 订单查询
#### 3.3.3 订单查询
**功能描述**:支持多维度订单查询
@ -393,9 +429,9 @@
---
### 2.4 对账管理模块
### 3.4 对账管理模块
#### 2.4.1 对账文件查询
#### 3.4.1 对账文件查询
**功能描述**:查询邮储银行生成的对账文件列表
@ -415,7 +451,7 @@
---
#### 2.4.2 对账文件下载
#### 3.4.2 对账文件下载
**功能描述**:下载对账文件内容
@ -446,30 +482,38 @@
---
### 2.5 安全与加密模块
### 3.5 安全与加密模块
#### 2.5.1 邮储银行加解密SM2/SM4
#### 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签名验签正确
---
#### 2.5.2 蓝色兄弟加解密RSA/AES
#### 3.5.2 蓝色兄弟加解密RSA/AES
**功能描述**:实现与蓝色兄弟通信的加解密
@ -489,54 +533,44 @@
---
## 3. 数据需求
## 4. 数据需求
### 3.1 数据实体
### 4.1 数据实体
#### 3.1.1 订单表(t_order)
#### 4.1.1 订单表(ycjfsc_order)
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|-------|------|-----|-----|------|
| id | bigint | 20 | M | 主键 |
| order_no | varchar | 32 | M | 订单号 |
| rights_code | varchar | 32 | M | 权益码 |
| service_type | varchar | 6 | M | 服务类型 |
| provider_code | varchar | 4 | M | 服务商编号 |
| status | int | 3 | M | 订单状态100/200/300/400/500 |
| cust_name | varchar | 40 | N | 客户名称 |
| cert_type | varchar | 2 | N | 证件类型 |
| cert_no | varchar | 30 | N | 证件号码 |
| cust_id | varchar | 32 | N | 客户编号 |
| partner_tx_sri_no | varchar | 24 | M | 合作方交易流水号 |
| req_time | datetime | - | M | 请求时间 |
| appointment_time | datetime | - | N | 预约时间 |
| completion_time | datetime | - | N | 完成时间 |
| cancel_time | datetime | - | N | 取消时间 |
| create_time | datetime | - | M | 创建时间 |
| update_time | datetime | - | 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 | 内部订单状态0异常 100 未预约 200已预约 300已完成 400已取消 500已过期 |
#### 3.1.2 券码表(t_coupon)
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|-------|------|-----|-----|------|
| id | bigint | 20 | M | 主键 |
| order_id | bigint | 20 | M | 关联订单ID |
| out_biz_no | varchar | 32 | M | 外部业务号 |
| trade_no | varchar | 32 | M | 交易号 |
| 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 | 256 | N | 短链接 |
| status | int | 1 | M | 状态1-正常2-已核销3-已作废4-已过期 |
| activity_no | varchar | 32 | M | 活动编号 |
| usable_num | int | 10 | M | 总兑换次数 |
| usage_num | int | 10 | M | 已兑换次数 |
| valid_begin_time | datetime | - | M | 有效期开始 |
| valid_end_time | datetime | - | M | 有效期结束 |
| usage_time | datetime | - | N | 核销时间 |
| discard_time | datetime | - | N | 作废时间 |
| create_time | datetime | - | M | 创建时间 |
| 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 | 创建时间 |
#### 3.1.3 对账记录表(t_reconciliation)
#### 4.1.2 对账记录表(ycjfsc_reconciliation)
| 字段名 | 类型 | 长度 | 必填 | 说明 |
|-------|------|-----|-----|------|
@ -551,7 +585,21 @@
| create_time | datetime | - | M | 创建时间 |
| update_time | datetime | - | M | 更新时间 |
### 3.2 数据规则
#### 4.1.3 服务编码映射表(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. **订单号生成规则**:渠道号(2位) + 日期(8位) + 序列号(8位)
2. **外部业务号生成规则**:订单号 + 随机数(4位),保证唯一性和幂等性
@ -560,306 +608,209 @@
---
## 4. 流程图
## 5. 非功能性需求
### 4.1 服务预约流程
### 5.1 性能要求
```plantuml
@startuml 服务预约流程
actor 客户 as Customer
participant "邮储银行\n服务开放平台" as Bank
participant "服务商系统" as Provider
participant "蓝色兄弟\n营销开放API" as LSB
database "服务商数据库" as DB
#### 5.1.1 响应时间要求
Customer -> Bank: 1.发起服务预约
activate Bank
| 接口类型 | P95 | P99 | 说明 |
|---------|-----|-----|------|
| 服务预约接口 | < 300ms | < 500ms | 含上游券码获取 |
| 服务取消接口 | < 200ms | < 400ms | 含上游券码作废 |
| 服务状态查询接口 | < 100ms | < 200ms | 优先读缓存 |
| 券码状态回调接口 | < 100ms | < 200ms | 快速响应后异步处理 |
Bank -> Provider: 2.调用预约接口\n(SM2/SM4加密)
activate Provider
#### 5.1.2 并发处理能力
Provider -> Provider: 3.解密验签\n校验权益码有效性
| 指标 | 要求 | 说明 |
|-----|------|------|
| 日常TPS | ≥ 100 | 正常业务峰值 |
| 峰值TPS | ≥ 500 | 活动期间峰值 |
| 单机QPS | ≥ 200 | 支持水平扩展 |
Provider -> LSB: 4.获取券码\n(RSA/AES加密)
activate LSB
#### 5.1.3 缓存设计
LSB -> LSB: 5.生成券码
**缓存策略**
LSB --> Provider: 6.返回券码信息\n(key/url)
deactivate LSB
| 缓存对象 | 缓存类型 | 过期策略 | 更新策略 | 说明 |
|---------|---------|---------|---------|------|
| 服务编码映射表 | 本地缓存 + Redis | 本地5分钟Redis 30分钟 | 配置变更主动刷新 | 高频读取,变更少 |
| 订单信息 | Redis | 24小时 | 状态变更时更新 | 按权益码缓存 |
| 券码信息 | Redis | 跟随订单 | 状态变更时更新 | 与订单关联存储 |
| 邮储AccessToken | Redis | 有效期前5分钟刷新 | 定时刷新 | 避免过期 |
Provider -> DB: 7.创建订单\n保存券码信息
activate DB
DB --> Provider: 8.保存成功
deactivate DB
**缓存Key设计**
Provider --> Bank: 9.返回预约成功\n(SM2/SM4加密)
deactivate Provider
```
# 服务编码映射
ycjfsc:service:mapping:{serviceType}
Bank --> Customer: 10.显示预约成功\n展示券码/链接
deactivate Bank
# 订单缓存(按权益码)
ycjfsc:order:code:{rightsCode}
@enduml
# 订单缓存(按订单号)
ycjfsc:order:no:{orderNo}
# AccessToken
ycjfsc:token:psbc
```
### 4.2 服务完成流程
**缓存穿透防护**
- 空值缓存查询不存在的数据时缓存空值过期时间60秒
- 布隆过滤器:权益码存在性预判(可选)
```plantuml
@startuml 服务完成流程
actor 客户 as Customer
participant "蓝色兄弟\n营销开放API" as LSB
participant "服务商系统" as Provider
participant "邮储银行\n服务开放平台" as Bank
database "服务商数据库" as DB
#### 5.1.4 高质量代码实现要求
Customer -> LSB: 1.使用券码核销
activate LSB
LSB -> LSB: 2.核销券码\n状态变更为已核销(2)
LSB -> Provider: 3.回调通知\n券码状态变更
activate Provider
Provider -> Provider: 4.验证回调签名
Provider -> DB: 5.更新券码状态
activate DB
DB --> Provider: 6.更新成功
deactivate DB
Provider --> LSB: 7.响应"ok"
deactivate LSB
Provider -> Bank: 8.通知服务完成\n(SM2/SM4加密)\n[T+2日内]
activate Bank
Bank -> Bank: 9.更新订单状态\n已预约(200)→已完成(300)
Bank --> Provider: 10.返回完成成功
deactivate Bank
Provider -> DB: 11.更新订单状态为300
deactivate Provider
@enduml
```
### 4.3 服务取消流程
```plantuml
@startuml 服务取消流程
actor 客户 as Customer
participant "邮储银行\n服务开放平台" as Bank
participant "服务商系统" as Provider
participant "蓝色兄弟\n营销开放API" as LSB
database "服务商数据库" as DB
Customer -> Bank: 1.发起服务取消
activate Bank
Bank -> Provider: 2.查询过期积分
activate Provider
Provider -> DB: 3.查询订单积分信息
activate DB
DB --> Provider: 4.返回积分信息
deactivate DB
Provider --> Bank: 5.返回过期积分信息
deactivate Provider
alt 存在过期幸福点
Bank --> Customer: 6a.提示"存在已过期幸福点\n取消后只退还未过期部分"
Customer -> Bank: 6b.确认取消
end
Bank -> Provider: 7.调用取消接口
activate Provider
Provider -> DB: 8.查询订单和券码
activate DB
DB --> Provider: 9.返回订单信息
deactivate DB
Provider -> LSB: 10.作废券码
activate LSB
LSB --> Provider: 11.作废成功
deactivate LSB
Provider -> DB: 12.更新订单状态为400
activate DB
DB --> Provider: 13.更新成功
deactivate DB
Provider --> Bank: 14.返回取消成功
deactivate Provider
Bank --> Customer: 15.显示取消成功\n已退还XX幸福点
deactivate Bank
@enduml
```
### 4.4 月度对账流程
```plantuml
@startuml 月度对账流程
participant "定时任务" as Scheduler
participant "服务商系统" as Provider
participant "邮储银行\n服务开放平台" as Bank
database "服务商数据库" as DB
Scheduler -> Provider: 1.每月3号触发对账任务
activate Provider
Provider -> Bank: 2.查询对账文件列表\n(上月已完成订单)
activate Bank
Bank --> Provider: 3.返回文件列表
deactivate Bank
Provider -> Bank: 4.下载对账文件
activate Bank
Bank --> Provider: 5.返回对账文件内容\n(SM4加密)
deactivate Bank
Provider -> Provider: 6.解密对账文件
Provider -> DB: 7.查询本地已完成订单
activate DB
DB --> Provider: 8.返回订单列表
deactivate DB
Provider -> Provider: 9.数据核对比对
alt 存在差异
Provider -> Provider: 10a.生成差异报告\n人工介入处理
else 无差异
Provider -> DB: 10b.更新对账状态为已对账
end
deactivate Provider
@enduml
```
### 4.5 错误处理流程
```plantuml
@startuml 错误处理流程
participant "调用方" as Caller
participant "服务商系统" as Provider
participant "下游服务" as Downstream
database "服务商数据库" as DB
Caller -> Provider: 1.发起请求
activate Provider
alt 参数校验失败
Provider --> Caller: 2a.返回参数错误\n(900001/900002)
else 签名验证失败
Provider --> Caller: 2b.返回签名错误\n(900005/900011)
else 权益码无效
Provider --> Caller: 2c.返回权益码错误\n(161026/161027)
else 业务规则不满足
Provider --> Caller: 2d.返回业务错误\n(161014/161024)
else 下游服务异常
Provider -> Downstream: 3.调用下游服务
activate Downstream
Downstream --> Provider: 4.返回异常
deactivate Downstream
Provider -> DB: 5.记录异常日志
Provider --> Caller: 6.返回系统繁忙\n(900000/990172)
else 处理成功
Provider -> Downstream: 3.调用下游服务
activate Downstream
Downstream --> Provider: 4.返回成功
deactivate Downstream
Provider -> DB: 5.更新业务数据
Provider --> Caller: 6.返回成功(000000)
end
deactivate Provider
@enduml
```
1. **连接池管理**HTTP客户端、数据库、Redis均需配置合理的连接池
2. **超时控制**所有外部调用设置合理超时连接超时3s读超时10s
3. **熔断降级**:上游服务异常时快速失败,避免雪崩
4. **异步处理**:非核心链路异步化(如日志记录、监控上报)
5. **批量操作**:对账等批量场景使用批量查询/更新
---
## 5. 用户故事
### 5.2 数据一致性要求
### 5.1 服务预约
#### 5.2.1 核心一致性场景
#### US-001: 预约虚拟商品服务
**场景描述**:蓝色兄弟券码已核销(用户已完成充值兑换),必须通知邮储银行服务完成,否则会造成资金损失。
**As a** 邮储银行高端客户
**I want** 使用幸福点兑换的权益码预约虚拟商品服务
**So that** 我可以获得虚拟商品券码并使用
**风险点**
- 回调通知邮储失败
- 回调成功但本地状态更新失败
- 系统宕机导致通知丢失
**Acceptance Criteria**:
- [ ] Given 有效的权益码20分钟内When 调用预约接口Then 返回预约成功并获得券码
- [ ] Given 权益码已超过20分钟有效期When 调用预约接口Then 返回161026错误码
- [ ] Given 相同的业务主ID重复请求When 调用预约接口Then 返回幂等结果
#### 5.2.2 一致性保障机制
**机制一:本地事务 + 可靠消息**
```
1. 接收蓝色兄弟核销回调
2. 本地事务:
- 更新订单状态为「待通知」(250)
- 写入待通知消息表
3. 响应蓝色兄弟"ok"
4. 异步消息消费:
- 调用邮储服务完成接口
- 成功:更新订单状态为「已完成」(300)
- 失败:保留状态,等待重试
```
**机制二:消息重试策略**
| 重试次数 | 间隔时间 | 累计时间 |
|---------|---------|----------|
| 第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次仍失败标记为「通知异常」(350),人工介入处理。
**机制三:定时补偿任务**
| 任务 | 执行频率 | 处理逻辑 |
|-----|---------|----------|
| 待通知订单扫描 | 每5分钟 | 扫描状态=250且超过1分钟未处理的订单重新发起通知 |
| 异常订单告警 | 每10分钟 | 扫描状态=350的订单发送告警通知 |
| 券码状态同步 | 每小时 | 查询蓝色兄弟券码状态,同步本地订单状态 |
**机制四:对账兜底**
- 每日凌晨对账:比对本地「已核销」订单与邮储「已完成」状态
- 发现不一致:自动重新发起服务完成通知
- 月度对账:与邮储对账文件核对,确保无遗漏
#### 5.2.3 订单状态扩展
为支持一致性保障,扩展订单状态:
| 状态码 | 状态名称 | 说明 |
|-------|---------|------|
| 100 | 服务未预约 | 已兑换但未预约 |
| 200 | 服务已预约 | 已预约待使用 |
| 250 | 待通知邮储 | 券码已核销,待通知邮储 |
| 300 | 服务已完成 | 券码已核销且已通知邮储 |
| 350 | 通知异常 | 通知邮储多次失败,需人工处理 |
| 400 | 服务已取消 | 用户主动取消 |
| 500 | 服务已过期 | 超过有效期未使用 |
#### 5.2.4 幂等性设计
| 接口/操作 | 幂等键 | 幂等策略 |
|----------|-------|----------|
| 服务预约 | 权益码(code) | 相同权益码重复请求返回相同结果 |
| 服务取消 | 权益码(rightsCode) | 已取消订单重复请求直接返回成功 |
| 服务完成通知 | 权益码(rightsCode) | 已完成订单重复请求直接返回成功 |
| 券码获取 | 外部业务号(out_biz_no) | 相同业务号返回相同券码 |
| 回调处理 | 交易号(trade_no) | 相同交易号仅处理一次 |
#### 5.2.5 数据一致性监控
**告警指标**
| 指标 | 阈值 | 告警级别 |
|-----|------|----------|
| 待通知订单积压 | > 10笔 | P2 |
| 通知异常订单 | > 0笔 | P1 |
| 通知失败率 | > 1% | P2 |
| 对账差异 | > 0笔 | P1 |
---
### 5.2 服务取消
### 5.3 可用性要求
#### US-002: 取消已预约服务
**As a** 邮储银行高端客户
**I want** 取消已预约但未使用的服务
**So that** 我可以退回幸福点
**Acceptance Criteria**:
- [ ] Given 订单状态为已预约(200)When 调用取消接口Then 券码被作废订单状态变为400幸福点退还
- [ ] Given 订单状态为已完成(300)When 调用取消接口Then 返回161014错误码
- [ ] Given 存在已过期幸福点When 取消前查询Then 返回过期积分提醒信息
| 指标 | 要求 |
|-----|------|
| 系统可用性 | ≥ 99.9% |
| 单点故障 | 无单点,支持多实例部署 |
| 故障恢复 | RTO < 5分钟RPO = 0 |
---
### 5.3 服务完成
### 5.4 安全要求
#### US-003: 券码核销后服务完成
**As a** 服务商系统
**I want** 在收到券码核销回调后通知邮储银行服务完成
**So that** 完成服务状态同步,确保对账数据一致
**Acceptance Criteria**:
- [ ] Given 收到蓝色兄弟核销回调(status=2)When 处理回调Then 在T+2日内通知邮储银行服务完成
- [ ] Given 订单状态为已取消(400)When 通知服务完成Then 邮储银行返回161014错误
- [ ] Given 回调验签失败When 处理回调Then 不触发服务完成通知
1. **传输安全**所有外部通信使用HTTPS
2. **数据脱敏**:日志中客户敏感信息脱敏处理
3. **密钥管理**:加密密钥通过配置中心管理,定期轮换
4. **访问控制**:接口签名验证,防止非法调用
---
### 5.4 服务状态查询
## 6. 流程图
#### US-004: 查询服务状态
### 6.1 服务预约流程
**As a** 邮储银行服务开放平台
**I want** 查询权益服务当前状态
**So that** 展示给客户了解服务进展
**Acceptance Criteria**:
- [ ] Given 有效的权益码When 调用状态查询接口Then 返回正确的状态码和描述
- [ ] Given 不存在的权益码When 调用状态查询接口Then 返回161027错误码
TODO
---
### 5.5 月度对账
### 6.2 服务完成流程
#### US-005: 下载并核对对账文件
TODO
**As a** 服务商运营人员
**I want** 每月下载邮储银行的对账文件并与本地数据核对
**So that** 确保交易数据一致性,完成结算
---
**Acceptance Criteria**:
- [ ] Given 每月3号When 触发对账任务Then 自动下载上月对账文件
- [ ] Given 对账文件下载成功When 数据核对Then 生成对账结果(匹配/差异)
- [ ] Given 存在对账差异When 核对完成Then 生成差异报告供人工处理
### 6.3 服务取消流程
TODO
---
### 6.4 月度对账流程
TODO
---
### 6.5 错误处理流程
TODO
---