Skip to main content
在 App WebView 中嵌入收银台的机制——您的 WebView 必须放行什么、如何在 Android 和 iOS 上拦截非 HTTP(S) scheme、以及如何 排查 net::ERR_UNKNOWN_URL_SCHEME——见 收银台集成步骤, 各支付方式的例外见 支付方式集成说明。 请先阅读那些内容。本页回答围绕它们产生的问题。

发布 WebView 集成之前有清单可以过一遍吗?

有——以下是支付流程可能依赖的能力。您的 App 每屏蔽 一项,就会直接去掉一些支付方式,而不是优雅降级。

我能从收银台检测到自己在 WebView 里吗?Waffo 会提示客户吗?

收银台一般不会尝试检测 App WebView,也不会 为此显示”请在浏览器中打开”的提示。有一个例外:当 收银台在已知支付流程无法运行的即时通讯 App 内置浏览器中打开时, 它会显示一个阻断对话框,要求 客户在别处打开链接,显示完整链接,并提供复制 按钮。该对话框无法关闭,因为在那个页面上继续 终归会失败。 对于您自己的 App,检测应在您这边完成:您控制着 WebView,所以 您本来就知道。请在创建订单时利用这一点——见 下文关于在 App 环境隐藏支付方式的问题。

我的 WebView 必须放行哪些域名?

放行 Waffo 收银台域名,并且不要把域名白名单当作 您对支付流程的控制手段。 收银台 URL 是 Waffo 域名下的 HTTPS,但之后的支付步骤 会导航到支付方式自己的域名,钱包唤起时还会导航到 支付页面在运行时决定的非 HTTP(S) scheme。这一下游集合 是每种支付方式的属性,会在您这边没有任何改动的情况下变化, 所以没有可以固定的列表。只允许固定主机集合的 App 能通过集成测试,然后在您没测过的某种方式上失败。 受支持的做法是 Steps → custom schemes 中的那种:把 HTTP(S) 导航留在 WebView 内,把经过校验的非 HTTP(S) 导航 交给操作系统。

客户离开我的 WebView 去钱包 App 付款了,我的 App 怎么得知结果?

通过您的服务端,而不是通过 WebView。可靠性顺序是固定的, 在 App 场景下也不会变: 一个实用的 App 模式:当您的 App 回到前台时,向您自己的 后端询问订单状态(后端通过通知或查询得知),而不是从 WebView 中读取任何内容。这也是能应对客户手动切回您的 App、 而不是跟随跳转的模式。 关于为什么跳转不是结果的完整论述,见 支付结果。

客户没经过跳转,直接切回了我的 App。这笔订单我该怎么处理?

不需要特殊处理——并且明确地说,不要把它当作失败。从 平台的角度看,订单正处于支付方式留下的那个状态, 跳转被跳过并不能说明该状态是什么。
  • 查询订单,或等待通知。两者都给出真实状态。
  • 不要因为客户没有回来就关闭、取消或重新创建订单。 重复支付就是这样产生的。
  • 如果支付仍在待处理,客户很可能之后会在订单有效期内、 在钱包 App 里完成支付。

客户回到了 WebView,收银台页面会自己刷新结果吗?

会。当收银台处于任何待定状态——等待跳转、等待 二维码等指引、或处理中——它会以退避间隔轮询订单状态, 并在结果到达时自行推进页面。 某些客户通常付款很快的二维码方式,在二维码展示后会 以更高频率轮询。 跳转页还带有一个明确的重新检查操作。按下它会立即查询 订单;如果支付仍未完成,页面会如实 告知,而不是假装已完成。 所以客户不需要重新加载任何东西,您的 App 也不应 在恢复前台时强制重新加载 WebView——那可能会重启一个本来正常的流程。

同一个支付跳转链接能打开两次吗?客户再点一次付款会失效吗?

取决于支付方式,您无法控制。有些支付 方式签发的跳转 URL 是一次性的——消费一次后,再次打开 就不起作用。其他方式允许重新打开。 托管收银台知道适用哪种情况并相应体现:允许重新打开时, 页面会一直提供 Pay 按钮让客户可以再次跳 出到钱包;不允许时,页面只提供重新检查操作, 以免把客户送到一个会失败的 URL。 两个后果:
  • 在托管收银台上您什么都不用做——页面已经 处理了两种情况。
  • 在商户自建收银台上,请把跳转 URL 当作一次性的。这一 属性有意不放在面向商户的 orderAction 中, 所以您没有任何可以据此分支的字段。展示跳转一次,然后 回退到查询订单。

