# Quickstart: 蓝新金流(NewebPay)线上支付接入 **Feature**: specs/011-newebpay-payment/spec.md **Date**: 2026-06-22 端到端验证指南。实现完成后按此验证「下单 → 付款 → 订单已支付」主链路与回调安全。 --- ## 前置条件 1. **数据库**: 已执行 `updatesql/sql.md` 中本期两段 DDL(`pos_store_newebpay`、`pos_order_payment`)。 2. **配置**: `ruoyi-admin/src/main/resources/application.yml` 已加 `newebpay` 段: - `base-url`: 测试环境用 `https://ccore.newebpay.com` - `notify-url` / `return-url`: 本机开发需用内网穿透(ngrok/frp)映射到本地 8082 端口的公网域名,如 `https://xxx.ngrok-free.app/pay/newebpay/notify`。 3. **蓝新测试商店**: 在蓝新测试区(ccore)申请测试商店,取得 `MerchantID` / `HashKey` / `HashIV`。 4. **测试卡**: 蓝新测试区信用卡测试卡号(NDNF 附录1),如 `4000-2211-1111-1111`(成功卡)、有效日期/安全码按附录。 --- ## 场景 1:门店开通蓝新凭证 1. 平台后台进「门店蓝新支付开通」列表 → 选门店 → 发起申请(状态→申请中)。 2. 录入测试 `MerchantID/HashKey/HashIV` + 勾选启用支付方式(CREDIT/LINEPAY/APPLEPAY)→ 保存。 3. **预期**: 系统调 QueryTradeInfo 探测,凭证有效 → 状态「已开通」、`last_verify_result=PASS`;无效 → 提示「凭证无效」、状态不变。 4. **验证**: `SELECT newebpay_status,is_enabled,enabled_payments FROM pos_store_newebpay WHERE store_id=?` → status=2, is_enabled=1。 --- ## 场景 2:信用卡支付主链路(核心 P1) 1. C 端用户对「已开通蓝新」的门店下一笔订单(任意类型)。 2. 调发起支付: `POST /pay/newebpay/create?orderid={ddId}`(带用户 token)。 - **预期 200**: 返回 `data.gatewayUrl/MerchantID/TradeInfo/TradeSha/Version/EncryptType`。 - **DB**: `pos_order_payment` 新增一行(merchant_order_no=NB+ddId, pay_status=0);`pos_order.pay_type=6`、`pay_url=gatewayUrl`。 3. 前端用返回字段构建隐藏 form 自动 submit → 跳转蓝新 MPG 付款页。 4. 在蓝新付款页选**信用卡**,输入测试卡号 + 有效期 + 安全码 → 送出。 5. **预期**: 付款成功后蓝新跳回 ReturnURL(重定向到前端结果页);蓝新同时 POST 到 NotifyURL。 6. **NotifyURL 处理**: - 解密 TradeInfo、验签 TradeSha 通过。 - 金额 == 订单 amount。 - `pos_order.pay_status` 由 0 → 1。 - `pos_order_payment` 写入 trade_no、pay_type=CREDIT、auth_code、pay_time、pay_status=1。 - 订单日志记录「系统收到支付成功回调」。 7. **验证**: 订单列表/详情显示「已支付」,商家端/骑手收到新订单推送。 --- ## 场景 3:回调安全(幂等 + 金额不符 + 伪造) 1. **幂等**: 把场景2的成功回调报文(含 trade_no)再 POST 到 `/pay/newebpay/notify` 一次。 - **预期**: 订单状态不变(不重复推送、不重复记账),仍返回成功应答。 2. **金额不符**: 构造一笔 TradeInfo 中 Amt 与订单 amount 不一致的合法签名回调。 - **预期**: 订单 pay_status 不变,`pos_order_payment`/日志记录「金额不一致」告警。 3. **伪造签名**: 篡改 TradeSha 后 POST。 - **预期**: 验签失败,订单不变,记录告警。 --- ## 场景 4:LINE Pay / Apple Pay(P2) 1. 发起支付同场景2(门店 enabled_payments 含 LINEPAY/APPLEPAY)。 2. 蓝新付款页选 **LINE Pay**(跳转 LINE 测试环境完成)或 **Apple Pay**(需 Apple Pay 环境/设备)。 3. **预期**: 回调到达后订单已支付,`pos_order_payment.pay_type` 分别为 LINEPAY / APPLEPAY。 > 注:Apple Pay 需 Apple Developer 配置与 HTTPS 域名验证;测试环境受限时可先验证信用卡 + LINE Pay,Apple Pay 在具备条件时补测。 --- ## 场景 5:单笔查询补单(P3) 1. 模拟回调丢失:付款成功但人为不触发 NotifyURL(订单 pay_status 仍 0)。 2. 商家/运营调 `POST /pay/newebpay/query?orderid={ddId}`。 3. **预期**: 系统调蓝新 QueryTradeInfo 返回 TradeStatus=1,检测到订单未支付 → 补单(pay_status→1、写流水、推送)。 4. **验证**: 订单变为已支付。 --- ## 场景 6:未开通/停用门店 1. 对未开通蓝新(无 pos_store_newebpay 行 / status≠2)或已停用(is_enabled=0)的门店下单。 2. 调发起支付。 3. **预期**: 返回错误「该门店暂不支持在线支付」,不生成交易。 --- ## 加密自测(无需联网) 运行 `NewebPayEncryptUtil.main`(实现时加入),用 NDNF §4.1 官方示例数据验证: - AES-256-CBC/PKCS7 加解密 round-trip。 - TradeSha 规则: `SHA256("HashKey={key}&{tradeInfoHex}&HashIV={iv}")` 大写。 - 明文示例 `MerchantID=MS127874575&RespondType=String&TimeStamp=...&Version=2.3&...` 加密后 hex 可被蓝新测试环境接受(场景2 即端到端验证)。 全部通过后方可进入场景1。