|
@@ -48,7 +48,7 @@
|
|
|
|
|
|
|
|
- 每个门店使用独立的 `MerchantID / HashKey / HashIV`,不使用平台统一凭证。
|
|
- 每个门店使用独立的 `MerchantID / HashKey / HashIV`,不使用平台统一凭证。
|
|
|
- 不传 `PlatformID`。
|
|
- 不传 `PlatformID`。
|
|
|
-- `ChoosePayment` 固定为 `ALL`,并发送 `IgnorePayment=ATM#CVS#BarcodeATM`;OMG 商户侧必须关闭 AFTEE 等代码无法过滤的渠道,最终在官方选择页面保留信用卡与已开通且设备支持的 Apple Pay。
|
|
|
|
|
|
|
+- App 在进入 OMG 前只提供 `CREDIT` 与 `APPLE_PAY` 两个受控选项;服务端分别映射为 `ChoosePayment=Credit + UnionPay=2` 与 `ChoosePayment=ApplePay`,不再进入 OMG 的 `ALL` 付款方式选择页。
|
|
|
- 客户端在当前页面提交表单,不使用 iframe,不打开新窗口。
|
|
- 客户端在当前页面提交表单,不使用 iframe,不打开新窗口。
|
|
|
- 当前仅接 OMG 测试环境。
|
|
- 当前仅接 OMG 测试环境。
|
|
|
- 新可信公开路径继续使用 `/pay/omg/*`;创建入口为 `POST /pay/omg/create`,可信回调为 `POST /pay/omg/notify`。
|
|
- 新可信公开路径继续使用 `/pay/omg/*`;创建入口为 `POST /pay/omg/create`,可信回调为 `POST /pay/omg/notify`。
|
|
@@ -62,7 +62,7 @@
|
|
|
|
|
|
|
|
### User Story 1 - 首次创建并进入 OMG 收银台 (Priority: P1)
|
|
### User Story 1 - 首次创建并进入 OMG 收银台 (Priority: P1)
|
|
|
|
|
|
|
|
-已登录用户为自己的单门店餐饮订单选择 OMG 后,调用创建接口并取得由服务端签名的表单。客户端在当前页面 POST 该表单,进入对应门店的 OMG 测试收银台;服务端通过 `ChoosePayment=ALL` 与 `IgnorePayment=ATM#CVS#BarcodeATM` 隐藏可由代码过滤的渠道,并保留信用卡与 Apple Pay。
|
|
|
|
|
|
|
+已登录用户为自己的单门店餐饮订单选择 OMG 后,先在 App 选择信用卡或 Apple Pay,再调用创建接口取得对应渠道的服务端签名表单。客户端在当前页面 POST 该表单,直接进入所选 OMG 测试付款流程,不展示包含超商快付或 AFTEE 的 OMG `ALL` 付款方式选择页。
|
|
|
|
|
|
|
|
**Why this priority**: 这是进入 OMG 收银台的基础,也是本期最终付款回调及后续查询、退款的前置能力。
|
|
**Why this priority**: 这是进入 OMG 收银台的基础,也是本期最终付款回调及后续查询、退款的前置能力。
|
|
|
|
|
|
|
@@ -72,8 +72,9 @@
|
|
|
|
|
|
|
|
1. **Given** 用户拥有一笔 `payType="2"`、未取消、未付款、金额为正的单门店订单,且门店 OMG 凭证已启用,**When** 用户首次调用创建接口,**Then** 系统创建唯一支付尝试并返回可提交的 OMG 表单。
|
|
1. **Given** 用户拥有一笔 `payType="2"`、未取消、未付款、金额为正的单门店订单,且门店 OMG 凭证已启用,**When** 用户首次调用创建接口,**Then** 系统创建唯一支付尝试并返回可提交的 OMG 表单。
|
|
|
2. **Given** 创建接口返回成功,**When** 客户端在当前页面向 `gatewayUrl` POST 全部 `formFields`,**Then** 浏览器进入 OMG 测试收银台,不通过 iframe 或新窗口加载。
|
|
2. **Given** 创建接口返回成功,**When** 客户端在当前页面向 `gatewayUrl` POST 全部 `formFields`,**Then** 浏览器进入 OMG 测试收银台,不通过 iframe 或新窗口加载。
|
|
|
-3. **Given** 门店已开通信用卡、Apple Pay、ATM、CVS 和 BarcodeATM,且商户侧已关闭 AFTEE,**When** 收银台接收 `ChoosePayment=ALL` 与 `IgnorePayment=ATM#CVS#BarcodeATM`,**Then** OMG 页面隐藏 ATM、CVS 和 BarcodeATM,并保留信用卡与当前设备支持的 Apple Pay。
|
|
|
|
|
-4. **Given** 门店未开通 Apple Pay 或当前设备环境不支持 Apple Pay,**When** 进入收银台,**Then** 页面仍可显示信用卡;系统不得通过前端 CSS、DOM 注入或未公开 OMG 参数篡改第三方支付页面。
|
|
|
|
|
|
|
+3. **Given** 用户选择信用卡,**When** 创建并提交表单,**Then** 服务端发送并签名 `ChoosePayment=Credit` 与 `UnionPay=2`,页面不得显示超商快付、AFTEE、Apple Pay 或银联选择项。
|
|
|
|
|
+4. **Given** 用户选择 Apple Pay,且门店与设备支持 Apple Pay,**When** 创建并提交表单,**Then** 服务端只发送并签名 `ChoosePayment=ApplePay`,直接进入 Apple Pay 流程,不显示信用卡、超商快付或 AFTEE 选择项。
|
|
|
|
|
+5. **Given** `paymentMethod` 缺失或不属于 `CREDIT/APPLE_PAY`,**When** 调用 create 或 retry,**Then** 服务端返回稳定错误 `PAYMENT_METHOD_INVALID`,且不创建或替换支付尝试。
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
@@ -99,12 +100,12 @@
|
|
|
|
|
|
|
|
**Why this priority**: 创建错误门店、错误金额或泄露密钥会形成直接资金风险。
|
|
**Why this priority**: 创建错误门店、错误金额或泄露密钥会形成直接资金风险。
|
|
|
|
|
|
|
|
-**Independent Test**: 分别使用无效 token、他人订单、终态订单、异常金额、错误支付类型、无凭证门店和非测试网关配置调用接口,均被拒绝且不写入尝试表。
|
|
|
|
|
|
|
+**Independent Test**: 分别使用无效 token、他人订单、终态订单、异常金额、错误支付类型、非法 `paymentMethod`、无凭证门店和非测试网关配置调用接口,均被拒绝且不写入尝试表。
|
|
|
|
|
|
|
|
**Acceptance Scenarios**:
|
|
**Acceptance Scenarios**:
|
|
|
|
|
|
|
|
1. **Given** 请求用户不是订单所有者,**When** 调用创建接口,**Then** 系统拒绝且不透露订单或门店支付详情。
|
|
1. **Given** 请求用户不是订单所有者,**When** 调用创建接口,**Then** 系统拒绝且不透露订单或门店支付详情。
|
|
|
-2. **Given** 订单已取消、已付款、金额不大于零、不是单门店订单或 `payType` 不是 `"2"`,**When** 调用创建接口,**Then** 系统返回国际化业务错误且不创建尝试。
|
|
|
|
|
|
|
+2. **Given** 订单已取消、已付款、金额不大于零、不是单门店订单、`payType` 不是 `"2"` 或 `paymentMethod` 非法,**When** 调用创建接口,**Then** 系统返回国际化业务错误且不创建尝试。
|
|
|
3. **Given** 门店没有已启用 OMG 凭证,**When** 调用创建接口,**Then** 系统拒绝且不创建尝试。
|
|
3. **Given** 门店没有已启用 OMG 凭证,**When** 调用创建接口,**Then** 系统拒绝且不创建尝试。
|
|
|
4. **Given** 服务配置不是允许的 OMG 测试端点,**When** 调用创建接口,**Then** 系统拒绝生成表单。
|
|
4. **Given** 服务配置不是允许的 OMG 测试端点,**When** 调用创建接口,**Then** 系统拒绝生成表单。
|
|
|
5. **Given** 创建成功或失败,**When** 检查 API 响应和应用日志,**Then** 所有响应和日志均不存在 `HashKey`、`HashIV`;完整 `CheckMacValue` 与签名表单只存在于订单本人获准取得的创建成功响应,不出现在错误响应或日志中。
|
|
5. **Given** 创建成功或失败,**When** 检查 API 响应和应用日志,**Then** 所有响应和日志均不存在 `HashKey`、`HashIV`;完整 `CheckMacValue` 与签名表单只存在于订单本人获准取得的创建成功响应,不出现在错误响应或日志中。
|
|
@@ -177,7 +178,7 @@ iOS 用户在 OMG 收银台完成或结束支付流程后,OMG 加载后端 `/p
|
|
|
- **FR-042**: `POST /pay/omg/refund` MUST 需要 token,并以显式 JSON DTO 只接收 `orderId`;不得接收客户端提供的金额、交易号、Action、凭证或地址。
|
|
- **FR-042**: `POST /pay/omg/refund` MUST 需要 token,并以显式 JSON DTO 只接收 `orderId`;不得接收客户端提供的金额、交易号、Action、凭证或地址。
|
|
|
- **FR-043**: 当前测试阶段退款 MUST 返回 `PAYMENT_REFUND_UNAVAILABLE_IN_TEST_ENVIRONMENT`,MUST NOT 调用 OMG 正式 `CreditDetail/DoAction`、查询或写入任何订单/支付/退款状态。
|
|
- **FR-043**: 当前测试阶段退款 MUST 返回 `PAYMENT_REFUND_UNAVAILABLE_IN_TEST_ENVIRONMENT`,MUST NOT 调用 OMG 正式 `CreditDetail/DoAction`、查询或写入任何订单/支付/退款状态。
|
|
|
- **FR-044**: 测试环境退款拒绝 MUST 提供五套 i18n 提示和必要的脱敏日志;日志不得记录 token、凭证或完整支付签名。
|
|
- **FR-044**: 测试环境退款拒绝 MUST 提供五套 i18n 提示和必要的脱敏日志;日志不得记录 token、凭证或完整支付签名。
|
|
|
-- **FR-045**: 系统 MUST 提供 `POST /pay/omg/retry`,使用 token 和只含 `orderId` 的显式 JSON DTO;客户端不得提交旧 `MerchantTradeNo`、支付方式、金额、凭证、网关地址或旧表单。
|
|
|
|
|
|
|
+- **FR-045**: 系统 MUST 提供 `POST /pay/omg/retry`,使用 token 和只含 `orderId`、`paymentMethod` 的显式 JSON DTO;`paymentMethod` 仅允许 `CREDIT/APPLE_PAY`。客户端不得提交旧 `MerchantTradeNo`、OMG 原始支付参数、金额、凭证、网关地址或旧表单。
|
|
|
- **FR-046**: retry MUST 先复用可信 query 查询 OMG 实际状态;查询失败、响应不可信或状态为 `UNKNOWN` 时不得修改尝试或创建新表单。
|
|
- **FR-046**: retry MUST 先复用可信 query 查询 OMG 实际状态;查询失败、响应不可信或状态为 `UNKNOWN` 时不得修改尝试或创建新表单。
|
|
|
- **FR-047**: query 确认 `PAID` 时 retry MUST 返回 `ORDER_ALREADY_PAID`;确认 `FAILED` 时 MAY 创建新尝试;确认 `UNPAID` 时仅当 `paymentType` 为空才 MAY 替换旧尝试。
|
|
- **FR-047**: query 确认 `PAID` 时 retry MUST 返回 `ORDER_ALREADY_PAID`;确认 `FAILED` 时 MAY 创建新尝试;确认 `UNPAID` 时仅当 `paymentType` 为空才 MAY 替换旧尝试。
|
|
|
- **FR-048**: 替换未付款尝试 MUST 在同一事务内锁定订单,精确比较 query 已验证的 `MerchantTradeNo` 与当前活动尝试,把该行原子更新为 `SUPERSEDED` 后再生成新交易号和新表单;任一条件变化 MUST 返回 `PAYMENT_RETRY_NOT_AVAILABLE`。
|
|
- **FR-048**: 替换未付款尝试 MUST 在同一事务内锁定订单,精确比较 query 已验证的 `MerchantTradeNo` 与当前活动尝试,把该行原子更新为 `SUPERSEDED` 后再生成新交易号和新表单;任一条件变化 MUST 返回 `PAYMENT_RETRY_NOT_AVAILABLE`。
|
|
@@ -198,20 +199,20 @@ iOS 用户在 OMG 收银台完成或结束支付流程后,OMG 加载后端 `/p
|
|
|
- **FR-002**: 系统 MUST 新建 `com.ruoyi.system.omgpay` 下的支付尝试 Entity、Mapper 和 Service;新支付尝试 MUST 使用 `pos_order_omg_attempt`,不得读取或写入旧 OMG 支付流水表。
|
|
- **FR-002**: 系统 MUST 新建 `com.ruoyi.system.omgpay` 下的支付尝试 Entity、Mapper 和 Service;新支付尝试 MUST 使用 `pos_order_omg_attempt`,不得读取或写入旧 OMG 支付流水表。
|
|
|
- **FR-003**: 系统 MAY 复用现有 `pos_store_omg` 门店凭证查询实现,且这是唯一允许复用的旧 OMG 实现;新创建流程 MUST 按订单门店读取该门店已启用的 `MerchantID / HashKey / HashIV`。
|
|
- **FR-003**: 系统 MAY 复用现有 `pos_store_omg` 门店凭证查询实现,且这是唯一允许复用的旧 OMG 实现;新创建流程 MUST 按订单门店读取该门店已启用的 `MerchantID / HashKey / HashIV`。
|
|
|
- **FR-004**: 系统 MUST 保持公开创建入口为 `POST /pay/omg/create`,使用 `@RequestHeader String token` 和显式 `@RequestBody` DTO;Controller 入参不得使用 Map,DTO 不使用 Bean Validation 注解。
|
|
- **FR-004**: 系统 MUST 保持公开创建入口为 `POST /pay/omg/create`,使用 `@RequestHeader String token` 和显式 `@RequestBody` DTO;Controller 入参不得使用 Map,DTO 不使用 Bean Validation 注解。
|
|
|
-- **FR-005**: 创建请求 DTO MUST 只接收 `orderId`;金额、门店、用户、支付类型、说明文字、网关地址、回调地址和支付渠道均必须由服务端决定。
|
|
|
|
|
|
|
+- **FR-005**: 创建请求 DTO MUST 只接收 `orderId` 与 `paymentMethod`;`paymentMethod` 仅允许 `CREDIT/APPLE_PAY`。金额、门店、用户、订单支付类型、说明文字、网关地址、回调地址及原始 OMG 参数均必须由服务端决定。
|
|
|
- **FR-006**: 系统 MUST 校验登录用户为订单所有者,订单为单门店订单、未取消、未付款、未完成、金额为正且 `PosOrder.payType="2"`;任何校验失败 MUST NOT 创建支付尝试。
|
|
- **FR-006**: 系统 MUST 校验登录用户为订单所有者,订单为单门店订单、未取消、未付款、未完成、金额为正且 `PosOrder.payType="2"`;任何校验失败 MUST NOT 创建支付尝试。
|
|
|
- **FR-007**: 系统 MUST 使用订单的整数新台币金额作为 `TotalAmount`,不得接受或信任客户端金额。
|
|
- **FR-007**: 系统 MUST 使用订单的整数新台币金额作为 `TotalAmount`,不得接受或信任客户端金额。
|
|
|
- **FR-008**: 系统 MUST 仅允许创建表单到 `https://payment-stage.funpoint.com.tw/Cashier/AioCheckOut/V5`;第一阶段不得配置或回退到正式环境。
|
|
- **FR-008**: 系统 MUST 仅允许创建表单到 `https://payment-stage.funpoint.com.tw/Cashier/AioCheckOut/V5`;第一阶段不得配置或回退到正式环境。
|
|
|
- **FR-009**: 系统 MUST 为每次新尝试生成全局唯一、不可复用、长度不超过 20 且只含 ASCII 英数字的 `MerchantTradeNo`;不得从业务订单号直接派生可冲突或超长的编号。
|
|
- **FR-009**: 系统 MUST 为每次新尝试生成全局唯一、不可复用、长度不超过 20 且只含 ASCII 英数字的 `MerchantTradeNo`;不得从业务订单号直接派生可冲突或超长的编号。
|
|
|
- **FR-010**: 同一业务订单在任一时刻 MUST 最多存在一条未结束 OMG 尝试;顺序重复或并发创建 MUST 返回业务状态 `PAYMENT_ATTEMPT_EXISTS`,不得返回旧表单、重复提交旧编号或创建新编号。
|
|
- **FR-010**: 同一业务订单在任一时刻 MUST 最多存在一条未结束 OMG 尝试;顺序重复或并发创建 MUST 返回业务状态 `PAYMENT_ATTEMPT_EXISTS`,不得返回旧表单、重复提交旧编号或创建新编号。
|
|
|
- **FR-011**: 在可信查询尚未实现前,系统 MUST NOT 基于固定分钟窗口、本地创建时间或用户再次点击自动结束 `CREATED` 尝试。
|
|
- **FR-011**: 在可信查询尚未实现前,系统 MUST NOT 基于固定分钟窗口、本地创建时间或用户再次点击自动结束 `CREATED` 尝试。
|
|
|
-- **FR-012**: 创建表单 MUST 发送以下字段和值:`MerchantID`、`MerchantTradeNo`、`MerchantTradeDate`、`PaymentType=aio`、`TotalAmount`、`TradeDesc`、`ItemName`、`ReturnURL`、`OrderResultURL`、`ChoosePayment=ALL`、`IgnorePayment=ATM#CVS#BarcodeATM`、`EncryptType=1`、`InvoiceMark=N`、`NeedExtraPaidInfo=Y` 和 `CheckMacValue`。
|
|
|
|
|
-- **FR-013**: 创建表单 MUST NOT 发送 `PlatformID`、`PaymentInfoURL`、`ClientRedirectURL`、`ClientBackURL`、`Language`、`UnionPay`、ATM/CVS/BarcodeATM 期限字段、分期、定期定额或记忆卡号参数。
|
|
|
|
|
|
|
+- **FR-012**: 创建表单公共字段 MUST 包含 `MerchantID`、`MerchantTradeNo`、`MerchantTradeDate`、`PaymentType=aio`、`TotalAmount`、`TradeDesc`、`ItemName`、`ReturnURL`、`OrderResultURL`、`EncryptType=1`、`InvoiceMark=N`、`NeedExtraPaidInfo=Y` 和 `CheckMacValue`。`CREDIT` 额外固定发送 `ChoosePayment=Credit`、`UnionPay=2`;`APPLE_PAY` 额外固定发送 `ChoosePayment=ApplePay` 且不发送 `UnionPay`。
|
|
|
|
|
+- **FR-013**: 创建表单 MUST NOT 发送 `ChoosePayment=ALL`、`IgnorePayment`、`PlatformID`、`PaymentInfoURL`、`ClientRedirectURL`、`ClientBackURL`、`Language`、ATM/CVS/BarcodeATM 期限字段、分期、定期定额或记忆卡号参数;`APPLE_PAY` 也 MUST NOT 发送仅适用于信用卡的 `UnionPay`。
|
|
|
- **FR-014**: `MerchantTradeDate` MUST 以 `Asia/Taipei` 时区格式化为 `yyyy/MM/dd HH:mm:ss`。
|
|
- **FR-014**: `MerchantTradeDate` MUST 以 `Asia/Taipei` 时区格式化为 `yyyy/MM/dd HH:mm:ss`。
|
|
|
- **FR-015**: `TradeDesc` 和 `ItemName` MUST 由服务端生成,禁止 HTML,符合 OMG 字符及长度限制;`ItemName` 不得超过中文 60 字或英数字 120 字的官方显示限制,字段总长度不得超过官方 `String(200)` 限制。
|
|
- **FR-015**: `TradeDesc` 和 `ItemName` MUST 由服务端生成,禁止 HTML,符合 OMG 字符及长度限制;`ItemName` 不得超过中文 60 字或英数字 120 字的官方显示限制,字段总长度不得超过官方 `String(200)` 限制。
|
|
|
- **FR-016**: `ReturnURL` MUST 是受控 HTTPS 地址并固定以 `/pay/omg/notify` 结尾;该路径 MUST 由新的 `omgpay` Controller 处理,不得被旧 Controller 接收。
|
|
- **FR-016**: `ReturnURL` MUST 是受控 HTTPS 地址并固定以 `/pay/omg/notify` 结尾;该路径 MUST 由新的 `omgpay` Controller 处理,不得被旧 Controller 接收。
|
|
|
- **FR-017**: `CheckMacValue` MUST 严格按 OMG 官方规则生成:排除 `CheckMacValue` 本身,将其余全部实际发送字段按官方字母顺序排序,以 `&` 串接,前置 `HashKey=...&`、后置 `&HashIV=...`,执行符合官方 .NET 表的 URL 编码并转小写,使用 SHA-256,最后输出大写十六进制。
|
|
- **FR-017**: `CheckMacValue` MUST 严格按 OMG 官方规则生成:排除 `CheckMacValue` 本身,将其余全部实际发送字段按官方字母顺序排序,以 `&` 串接,前置 `HashKey=...&`、后置 `&HashIV=...`,执行符合官方 .NET 表的 URL 编码并转小写,使用 SHA-256,最后输出大写十六进制。
|
|
|
-- **FR-018**: 除 `CheckMacValue` 自身外,创建请求实际发送的全部字段 MUST 参加签名,包括 `OrderResultURL`、`ChoosePayment=ALL`、`IgnorePayment=ATM#CVS#BarcodeATM` 和 `NeedExtraPaidInfo=Y`;不得挑选所谓核心字段计算。
|
|
|
|
|
|
|
+- **FR-018**: 除 `CheckMacValue` 自身外,创建请求实际发送的全部字段 MUST 参加签名,包括 `OrderResultURL`、所选渠道对应的 `ChoosePayment`、信用卡渠道的 `UnionPay=2` 和 `NeedExtraPaidInfo=Y`;不得挑选所谓核心字段计算。
|
|
|
- **FR-019**: 回调 MUST 遵守同一完整字段原则:除 `CheckMacValue` 外,OMG 实际返回的全部字段均参加验签;启用 `NeedExtraPaidInfo=Y` 后,全部额外回传字段、未知字段及空值字段也必须进入验签集合。重复参数名必须作为非法请求拒绝,不得静默选取其中一个值。
|
|
- **FR-019**: 回调 MUST 遵守同一完整字段原则:除 `CheckMacValue` 外,OMG 实际返回的全部字段均参加验签;启用 `NeedExtraPaidInfo=Y` 后,全部额外回传字段、未知字段及空值字段也必须进入验签集合。重复参数名必须作为非法请求拒绝,不得静默选取其中一个值。
|
|
|
- **FR-020**: 创建成功响应 MUST 使用明确对象 `{status, gatewayUrl, formFields}`;`status` 固定为 `CREATED`,`gatewayUrl` 为测试 AioCheckOut 端点,`formFields` 含实际需要 POST 的全部字段但不含 `gatewayUrl`。
|
|
- **FR-020**: 创建成功响应 MUST 使用明确对象 `{status, gatewayUrl, formFields}`;`status` 固定为 `CREATED`,`gatewayUrl` 为测试 AioCheckOut 端点,`formFields` 含实际需要 POST 的全部字段但不含 `gatewayUrl`。
|
|
|
- **FR-021**: 客户端 MUST 在当前页面以 `application/x-www-form-urlencoded` 表单 POST 全部 `formFields` 到 `gatewayUrl`;不得使用 iframe,不得另开新窗口,不得把响应转换为 GET 查询链接。
|
|
- **FR-021**: 客户端 MUST 在当前页面以 `application/x-www-form-urlencoded` 表单 POST 全部 `formFields` 到 `gatewayUrl`;不得使用 iframe,不得另开新窗口,不得把响应转换为 GET 查询链接。
|
|
@@ -248,7 +249,8 @@ Content-Type: application/json
|
|
|
token: <login-token>
|
|
token: <login-token>
|
|
|
|
|
|
|
|
{
|
|
{
|
|
|
- "orderId": "991786433092835"
|
|
|
|
|
|
|
+ "orderId": "991786433092835",
|
|
|
|
|
+ "paymentMethod": "CREDIT"
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
@@ -268,8 +270,8 @@ token: <login-token>
|
|
|
"ItemName": "Order 991786433092835",
|
|
"ItemName": "Order 991786433092835",
|
|
|
"ReturnURL": "https://example.test/pay/omg/notify",
|
|
"ReturnURL": "https://example.test/pay/omg/notify",
|
|
|
"OrderResultURL": "https://example.test/pay/omg/result",
|
|
"OrderResultURL": "https://example.test/pay/omg/result",
|
|
|
- "ChoosePayment": "ALL",
|
|
|
|
|
- "IgnorePayment": "ATM#CVS#BarcodeATM",
|
|
|
|
|
|
|
+ "ChoosePayment": "Credit",
|
|
|
|
|
+ "UnionPay": "2",
|
|
|
"EncryptType": "1",
|
|
"EncryptType": "1",
|
|
|
"InvoiceMark": "N",
|
|
"InvoiceMark": "N",
|
|
|
"NeedExtraPaidInfo": "Y",
|
|
"NeedExtraPaidInfo": "Y",
|
|
@@ -278,7 +280,7 @@ token: <login-token>
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-`HashKey` 和 `HashIV` 永远不属于响应。外层继续使用项目现有 `AjaxResult` 成功/失败封装;上例只定义 `data` 契约。
|
|
|
|
|
|
|
+`HashKey` 和 `HashIV` 永远不属于响应。上例是 `paymentMethod=CREDIT` 的响应;`paymentMethod=APPLE_PAY` 时 `ChoosePayment=ApplePay`,且不包含 `UnionPay` 或 `IgnorePayment`。外层继续使用项目现有 `AjaxResult` 成功/失败封装;上例只定义 `data` 契约。
|
|
|
|
|
|
|
|
#### Existing-attempt failure
|
|
#### Existing-attempt failure
|
|
|
|
|
|
|
@@ -378,7 +380,7 @@ token: <login-token>
|
|
|
|
|
|
|
|
- 使用门店测试凭证调用 `POST /pay/omg/create`。
|
|
- 使用门店测试凭证调用 `POST /pay/omg/create`。
|
|
|
- 在当前页面将全部 `formFields` POST 到返回的测试 `gatewayUrl`。
|
|
- 在当前页面将全部 `formFields` POST 到返回的测试 `gatewayUrl`。
|
|
|
-- 确认进入 OMG 测试收银台,金额、商品说明和 `ALL` 可用渠道显示正确。
|
|
|
|
|
|
|
+- 分别使用 `CREDIT` 与 `APPLE_PAY` 创建并提交表单,确认直接进入所选 OMG 测试付款流程;不得出现超商快付或 AFTEE 选择项。
|
|
|
- 确认不使用 iframe 或新窗口。
|
|
- 确认不使用 iframe 或新窗口。
|
|
|
- 创建和付款结果回调按本规格完成;查询、补单、取号、退款与推送不作为本阶段完成标准。
|
|
- 创建和付款结果回调按本规格完成;查询、补单、取号、退款与推送不作为本阶段完成标准。
|
|
|
|
|
|
|
@@ -390,7 +392,7 @@ token: <login-token>
|
|
|
- **SC-002**: 官方 AioCheckOut 签名向量自动化测试与官方 `CheckMacValue` 完全一致。
|
|
- **SC-002**: 官方 AioCheckOut 签名向量自动化测试与官方 `CheckMacValue` 完全一致。
|
|
|
- **SC-003**: 实际发送的每一个非 `CheckMacValue` 字段均由测试证明参与签名,额外字段与空值字段不会被签名器丢弃。
|
|
- **SC-003**: 实际发送的每一个非 `CheckMacValue` 字段均由测试证明参与签名,额外字段与空值字段不会被签名器丢弃。
|
|
|
- **SC-004**: 对同一订单进行顺序或并发重复创建时,数据库未结束尝试数始终不超过 1,第二个 `MerchantTradeNo` 产生率为 0。
|
|
- **SC-004**: 对同一订单进行顺序或并发重复创建时,数据库未结束尝试数始终不超过 1,第二个 `MerchantTradeNo` 产生率为 0。
|
|
|
-- **SC-005**: 未授权、非法状态、非法金额、错误支付类型、无凭证和非测试环境请求的尝试写入数为 0。
|
|
|
|
|
|
|
+- **SC-005**: 未授权、非法状态、非法金额、错误支付类型、非法 `paymentMethod`、无凭证和非测试环境请求的尝试写入数为 0。
|
|
|
- **SC-006**: 新 OMG 创建链路中对旧支付 Controller、旧工具类和旧支付流水服务的引用数为 0;对旧支付表的 SQL 访问数为 0。
|
|
- **SC-006**: 新 OMG 创建链路中对旧支付 Controller、旧工具类和旧支付流水服务的引用数为 0;对旧支付表的 SQL 访问数为 0。
|
|
|
- **SC-007**: 旧 OMG Controller、旧补单/退款入口和旧定时任务的可达运行入口数为 0;`/pay/omg/create` 只映射到新 Controller。
|
|
- **SC-007**: 旧 OMG Controller、旧补单/退款入口和旧定时任务的可达运行入口数为 0;`/pay/omg/create` 只映射到新 Controller。
|
|
|
- **SC-008**: API 响应及应用日志中的登录 token、`HashKey`、`HashIV` 泄露数为 0;错误响应和应用日志中的完整 `CheckMacValue` 或完整签名表单泄露数为 0。
|
|
- **SC-008**: API 响应及应用日志中的登录 token、`HashKey`、`HashIV` 泄露数为 0;错误响应和应用日志中的完整 `CheckMacValue` 或完整签名表单泄露数为 0。
|