diff --git a/docs/需求文档-PRD.md b/docs/需求文档-PRD.md index 712527e..086c15d 100644 --- a/docs/需求文档-PRD.md +++ b/docs/需求文档-PRD.md @@ -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 ---