# 九、saas-starter 本地支付验收 第 8 章已经把 web-pay 的收银台、支付网关、运营平台和运营 API 部署到了线上。本章不再启动本机的 web-pay 服务,而是只在本机启动 `saas-starter`,让它直接调用第 8 章上线后的 web-pay,完成最后一笔真实支付验收。 ```{important} 🎯 **本章目标:** 用本地 `saas-starter` 跑通基于线上 web-pay 的完整支付流程。用户从本地 H5 创建订单后,进入线上收银台,选择支付宝或微信扫码支付;支付成功后,线上 web-pay 记录订单并通知本机 SaaS 后端更新业务订单和订阅状态。 **做到这里,本教程基础主线就是 100%。** 你已经证明自己的 SaaS 可以接入线上统一收银台和运营平台完成收款。之后可以按第 8 章同一套 OBS/CDN、宝塔后端和 CodeArts 流程上线 `saas-starter` 或继续开发自己的 SaaS 服务,不需要再单独完成一个新章节。 ``` ## 9.1 启动前确认 开始前先确认这些准备项已经完成: ![SaaS 本地支付验收启动前确认](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-28-091-preflight-check.png) ```{important} ✅ **本章是真实支付验收,不是只看页面能不能打开。** 如果支付宝 / 微信官方资料、支付参数或支付通道还没配好,可以先回到第 6 章补齐;否则本章只能验证 SaaS 能创建订单,无法完成真实付款和回调。 ``` - 第 6 章已经在 web-pay 运营平台创建商户和应用,并把同一组 `mchNo`、`appId`、`AppSecret` 写入 `saas-starter`。 - 支付宝或微信支付参数已经在运营平台保存并启用。 - 至少一个支付通道已经启用;本章建议优先验证 `ALI_QR` 和 `WX_NATIVE`。 - 第 7 章已经证明 `saas-starter` 后端、H5 前端和业务库本地可用。 - 第 8 章的线上 web-pay 已经可访问:`pay.example.com`、`pay-api.example.com`、`paymanager.example.com`、`paymanager-api.example.com` 都已通过 HTTPS 验收。 再检查 `saas-starter` 本地后端配置: ```yaml zhcpay: api-base-url: "https://pay-api.example.com" cashier-base-url: "https://pay.example.com" site-base-url: "http://localhost:5173" ``` ```{tip} 📌 这三个地址的方向不要混:`api-base-url` 调线上支付网关,`cashier-base-url` 跳线上收银台,`site-base-url` 仍然指向本机 SaaS H5。SaaS 通知地址不用手填,后端启动脚本会用本次 cloudflared 地址临时覆盖。 ``` ```{warning} ⚠️ 本章本地只启动 `saas-starter`。`api-base-url` 和 `cashier-base-url` 必须指向第 8 章上线后的 web-pay 域名,不能再指向本机 `localhost`。 ``` ## 9.2 本地服务启动顺序 按下面顺序启动: ![SaaS 本地服务启动顺序](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-29-092-local-start-sequence.png) ```{important} 🚀 **本章只启动 SaaS 本地服务。** web-pay 的收银台、支付网关、运营平台和运营 API 都使用第 8 章的线上环境;不要再同时启动仓库根目录的 web-pay 本地脚本。 ``` 1. 启动本机 Redis 和 ActiveMQ。 2. 启动 SaaS 后端: ```bash cd saas-starter ./env-scripts/start-local-test-backend.sh ``` 脚本会构建并启动本地 SaaS 后端,默认监听: ```text http://localhost:9220 ``` 脚本还会生成 SaaS 的 cloudflared 公网通知地址,并写入: ```text saas-starter/logs/application-local-tunnel.yml ``` 这个文件里的 `zhcpay.notify-url` 会覆盖本次运行配置。线上 web-pay 支付成功后,会通过这个公网地址通知本机 SaaS 后端: ```text https://xxxx.trycloudflare.com/api/pay/notify ``` ```{tip} 🔗 每次重启 SaaS 后端脚本,cloudflared 地址都可能变化。测试付款时以本次 `application-local-tunnel.yml` 生成的地址为准,不要继续使用旧地址。 ``` ```{warning} ⚠️ 线上 web-pay 要能访问这个 SaaS tunnel。若 tunnel 进程断开、地址过期,或 `application-local-tunnel.yml` 不是本次启动生成的,支付成功后 web-pay 可能已经入账,但 SaaS 业务订单不会更新。 ``` 3. 用 HBuilderX 启动 SaaS H5 前端: - 打开 HBuilderX。 - 选择 `文件` -> `打开目录`,打开 `saas-starter/frontend`。 - 选择 `运行` -> `运行到浏览器` -> `Chrome` 或你常用的浏览器。 - 以 HBuilderX 控制台输出的地址为准,默认通常是: ```text http://localhost:5173 ``` ```{important} 🎯 本章不需要运行仓库根目录的 `./env-scripts/start-local-test-backend.sh` 或 `./env-scripts/start-local-test-frontend.sh`。web-pay 已经在第 8 章上线,本章只用线上收银台、线上支付网关和线上运营平台。 ``` ```{tip} 💡 如果 SaaS H5 仍然请求旧接口,先在 HBuilderX 里停止运行并重新运行到浏览器;必要时清理浏览器缓存或用无痕窗口复测。 ``` ## 9.3 创建一笔 SaaS 订单 打开 HBuilderX 输出的 SaaS H5 地址,通常是: ```text http://localhost:5173 ``` ![SaaS 创建订单并调用线上支付网关](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-30-093-create-saas-order.png) 进入订阅、续费或开通专业版页面,选择一个套餐并点击支付。预期结果: ```{important} 📌 **每次改配置后都重新创建一笔新订单。** 旧订单里可能已经固化了旧金额、旧通道或旧支付链接,不适合拿来验证刚改过的配置。 ``` - SaaS 后端生成业务订单。 - SaaS 后端调用线上 web-pay 支付网关创建支付订单。 - 页面返回或跳转到线上收银台支付链接。 - 收银台地址指向第 8 章配置好的线上域名。 支付链接应该类似: ```text https://pay.example.com/#/hub/{zhcpayToken} ``` 如果订单停在 SaaS 侧,先看 SaaS 后端日志: ```text saas-starter/logs/backend.local.log ``` 重点确认: - `mchNo`、`appId`、`AppSecret` 来自同一个 web-pay 应用。 - `zhcpay.api-base-url` 指向线上 `pay-api` 域名。 - `zhcpay.cashier-base-url` 指向线上收银台域名。 - SaaS 业务库中能写入订单记录。 ```{warning} ⚠️ 如果这里报签名失败、应用不存在、商户不存在或无可用通道,优先回到第 6 章核对同一组 `mchNo`、`appId`、`AppSecret` 和支付通道,不要先改前端页面。 ``` ## 9.4 进入线上收银台 订单创建成功后,浏览器会进入线上收银台: ```text https://pay.example.com/#/hub/{zhcpayToken} ``` 预期结果: - 收银台能展示订单金额。 - 收银台能展示支付宝和微信等可用支付方式。 - 选择支付宝时可以看到支付宝扫码或跳转支付页面。 - 选择微信时可以看到微信扫码支付页面。 - 线上运营平台订单页能看到这笔支付订单。 ![SaaS 订单进入线上收银台](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-31-094-online-cashier-entry.png) ![统一收银台:选择支付方式](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/cashier-select.png) ![统一收银台:微信扫码支付](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/cashier-wechat.png) ![统一收银台:支付宝扫码支付](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/cashier-alipay.png) ```{note} 📌 无 token 直接访问 `https://pay.example.com` 出现空白、错误页或缺少订单信息是预期行为。收银台需要 SaaS 创建订单后生成的 `zhcpayToken` 才能展示付款页。 ``` ```{tip} ✅ 线上运营平台能看到这笔订单,说明 SaaS 已成功调用线上支付网关创建 web-pay 订单。此时如果收银台页面异常,排查重点从 SaaS 后端转到收银台前端、支付通道和线上 `pay-api`。 ``` 如果收银台没有支付方式,回到第 6 章检查支付参数和支付通道是否启用;如果线上页面仍是旧版本,回到第 8 章检查 OBS 上传和 CDN 刷新。 ## 9.5 完成付款并验证回调 使用支付宝或微信完成扫码支付。第一笔建议用小金额验证,确认链路稳定后再继续扩展业务场景。 ```{danger} 🔐 **第一笔用真实小额支付。** 本章已经进入真实支付链路,不要用大金额测试;付款前确认商户、金额、支付通道和订单描述都符合预期。 ``` ![支付成功后的两段回调通知链路](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-32-095-payment-callbacks.png) 本章的完整链路是: ```text 本地 SaaS H5 -> 本机 http://localhost:9220 -> 线上 https://pay-api.example.com -> 线上 https://pay.example.com/#/hub/{zhcpayToken} -> 微信 / 支付宝 -> 线上 web-pay 支付网关接收支付平台回调 -> 线上 web-pay 更新支付订单 -> SaaS cloudflared 公网地址 -> 本机 http://localhost:9220/api/pay/notify -> SaaS 更新业务订单和订阅 ``` ```{important} 🎯 **这里有两段回调/通知。** 第一段是微信 / 支付宝回调线上 `pay-api`;第二段是线上 web-pay 通知本机 SaaS cloudflared 地址。web-pay 订单成功但 SaaS 没更新时,通常是第二段出了问题。 ``` 打开线上运营平台: ```text https://paymanager.example.com ``` 检查 web-pay 订单: - 支付订单能查到。 - 金额正确。 - 商户和应用正确。 - 支付状态已变成成功或已支付。 - 通知记录没有持续失败。 再检查 SaaS 业务库: ```text saas_starter ``` 重点表: ```text t_saas_pay_order t_vip_subscription ``` 预期结果: - `t_saas_pay_order` 中对应订单状态已成功。 - 订阅类订单会更新 `t_vip_subscription`。 - SaaS 前端刷新后能看到会员、订阅或业务状态变化。 ```{tip} 🧪 支付成功后,线上运营平台订单成功但本地 SaaS 状态还没更新时,优先看 `saas-starter/logs/application-local-tunnel.yml` 和 `saas-starter/logs/backend.local.log`。这通常说明线上 web-pay 已收款成功,但通知本机 SaaS 的公网地址不可达或验签失败。 ``` ## 9.6 失败排查 | 现象 | 优先检查 | | --- | --- | | SaaS 不能创建订单 | `saas-starter/logs/backend.local.log`、`mchNo` / `appId` / `AppSecret`、线上 `pay-api` 是否可访问 | | SaaS 创建订单后没有跳到收银台 | `zhcpay.cashier-base-url` 是否指向线上收银台、返回的 `payUrl` 是否存在 | | 收银台打不开 | 第 8 章 OBS/CDN、HTTPS、CDN 缓存、收银台前端是否为最新构建 | | 收银台没有支付宝或微信 | 第 6 章支付参数、支付通道、官方产品权限是否启用 | | 线上运营平台看不到订单 | `zhcpay.api-base-url`、应用身份、线上支付网关日志、统一下单响应 | | 支付成功但 web-pay 订单没成功 | `pay-api` 域名、Nginx、支付平台回调配置、支付网关日志 | | web-pay 订单成功但 SaaS 没更新 | `saas-starter/logs/application-local-tunnel.yml`、SaaS tunnel 是否有效、通知地址是否为 `/api/pay/notify` | | SaaS 收到通知但业务状态没变 | `saas-starter/logs/backend.local.log`、`t_saas_pay_order`、签名校验、订单状态幂等逻辑 | | SaaS 前端仍显示未支付 | 前端轮询接口、浏览器缓存、业务订单状态、HBuilderX 是否重新运行 | ![SaaS 支付链路失败排查路径](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-33-096-troubleshooting-path.png) ```{tip} 🧪 排查时先判断失败发生在哪一段:本地 SaaS 创建订单、线上支付网关下单、线上收银台展示、微信 / 支付宝付款、线上 web-pay 入账、本机 SaaS 通知。位置分清后,日志会好读很多。 ``` ```{warning} ⚠️ 不要在同一轮排查里同时改支付参数、通道、SaaS 身份、前端缓存和 tunnel 地址。一次只改一个变量,重新创建新订单验证,否则很难判断到底是哪一步修好了问题。 ``` ## 9.7 本章完成标准 ```{important} 🎉 **这些勾完,基础主线就是 100%。** 你已经验证了业务 SaaS、线上 web-pay、支付平台回调和业务状态更新这条链路可以完整跑通。 ``` ![SaaS 本地支付验收完成标准](https://image-osb.obs.cn-east-3.myhuaweicloud.com/OPC%E5%9B%BE%E5%BA%93/index-34-097-completion-standard.png) - [ ] 第 8 章的线上收银台、支付网关、运营平台和运营 API 均可通过 HTTPS 访问。 - [ ] SaaS 后端已通过 `saas-starter/env-scripts/start-local-test-backend.sh` 启动。 - [ ] `saas-starter/logs/application-local-tunnel.yml` 已生成本次 SaaS 公网通知地址。 - [ ] SaaS H5 已用 HBuilderX 打开 `saas-starter/frontend` 并运行到浏览器。 - [ ] SaaS 能创建订阅、续费或购买订单。 - [ ] 订单能进入线上收银台 `https://pay.example.com/#/hub/{zhcpayToken}`。 - [ ] 收银台能选择支付宝和微信,并能正常展示扫码支付页面。 - [ ] 支付宝或微信可以完成小额扫码支付。 - [ ] 线上运营平台能看到对应支付订单变为成功。 - [ ] 线上 web-pay 能通知本机 SaaS。 - [ ] SaaS 业务订单和订阅状态同步更新。 - [ ] 已理解:本章完成后,基础教程主线 100% 完成;后续如果要上线 `saas-starter` 或自己的 SaaS,回看第 8 章同一套部署步骤即可。 ```{seealso} ➡️ 如果你只是学习或交付基础支付能力,完成本章就可以收尾。接下来可以直接基于这套支付底座继续开发自己的 SaaS;等产品功能成熟后,再按第 8 章的方法上线 SaaS 前端、后端和自动发布流程。 ```