技术问题
全球收单
1. WebView 打开收银台的推荐方式
适用场景: 使用「全量支付方式收银台」或「指定支付方式收银台」的商户。
建议: 优先使用用户移动端系统浏览器打开 Checus 收银台,尽量避免在 App 内使用 WebView 打开收银台页面。
部分支付方式在交易过程中需要跳转到电子钱包、银行 App 或渠道页面。系统浏览器对外部 App 跳转、Deep Link、Universal Link 等行为的兼容性更好,能降低支付链路被 WebView 容器拦截的风险。
如果业务上必须使用 WebView,请确保 WebView 允许以下渠道链接正常重定向。
| 地区 | 目标机构 | 重定向 URL - 跳转 Web | 重定向 URL - 跳转 App |
|---|---|---|---|
| 印度尼西亚 | DANA | https://m.dana.id/ | - |
| 印度尼西亚 | GOPAY | https://gopay.co.id/ | gopay.co.id/**.gopay.co.id/* |
| 印度尼西亚 | SHOPEEPAY | https://app.shopeepay.co.id/ | shopeepayid:// |
| 马来西亚 | TNG | https://m.tngdigital.com.my/ | - |
| 菲律宾 | GCASH | https://payments.gcash.com/ | - |
| 俄罗斯 | SBERPAY | https://securepayments.sberbank.ru/https://epay.sberbank.ru/ | sberpay:// |
| 俄罗斯 | TPAY | https://pay.tbank.ru/https://securepay.tinkoff.ru/ | https://o.tbank.ru/tpay/ |
俄罗斯支付方式中,SberPay 和 T‑Pay 均可能涉及外部 App 跳转或移动端重定向。若商户 App 使用 WebView 打开收银台,请确保 WebView 不会拦截上述域名、HTTPS App Link 或自定义 scheme;实际生产链路中需要放行的完整 URL 以 Checus 收银台返回的跳转地址为准。
2. WebView 无法拉起第三方 App(ERR_UNKNOWN_URL_SCHEME 等)
现象: 使用 GoPay、LinePay 等支付方式时,WebView 页面提示 ERR_UNKNOWN_URL_SCHEME,或无法拉起对应第三方 App。
原因: WebView 默认只处理 http、https 等常规链接。渠道返回 intent:// 或自定义 scheme 时,如果商户 App 未拦截并转交系统处理,就会导致跳转失败。
解决: 如果打开收银台的容器是 Android WebView,需要复写 WebViewClient 的 shouldOverrideUrlLoading,对 intent:// 和非 http/https scheme 做系统跳转或 fallback 处理。
核心示例:
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request != null && request.getUrl() != null
? request.getUrl().toString()
: "";
return handleExternalUrl(view, url) || super.shouldOverrideUrlLoading(view, request);
}
private boolean handleExternalUrl(WebView view, String url) {
if (TextUtils.isEmpty(url)) {
return false;
}
Uri uri = Uri.parse(url);
String scheme = uri.getScheme();
if ("intent".equals(scheme)) {
try {
Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
if (intent.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(intent);
return true;
}
String fallbackUrl = intent.getStringExtra("browser_fallback_url");
if (!TextUtils.isEmpty(fallbackUrl)) {
view.loadUrl(fallbackUrl);
return true;
}
} catch (Exception ignored) {
}
}
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
try {
context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (Exception ignored) {
}
}
return false;
}如果打开收银台的容器是 iOS WKWebView,需要在导航决策中拦截非 http/https scheme,并交给系统打开。
Objective-C 示例:
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *requestUrl = navigationAction.request.URL;
NSString *scheme = requestUrl.scheme;
if (scheme && ![scheme isEqualToString:@"http"] && ![scheme isEqualToString:@"https"]) {
decisionHandler(WKNavigationActionPolicyCancel);
UIApplication *application = [UIApplication sharedApplication];
if (@available(iOS 10.0, *)) {
[application openURL:requestUrl options:@{} completionHandler:nil];
} else {
[application openURL:requestUrl];
}
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}Swift 示例:
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url,
let scheme = url.scheme else {
decisionHandler(.allow)
return
}
if scheme != "http" && scheme != "https" {
decisionHandler(.cancel)
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return
}
decisionHandler(.allow)
}如果打开失败,可按业务需要引导用户安装对应 App,或跳转到 App Store / 应用市场搜索页。
3. DANA 支付页面空白或提示网络不稳定
现象: API 标准入款接入方式打开 DANA 支付时,页面可能显示空白。滑动页面后可看到错误信息:The network connection is unstable. Please try again later.
原因: Android WebView 未开启必要的存储或视口配置,导致渠道页面资源加载异常。
解决: 初始化 WebView 时确认以下配置已开启:
webSettings.setDomStorageEnabled(true);
webSettings.setTextZoom(100);
webSettings.setUseWideViewPort(true);4. 支付成功后如何返回商户 App
说明: 支付完成后,Checus 会打开商户传入的前端回调地址 frontCallBackUrl。
- 如果收银台是在商户 App 内部 WebView 打开的,
frontCallBackUrl通常也会在当前 App 容器内打开。 - 如果收银台是在外部浏览器打开的,
frontCallBackUrl会在外部浏览器打开。此时如需回到商户 App,需要将回调地址设计为 scheme、Deep Link 或 Universal Link。
建议商户在支付结果页中同时处理「App 回跳」和「浏览器内展示结果」两种场景,避免用户无法回到业务流程。
5. 异步回调通知注意事项
适用场景: 商户通过服务端异步通知获取支付结果。
请确认以下事项:
- 回调地址真实存在,且外部网络可访问。
- 回调接口支持
application/json。 - 回调处理需要校验签名,并做好幂等处理。
- 如果商户服务器设置了 IP 白名单,需要放行 Checus 回调服务器 IP。
- 回调响应内容请参考异步通知。
注意:支付最终状态建议以服务端异步通知或主动查询结果为准,不建议仅以前端跳转结果判断。
6. 点击"确认支付"后未打开后续支付页面
现象: API 标准入款接入方式中,点击"确认支付"按钮后没有打开后续支付页面。
原因: Android WebView 未设置 WebViewClient,或相关跳转被默认容器行为拦截。
解决: 至少需要为 WebView 设置 WebViewClient:
mWebView.setWebViewClient(new WebViewClient());如果支付方式需要拉起第三方 App,请同时参考"WebView 无法拉起第三方 App"的处理方式。
7. 收银台提示"请求参数格式错误"
现象: 进入收银台后页面提示"请求参数格式错误"。
常见原因: 商户使用设备默认区域格式化金额,例如:
String.format(Locale.getDefault(), "%.2f", price)不同地区的 Locale 可能产生不同的小数分隔符或格式,导致金额不符合接口要求。
解决: 金额格式化建议固定使用英文 locale:
String.format(Locale.ENGLISH, "%.2f", price)8. 收银台支付方式展示不全或样式混乱
现象: 收银台页面支付方式展示不全、排版错乱或字体异常。
原因: Android WebView 字体缩放跟随系统设置,可能影响页面布局。
解决: 建议固定 WebView 字体缩放比例:
mWebView.getSettings().setTextZoom(100);9. 支付时软键盘覆盖输入框
现象: 支付过程中需要输入手机号、邮箱等信息时,点击输入框后软键盘遮挡输入区域。
处理建议:
- 不要将支付页面容器设置为全屏模式。
windowSoftInputMode可以不设置,或设置为adjustResize。- 不建议使用
adjustPan。 - 如果使用沉浸式状态栏,布局中需要设置
fitSystemWindows=true。
10. URI scheme 自动变为小写
现象: 商户传入的 URI 为 APP://,跳转时变成了 app://。
原因: 浏览器和 WebView 通常会按 URL 规范处理 scheme。scheme 本身不区分大小写,部分容器会统一转为小写。
解决: AndroidManifest 中配置的 scheme 和 host 建议全部使用小写,避免因大小写不一致导致 App 无法被拉起。
11. 页面报 X-Frame-Options
现象: 页面加载时报 X-Frame-Options 相关错误。
原因: 渠道侧页面不允许被 iframe 嵌套。
解决: 不要在 iframe 中打开该页面,改为直接打开页面地址。
12. Android WebView 推荐配置
如果商户必须在 Android WebView 中打开 Checus 收银台,建议至少确认以下配置:
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setTextZoom(100);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
}
mWebView.setWebViewClient(new WebViewClient());同时建议确认:
- Activity 已开启硬件加速:
android:hardwareAccelerated="true"。 - 若支付链路涉及第三方 App,已处理
intent://和自定义 scheme。 - 若商户对缓存策略有自定义处理,请避免禁用收银台静态资源缓存。
- 若项目仍兼容旧版本 Android,可结合实际情况处理
allowFileAccess、allowUniversalAccessFromFileURLs、缩放控件、多窗口能力等配置。 - 如项目支持较低版本 Android,建议移除系统默认注入的高风险 JS 接口,例如
searchBoxJavaBridge_、accessibility、accessibilityTraversal。
13. 收银台域名预连接建议
适用场景: 商户希望优化首次打开收银台的耗时。
建议: 在 App 启动后,或用户进入订单待支付页面但尚未点击支付时,提前对 Checus 收银台域名做连接预热,减少正式打开收银台时的 DNS 与 TLS 握手耗时。
- Android:可引入
androidx.browser:browser,使用CustomTabsClient.warmup()与mayLaunchUrl(Uri.parse("https://cashier.checus.com"))预热底层连接池。 - iOS:可在进入支付前对
https://cashier.checus.com发起轻量 HTTPS 请求,或按当前 iOS SDK 支持的公开能力进行预连接处理。
14. 页面报 net::ERR_CACHE_MISS
原因: Android 网络权限配置异常时,WebView 可能出现 net::ERR_CACHE_MISS。
解决: 检查 AndroidManifest.xml 中的网络权限,权限名称需要使用大写 INTERNET。
错误示例:
<uses-permission android:name="android.permission.internet"/>正确示例:
<uses-permission android:name="android.permission.INTERNET"/>15. iOS WKWebView 跳转失败,但系统浏览器正常
现象: 同一个链接在系统浏览器中可以正常打开,但在 iOS WKWebView 中跳转失败。
可能原因: WKWebView 对 URL 做编码处理后,链接中的 # 被编码为 %23,导致渠道页面识别异常。
解决: 对 URL 编码逻辑做兼容处理,确保 # 保持为允许字符。
Objective-C 示例:
-(NSString *)WM_FUNC_urlEncode:(NSString *)urlStr {
NSMutableCharacterSet *set = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[set addCharactersInString:@"#"];
return [urlStr stringByAddingPercentEncodingWithAllowedCharacters:set];
}Swift 示例:
func WM_FUNC_urlEncode(_ urlStr: String) -> String {
if urlStr.isEmpty {
return ""
}
var charSet = CharacterSet.urlQueryAllowed
charSet.insert(charactersIn: "#")
return urlStr.addingPercentEncoding(withAllowedCharacters: charSet) ?? ""
}16. Android 9.0 以上无法打开 http 页面
现象: Android 9.0 以上设备无法打开 http 页面,Android 9.0 以下设备正常。
原因: Android P 起默认限制 HTTP 明文流量,非加密请求可能被系统拦截。
解决: 优先将相关 API 或页面改为 HTTPS。
如业务仍需使用 HTTP,可通过以下方式允许明文流量。
方式一:新增 res/xml/network_security_config.xml。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>并在 AndroidManifest.xml 中引用:
<application android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="org.apache.http.legacy" android:required="false" />
</application>方式二:在 AndroidManifest.xml 中配置:
<application android:usesCleartextTraffic="true">17. WebView 加载页面报 net::ERR_BLOCKED_BY_RESPONSE
原因: 目标页面不支持在 iframe 中打开,或响应头策略阻止页面被嵌入。
解决: 不要通过 iframe 嵌入该页面,改为直接打开页面地址。
参数配置
1. 如何生成密钥?
商户可登录商户平台,在「开发参数」中生成或重置密钥。
配置时请注意区分测试环境和正式环境,不同环境的密钥不可混用。
2. 如何添加回调地址?
Checus 支持两种方式设置回调地址:
- 拥有开发参数权限的操作员或超级管理员,可在商户平台「开发参数」中配置回调地址。
- 商户可在下单时传入回调地址。
如果下单时传入的回调地址与商户平台配置的回调地址不一致,以接口传入的回调地址为准。
3. 为什么没有收到回调通知?
请按以下顺序排查:
- 是否已配置回调地址。
- 回调地址是否填写正确。
- 回调地址是否可以被外部网络访问。
- 商户服务器是否配置 IP 白名单;如有,需要放行 Checus 回调服务器 IP。
- 商户服务是否正常返回 Checus 要求的响应内容。
若以上配置均正常仍未收到回调,请联系 Checus 平台协助排查。
