# wechat-payment Specification ## Purpose 定义 PRI-MP-PAY-001 微信支付基础、支付结果与异常查询的正式能力边界。该规格约束统一支付契约、支付确认、支付状态查询、交易详情/票据查询和异常撤销:真实下单、`wx.requestPayment` 和 `130994` 撤销按旧版链路开放,只能由用户在页面明确确认后执行,页面生命周期不得自动触发。 ## Requirements ### Requirement: REQ-PAY-001-01 PAY-001 微信支付契约 系统 MUST 以旧版业务类型对应的真实嵌套报文实现支付,并提供从业务订单到服务端最终状态的完整正式支付闭环。 - MUST:挂号业务按 `03100090` 校验、`03050234` 锁号、`01050002` 预结算、`wx.requestPayment`、`130980` 状态确认的顺序执行;任何一步失败 SHALL 停止后续动作并保留可恢复提示。 - MUST:按业务类型构造旧版 `01050002` 业务体;挂号使用 `REGPAY` 与 `03100041` 嵌套体,其他支付业务使用其对应的 `99070009`、`99070016`、`99070044`、`17090005` 或咨询业务体,不得以同一个扁平 payload 替代。 - MUST:`01050002` 的网关外层 `params` MUST 直接承载旧版预结算业务对象;不得将 `{ params: [...] }` 再包装为一项 `params`。挂号业务的 `03100041` 嵌套体、`orderNo`、`resModelLocID`、`resTimeID`、`resDetailID` 与 `paywStr` MUST 保持旧版层级。 - MUST:预结算返回的微信签名参数只能在当前用户点击支付的内存链路中使用,不得写入本地支付上下文;缺少 `timeStamp`、`nonceStr`、`package`、`signType` 或 `paySign` 时不得调用微信 SDK。 - MUST:支付确认页仅在交易号、金额、医院、就诊人和用户明确确认均有效时调用支付接口;客户端 SHALL 不保存或展示商户密钥、完整签名参数及原始响应。 - MUST:挂号支付的服务端最终状态 MUST 使用旧版 `130980(hospitalCode, userCode, payTradeNum)` 查询;`130993(foreignTradeNum)` 仅用于自助订单。挂号成功后的 `01050004(payTradeNum, prescribeTradeNum)` 与 `131027(hospCode, userCode, payTradeNum, openID)` 也 MUST 使用旧版字段集合;服务端状态 MUST 作为支付成功、未支付、异常与完成页跳转的最终依据。 - MUST:对 `SUCCESS`、`NOTPAY`、`UN`、用户取消、SDK 失败、网络中断、查询超时和已支付重复点击提供确定性分支与幂等保护。 - MUST:异常撤销仅在服务端确认可撤销且用户再次明确确认时调用 `130994`;普通失败或未知状态不得自动撤销或重新扣款。 - MUST NOT:在交易号缺失、订单无效或用户未明确确认时调用 `01050002`、`wx.requestPayment` 或 `130994`。 - MUST NOT:使用 mock、本地假支付结果、硬编码交易号或静态业务数据替代真实服务端返回。 #### Scenario: 挂号自费支付成功 - **GIVEN** 用户完成挂号选择,`03100090` 校验通过且 `03050234` 返回有效锁号订单 - **WHEN** 用户在支付确认页明确点击支付并完成微信 SDK 授权 - **THEN** 系统 SHALL 使用旧版挂号业务体调用 `01050002`,保存返回的 `payTradeNum`,并以 `130980` 返回的成功状态展示支付结果 #### Scenario: 支付取消或状态待确认 - **GIVEN** 微信 SDK 返回取消、失败或网络中断,或服务端状态为 `NOTPAY`/未知 - **WHEN** 用户回到支付确认或支付结果页 - **THEN** 系统 SHALL 保留同一有效交易上下文供用户刷新或重新发起,且不得把 SDK 本地回调直接当作支付成功,也不得自动生成新订单或重复扣款 #### Scenario: 支付前置条件不完整 - **GIVEN** 支付前置字段缺失或订单已失效 - **WHEN** 用户尝试提交支付 - **THEN** 系统 SHALL 阻止支付动作,展示明确的不可支付原因,并不得调用支付接口或微信支付 SDK