diff --git a/.env b/.env
index 4c29fa8..d861b06 100644
--- a/.env
+++ b/.env
@@ -8,4 +8,5 @@ VITE_IS_MICRO=true
VITE_APP_DEV_SERVICE=https://dzc-test-1.fy.takin.cc
# 生产环境后端地址;配置为空时由线上部署提供同源接口。
-VITE_APP_PROD_SERVICE=https://www.zianxin.com/api
+# VITE_APP_PROD_SERVICE=https://www.zianxin.com/api
+VITE_APP_PROD_SERVICE=/api
diff --git a/README.md b/README.md
index 4166460..f161f7d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# 商户付款 H5
-uni-app Vue 3 + TypeScript + UnoCSS + tm-ui 的独立 H5 项目。工程与蓝色主题参考 `../biz_zax_app_cloud`,只注册一个付款页面,默认中文、人民币、浅色主题。
+uni-app Vue 3 + TypeScript + UnoCSS + tm-ui 的独立 H5 项目。工程与蓝色主题参考 `../biz_zax_app_cloud`,提供商户收银与付款结果页面,默认中文、人民币、浅色主题。
## 本地开发
@@ -24,7 +24,8 @@ pnpm build:h5
```text
src/
-├── pages/pay/index.vue # 唯一页面:商户、金额与付款交互
+├── pages/pay/index.vue # 收银页面:商户、金额与付款交互
+├── pages/pay/pay-complete.vue # 只读付款结果页:Lottie、金额与交易信息
├── sheep/
│ ├── components/payment-keyboard.vue # 四列常驻键盘
│ ├── config/merchant.ts # 仅供设计参考的示例数据,真实页面不引用
@@ -37,7 +38,7 @@ src/
- 商户名称与标识通过匿名商户接口读取;`src/sheep/config/merchant.ts` 中的示例仅保留作设计参考,真实页面不引用。标识缺省或加载失败时展示统一店铺图形。
- 修改主题:编辑 `src/sheep/config/theme.ts`。页面基础色在 `pages.json`、`uni.scss` 和 HTML 的 theme-color 中保留一致的框架配置。
-- 页面采用 Hash 路由,唯一页面为 `/pages/pay/index`。部署子路径统一在 `src/manifest.json` 的 `h5.router.base` 中修改,默认 `/`,避免在 Vite 中重复设置路径前缀。
+- 页面采用 Hash 路由,收银页面为 `/pages/pay/index`,结果页为 `/pages/pay/pay-complete`。部署子路径统一在 `src/manifest.json` 的 `h5.router.base` 中修改,默认 `/`,避免在 Vite 中重复设置路径前缀。
- 接入 third 服务的匿名商户查询、线下收款、OAuth 回跳和真实支付。无签名入口或短期收银票据时展示错误,不回退到示例商户。
## 金额与 H5 交互
@@ -64,14 +65,24 @@ tm-ui `3.2.0` 从参考项目的 `src/uni_modules/tm-ui` 原样引入 `tm-sheet`
`VITE_IS_MICRO=true` 保留 `/third`;`false` 对接单体服务时移除 `/third`,代理规则共用。生产构建直接读取同一 `.env` 的 `VITE_APP_PROD_SERVICE`;若线上反向代理已提供同源接口,可将其设为空。Vite 开发代理不随生产构建发布。
- 商户码入口:`/#/pages/pay/index?id=...&tenantId=...&v=1&sign=...`,商户和租户 ID 按字符串处理。
-- OAuth 回跳:`/#/pages/pay/index?tenantCode=...&ticket=...`,页面通过接口读取真实场景、固定金额和渠道参数。
+- 收银入口:`/#/pages/pay/index?tenantCode=...&ticket=...`,页面通过接口读取真实场景、固定金额和渠道参数。支付宝 WAP 的返回/退出由后端固定入口回跳同一票据,并附加 `returned=1`;该标记只阻止自动重复唤起,不表示支付结果。
- `GET /third/aggregate-merchant-pay/merchant` 读取公开商户资料及 `supportedPlatforms`(10 微信、20 支付宝);商户可以只开通其中一个渠道。
- `POST /third/aggregate-merchant-pay/create` 提交整数分金额及稳定 `requestId`;不在前端指定业务类型或渠道商户。
- `GET /third/aggregate-order-pay/context/{tenantCode}/{ticket}` 读取收银上下文;现有 `/status/{tenantCode}/{ticket}` 确认结果。
- 后端把本 H5 来源加入精确 CORS 允许列表;跨域接口必须使用 HTTPS。OAuth 回调仍由后端接收,平台密钥和 OAuth 身份不进入前端。
-线下收款在提交前保留数字键盘;订单聚合及已提交的收款金额锁定。OAuth 回跳只自动调起一次,取消后可手动继续,刷新不会自动重复弹出。JSBridge 返回成功后仍查询服务端状态;未确认原单成功或关闭之前不释放金额创建新请求。
+线下收款在提交前保留数字键盘;订单聚合及已提交的收款金额锁定。新票据只自动调起一次,取消后可手动继续,刷新不会自动重复弹出。微信 JSBridge 返回成功或支付宝 WAP 返回后仍查询服务端状态;未确认原单成功或关闭之前不释放金额创建新请求。
+
+支付宝 WAP 使用后端 `launchParams.mode=ALIPAY_WAP` 和签名 `payUrl`,直接前往 `https://openapi.alipay.com/gateway.do`,必须带 `method=alipay.trade.wap.pay`,不等待 JSBridge。签名支付地址仅保留在当前上下文内存,不写入二维码、Hash 或浏览器恢复存储;支付宝旧 `tradeNO/AlipayJSBridge.tradePay` 分支已移除,微信客户端桥保持原逻辑。WAP 返回、退出或浏览器后退只查询原单,不自动重复导航;手动“继续付款”会先重读上下文,已成功、关闭或过期时停止发起。
扫码客户端未在商户已开通渠道中时,在原单页展示“商户暂不支持微信/支付宝支付”及换用已开通 App 重新扫码的指引,隐藏金额与键盘。普通浏览器提示使用已支持 App 扫码;全部渠道停用时提示联系商户。可重新检查开通情况,不在当前客户端强制唤起另一个 App,也不会据此清除待确认的原付款请求。
完整后端配置、迁移、平台域名设置及发布顺序见 `../biz-api-cloud-zax/pjcloud-thirdparty/docs/aggregate-h5.md`。更换二维码使用的域名或签名密钥后需重新生成商户 URL 收款码,原 App Base64 收款码保持兼容。
+
+## 付款结果页
+
+付款成功或服务端明确关闭、过期、创建失败后,收银页自动进入 `/pages/pay/pay-complete`。入口只传 `tenantCode、ticket`,刷新后重新查询真实金额、商户、支付渠道和支付单号;不信任 URL 中的金额或成功状态。结果页仅调用已有 context/status 查询接口,不创建付款、不调起 JSBridge/WAP,也不释放待确认的 requestId。
+
+结果页参考 App 的 `pay-complete.vue`,使用同版 `lottie-web 5.13.0` 和原始 `success/fail/loading` 矢量动画:成功、失败播放一次,查询中循环;减少动态效果时显示最终帧,后台暂停,销毁时清理。动画不可用时显示本地状态图标,文字与金额保持可读。
+
+取消、网络错误和确认超时不会显示“支付失败”,而是保留待确认说明及只读重新查询入口。返回收银台仍使用同一票据,携带 `returned=1、resultViewed=1` 抑制再次自动付款及结果页往返跳转;该标记只影响导航,不改变服务端状态。确认成功或关闭后,线下商户入口可继续沿用原“再付一笔/重新输入金额”流程。
diff --git a/package.json b/package.json
index 60547c7..71d8f00 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@dcloudio/uni-app": "3.0.0-5000720260410001",
"@dcloudio/uni-components": "3.0.0-5000720260410001",
"@dcloudio/uni-h5": "3.0.0-5000720260410001",
+ "lottie-web": "5.13.0",
"pinia": "3.0.4",
"vue": "3.5.26"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f8e0668..ca6fd08 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,6 +14,9 @@ importers:
"@dcloudio/uni-h5":
specifier: 3.0.0-5000720260410001
version: 3.0.0-5000720260410001(postcss@8.5.6)(vue@3.5.26(typescript@4.9.5))
+ lottie-web:
+ specifier: 5.13.0
+ version: 5.13.0
pinia:
specifier: 3.0.4
version: 3.0.4(typescript@4.9.5)(vue@3.5.26(typescript@4.9.5))
@@ -52,6 +55,9 @@ importers:
specifier: 1.8.27
version: 1.8.27(typescript@4.9.5)
packages:
+ lottie-web@5.13.0:
+ resolution:
+ integrity: sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==
"@ampproject/remapping@2.3.0":
resolution:
integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==
@@ -3103,6 +3109,7 @@ packages:
engines:
node: ">= 6"
snapshots:
+ lottie-web@5.13.0: {}
"@ampproject/remapping@2.3.0":
dependencies:
"@jridgewell/gen-mapping": 0.3.13
diff --git a/src/pages.json b/src/pages.json
index d8de7a5..d3722e2 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -12,6 +12,13 @@
"navigationBarTitleText": "商户收款",
"disableScroll": true
}
+ },
+ {
+ "path": "pages/pay/pay-complete",
+ "style": {
+ "navigationBarTitleText": "付款结果",
+ "disableScroll": true
+ }
}
],
"globalStyle": {
diff --git a/src/pages/pay/index.vue b/src/pages/pay/index.vue
index 6e3723e..43fea6a 100644
--- a/src/pages/pay/index.vue
+++ b/src/pages/pay/index.vue
@@ -35,6 +35,7 @@
{{ error }}
{{ feedback || '正在读取收款信息…' }}
+ {{ resultNavigationError }}
@@ -43,7 +44,8 @@
-