本模块与原有 src/api/pay 并行,旧支付接口保持不变。新模块继续使用
ProductPayInfo、MiaoguoWXUsers 和 MiaoguoCoupon,订单状态、金额单位及秒过
PayType=7/9 的业务含义与旧代码兼容。
服务端启动前配置以下环境变量:
WX_VIRTUAL_PAY_OFFER_ID=微信虚拟支付OfferId
WX_VIRTUAL_PAY_APP_KEY=正式环境AppKey
WX_VIRTUAL_PAY_SANDBOX_APP_KEY=沙箱环境AppKey
WX_VIRTUAL_PAY_ENV=1
WX_MIAOGUO_MESSAGE_TOKEN=秒过小程序消息推送Token
WX_VIRTUAL_PAY_POST_ACTION_TIMEOUT_MS=60000
WX_VIRTUAL_PAY_PRODUCTS_JSON='[
{"productId":"后台正式商品ID","payType":7,"price":19900,"goodsPrice":36500,"env":0},
{"productId":"后台正式试用商品ID","payType":9,"price":100,"env":0},
{"productId":"后台沙箱商品ID","payType":7,"price":19900,"goodsPrice":36500,"env":1},
{"productId":"后台沙箱试用商品ID","payType":9,"price":100,"env":1}
]'
price 是用户实际支付金额,单位为分;goodsPrice 是小程序后台已发布商品原价。两者不同时,服务端会把 price 作为 activitySellingPrice 签名。goodsPrice 时默认与 price 相同。WX_VIRTUAL_PAY_PRODUCTS_JSON 可以省略。没有匹配配置时,服务端按“内部产品编号_实际金额(元)”生成微信道具 ID。秒过当前对应关系为:1 元使用 166_1、199 元使用 166_199、258 元使用 166_258。以后其他小程序也采用相同规则,例如内部产品编号 205 的 199 元道具为 205_199。PayType=9 只允许 1 元,购买 PayType=7 通常只允许 199 元或 258 元。服务端通过 OpenID 查到的真实 UserID < 8 或 UserID=3089 可用 1 元测试购买;不能依赖客户端自行传入的 UserID,以免普通用户篡改金额后低价开通权益。activitySellingPrice。WX_VIRTUAL_PAY_ENV=1 为沙箱,0 为正式环境。iOS 没有沙箱,服务端会强制使用正式环境商品和正式 AppKey。WX_VIRTUAL_PAY_POST_ACTION_TIMEOUT_MS 只控制支付事务提交后的统计刷新等非关键任务,默认 60 秒;该任务失败不会回滚已经完成的订单和会员权益。| 接口 | 用途 |
|---|---|
GET /api/MiaoguoVirtualPayLogin500 |
换取登录态、创建兼容订单并返回虚拟支付签名 |
GET /api/MiaoguoVirtualPayOrderStatus500 |
主动查询微信订单并在漏回调时补发货 |
POST /api/MiaoguoVirtualPayNotify500 |
接收 xpay_goods_deliver_notify 并发放权益 |
微信公众平台的秒过小程序消息推送地址应指向:
https://www.kylx365.com/api/MiaoguoVirtualPayNotify500
当前代码按明文 XML/JSON 消息接收;Token 必须与 WX_MIAOGUO_MESSAGE_TOKEN 一致。
同一路径的 GET 请求已实现公众平台首次保存地址时的签名校验与 echostr 回显。
若公众平台启用了安全模式(AES 加密消息),需先切换为明文模式,或后续增加消息解密。
main.virtualPayMoney,原 main.payMoney 保留。Status=1 判定幂等。/xpay/notify_provide_goods。本次没有实现退款、iOS 退款询问事件和投诉处理。
支付完成后的核心逻辑由发货通知和主动查单共同调用 fulfillOrder。该函数支持在测试中注入假数据库,因此以下命令不会连接或修改真实数据库,也不会调用微信接口:
npm run test:virtual-pay:completion
测试覆盖:正常购买完成、测试用户 1 元购买、1 元试用、重复发货幂等、金额不一致回滚,以及模拟微信 xpay_goods_deliver_notify 发货通知。完整虚拟支付测试可运行:
npm run test:virtual-pay
只有最终的微信客户端拉起支付、微信真实扣款和公网消息推送需要做少量线上联调;会员更新、优惠券消耗、订单完成与异常回滚都可先在本地自动测试。