客户在 WebView 里点了付款,什么都没发生。联系支持团队前我要采集什么?

在失败当时采集以下五项。没有它们,该报告 无法与正常的”客户改变主意”区分开。
  1. WebView 收到的最后一个导航 URL,完整且未修改—— 包括其 scheme 和每一个查询参数
  2. 您的 WebView 导航回调是否对该 URL 触发过
  3. 设备上是否有任何已安装的 App 能处理该 scheme
  4. 订单 ID 和时间戳
  5. 客户是在您 App 的 WebView、外部浏览器,还是 另一个 App 的内置浏览器中
Steps → troubleshooting 中的排查表把常见症状映射到原因。注意那里的规则:从 失败 URL 的 scheme 和您 WebView 对它的处理来诊断,而不是从设备型号 或操作系统版本。同一个 App 构建在不同操作系统版本上表现不同, 几乎总是导航回调被触达方式的差异,而不是 平台级别的拦截。

为什么我在 sandbox 里复现不了钱包 App 唤起?

因为 sandbox 不连接真实的支付方式。sandbox 收银台是一个模拟器:您按按钮声明结果, 没有真实的支付方式选择、没有卡输入,也没有钱包 App 交接。见 Sandbox 模拟器。 所以您集成中的 App 唤起部分——scheme 拦截、把 URL 交给 操作系统、返回——必须在生产环境用一笔 小额真实支付验证。sandbox 擅长的是它周边的一切:订单 创建、通知处理、App 恢复逻辑,以及您自己的 恢复时读取订单状态的流程。 请为每种涉及 App 交接的支付方式规划一次生产冒烟测试, 并预留它需要真实钱包账户这一事实的成本。

我能只在我的 App 环境里隐藏某种支付方式吗?

无法通过设置实现,收银台上也没有”环境”参数。 您能做的——也是平台围绕其设计的——是按订单决定:
  • 您的 App 知道自己是您的 App。让您的服务端在 /api/v1/order/create 上传入 payMethodType, 以及针对特定钱包传入 payMethodName,这样订单只 提供在该环境下可用的方式。
  • 如实发送 userInfo.userTerminal。不支持您所发送终端 类型的方式根本不会被提供。
无论如何,按订单过滤比账户级开关更稳健,因为 同一个账户通常还服务于一个没有此类限制的网页流程。 参数规则见 收银台定制。

我是不是应该一开始就在外部浏览器打开收银台?

这是一种合理的设计,而且对某些支付方式来说是唯一 可行的——各方式说明列出了其自身流程无法在 商户 App WebView 内运行的情形。 需要权衡的取舍: 许多集成最终采用的折中路线:对能在 WebView 中运行的流程保留 WebView,仅对支付方式要求的订单打开外部浏览器—— 这在创建时您就知道,因为方式是您选的。 注意 successRedirectUrl、failedRedirectUrl 和 cancelRedirectUrl 既接受 HTTPS URL 也接受 deeplink,所以外部浏览器流程仍然可以 把客户带回您的 App。

有 SDK 帮我封装 App 侧的唤起吗?

Waffo 前端 SDK 覆盖的是网页层面——渲染卡字段,以及 在您的页面中嵌入收银台。App 侧的部分——在您的 WebView 中拦截 非 HTTP(S) 导航并交给操作系统—— 是您自己 App 中的平台 API,没有 Waffo 库可以替代 它们。Android 和 iOS 的平台文档链接见 Steps → custom schemes。

我能直接把收银台链接通过短信或邮件发给客户吗?

那正是支付链接的用途,它是一个独立的产品层面,有 自己的过期和复用规则——见支付链接。 不要把 API 创建订单的收银台 URL 改作对外发送的链接: 它属于一笔订单,随该订单过期,一旦订单 到达最终状态,链接就会显示过期页面。
遇到无法归类的 WebView 故障?请携上文采集清单中的五项 联系支持团队。