【收款】
1. 有些支付渠道需要打开三方app进行支付,如果webView不处理,拉起三方app失败。
问题:
有些支付渠道需要打开三方app进行支付,如果webView不处理,拉起三方app失败。比如:使用GoPay支付时,提示“"ERR_UNKNOWN_URL_SCHEME"错误;LinePay, AirPay没有办法正常拉起相应app。
解答:
如果打开API的容器是Android的WebView,需要复写WebViewClient,下面是示例代码。
public class TestWebViewClient extends WebViewClient {
private static final String TAG = "TestWebViewClient";
private Activity mContext;
private List<String> HTTP_SCHEMES = Arrays.asList("http", "https");
public TestWebViewClient(Activity context, WebView webView) {
this.mContext = context;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d(TAG, "shouldOverrideUrlLoading url1=" + url);
if(shouldOverrideUrlLoadingInner(view, url)) {
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request != null && request.getUrl() != null ? request.getUrl().toString() : "";
Log.d(TAG, "shouldOverrideUrlLoading url=" + (request != null ? request.getUrl().toString() : ""));
if(shouldOverrideUrlLoadingInner(view, url)) {
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}
/**
* Parse the url and open it by system function.
* case 1: deal "intent://xxxx" url.
* case 2: deal custom scheme. url
* @param view: WebView
* @param url
* @return
*/
private boolean shouldOverrideUrlLoadingInner(WebView view, String url) {
if(!TextUtils.isEmpty(url)) {
Uri uri = Uri.parse(url);
if(uri != null) {
if ("intent".equals(uri.getScheme())) {
try {
Intent intent = Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME);
if(intent != null) {
PackageManager pm = mContext.getPackageManager();
ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
if(info != null) {
mContext.startActivity(Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME));
return true;
}
else {
String fallbackUrl = intent.getStringExtra("browser_fallback_url");
if (!TextUtils.isEmpty(fallbackUrl)) {
if(fallbackUrl.startsWith("market://"))
startAppMarketWithUrl(mContext, fallbackUrl, false);
else
view.loadUrl(fallbackUrl);
return true;
}
}
}
} catch (Exception e) {
}
}
if (!HTTP_SCHEMES.contains(uri.getScheme())) {
startUrl(mContext, url, true);
return true;
}
}
}
return false;
}
public static void startUrl(Context context, String url, boolean isNewTask) {
if(context != null && !TextUtils.isEmpty(url)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if(isNewTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
} catch (Exception e) {
}
}
}
public static boolean hasActivity(Context context, Intent intent, String packageName) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> appList = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo info : appList) {
if (info.activityInfo.packageName.equals(packageName))
return true;
}
return false;
}
public static void startAppMarketWithUrl(Context context, String url, boolean forceUseGoogle) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if (forceUseGoogle || hasActivity(context, intent, "com.android.vending"))
intent.setPackage("com.android.vending");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Exception e) {
try {
startUrl(context, url, true);
} catch (Exception e1) {}
}
}
}
2. 打开DANA支付时,页面显示空白或"The network connection is unstable. Please try again later."
问题:
API标准入款接入方式, 打开DANA支付方式, 页面提示错误, 看到的现象是空白,实际页面比较大, 移动页面可以看到页面错误:“The network connection is unstable. Please try again later."
解答:
如果打开PaySDK的容器是Android 的WebView,需要设置webView的WebSettings属性,代码如下
webSettings.setDomStorageEnabled(true);
webSettings.setTextZoom(100);
webSettings.setUseWideViewPort(true);
3. 支付成功后想返回自己的APP的方法
解答:
在自己APP内部打开收银台url,在支付完成打开跳转地址(前端回调地址frontCallBackUrl)也是在App内部。 如果用外部浏览器打开收银台URL,在支付完成打开跳转地址(前端回调地址frontCallBackUrl)时是在外部浏览器中打开的,这时如果要跳转到App内部,需要通过(schema DeepLink)跳转。
4. 异步回调通知注意事项
解答:
1、回调地址必须真实存在; 2、协议格式: application/json; 3、协议返回内容:请查看【异步通知】 地址不通的问题(如果商户服务器对外部 IP 地址访问有限制,需要将payermax服务器IP地址添加到商户服务器的白名单中。
5. 点击"确认支付"按钮后,没有打开后续支付页面
问题:
API标准入款接入方式,点击”确认支付”按钮后,没有打开后续支付页面
解答:
如果打开API的容器是Android的WebView,需要对WebView做如下处理,下面是示例代码:
mWebView.setWebViewClient(new WebViewClient());
6. 进入收银台,页面提示“请求参数格式错误”
问题:
商户使用String.format(Locale.default(), "%.2f", price)格式化金额,造成金额格式为乱码
解答:
由于Locale.getDefault()是获取当前设备的所在地区的locale,不同地区格式后的字符串不一样。建议使用 String.format(Locale.ENGLISH, "%.2f", price)
7. 使用UPI支付时,出现界面没有办法退出
问题:
使用UPI支付进入到渠道页,操作然后点击返回键没有办法回到上个页面或者退出后,再次进入打不开收银台
解答:
如果商户在离开webView时,使用“webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);"关闭当前JS线程。需要修改为“webView.loadUrl("about:blank");”
8. 收银台页面支付方式展示不全或者样式混乱等适配问题
问题:
如果遇到收银台页面支付方式展示不全或者样式混乱,例如:示例.png
解答:
商户需要设置webView的下面参数:
mWebView.getSettings().setTextZoom(100);
9. 支付时软键盘覆盖输入框
问题:
在支付时,有些输入方式需要输入手机号或邮箱,这时候点击输入框,软键盘会覆盖输入框。
解答:
出现上面问题,需要对容器做如下检查:
- 不要设置全屏模式
- windowSoftInputMode可以不设置或者设置为adjustResize, 不要设置为adjustPan
- 如果是沉浸式状态栏,需要在布局中设置fitSystemWindows=true
10. 商户传给PayerMax的URI是大写的APP://开头,为什么我方在跳转的时候变成了app://开头的?
因为浏览器和webview自动转换的,cheme在浏览器里是不分大小写的,会统一转为小写。 在manifest中配置时,scheme 和 host 都要全为小写
11. 页面报这类错误'X-Frame-Options' 是什么原因
一般是渠道侧页面不支持iframe嵌套,请检查下 web服务中是否设置 X-Frame-Options。
12. 如果打开收银台链接地址的容器是Android WebView,请参考下面代码设置
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setPluginState(WebSettings.PluginState.ON); //enable plugin. Ex: flash. deprecated on API 18
//whether the zoom controls display on screen.
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
webSettings.setDisplayZoomControls(false);
//disable the webview font size changes according the phone font size.
webSettings.setTextZoom(100);
webSettings.setSaveFormData(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
webSettings.setAllowUniversalAccessFromFileURLs(true);
}
webSettings.setAppCacheEnabled(true);
String appCacheDir = getDir("cache", Context.MODE_PRIVATE).getPath();
webSettings.setAppCachePath(appCacheDir);
webSettings.setAppCacheMaxSize(1024*1024*20);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
try {
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
mWebView.removeJavascriptInterface("accessibility");
mWebView.removeJavascriptInterface("accessibilityTraversal");
} catch (Exception e) {}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mWebView.enableSlowWholeDocumentDraw();
}
13. 页面报"net::ERR_CACHE_MISS"
这是因为网络权限配置异常。可以更改 AndroidManifest.xml 中的权限配置尝试。 old: new: 参考:https://stackoverflow.com/questions/30637654/android-webview-gives-neterr-cache-miss-message
14. 系统浏览器正常,用 iOS 的 wkwebview 跳转会失败,无法正常打开页面
这个可能原因是wkwebview 更改 url 编码,导致链接异常,链接中 # 被 urlEncode 为 %23。可以webview 增加代码逻辑,避免 url 被异常编码
OC
-(NSString *)WM_FUNC_urlEncode:(NSString *)urlStr{
NSMutableCharacterSet *set = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[set addCharactersInString:@"#"];
return [urlStr stringByAddingPercentEncodingWithAllowedCharacters:set];
}
swift 4.0
func WM_FUNC_urlEncode(_ urlStr:String) -> String {
if urlStr.isEmpty {
return ""
}
var charSet = CharacterSet.urlQueryAllowed
charSet.insert(charactersIn: "#")
let encodingURLStr = urlStr.addingPercentEncoding(withAllowedCharacters: charSet)
return encodingURLStr ?? ""
}
下面模仿oc写法: CharacterSet 转换 NSMutableCharacterSet 来操作
func WM_FUNC_urlEncode(_ urlStr:String) -> String {
if urlStr.isEmpty {
return ""
}
let charSet = CharacterSet.urlQueryAllowed as NSCharacterSet
let mutSet = charSet.mutableCopy() as! NSMutableCharacterSet
mutSet.addCharacters(in: "#")
let encodingURLStr = urlStr.addingPercentEncoding(withAllowedCharacters: mutSet as CharacterSet)
return encodingURLStr ?? ""
}
func WM_FUNC_urlEncode(_ urlStr:String) -> String {
if urlStr.isEmpty {
return ""
}
let charSet = NSMutableCharacterSet()
charSet.formUnion(with: CharacterSet.urlQueryAllowed)
charSet.addCharacters(in: "#")
let encodingURLStr = urlStr.addingPercentEncoding(withAllowedCharacters: charSet as CharacterSet)
return encodingURLStr ?? ""
}
参考: https://www.jianshu.com/p/e4938ada31e6
15.安卓9.0 以上手机打不开页面,协议改成 https,9.0 以下的都好了,以上的不行。
这个原因可能是Android P 限制了 http 协议的明文流量的网络请求,非加密的流量请求都会被系统禁止掉。您可以将相关 api / 页面更换成 https 协议 若仍需使用 http,可通过下列方法使 Android webview 支持 http 协议:
方法一: 1.res 目录下新建 xml 目录,xml 目录下新建 network_security_config.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
2.AndroidManifest.xml
<application android:networkSecurityConfig="@xml/network_security_config">
<!--android9.0适配-->
<uses-library android:name="org.apache.http.legacy" android:required="false" />
</application>
方法二: AndroidManifest.xml添加:
<application android:usesCleartextTraffic="true">
参考 https://juejin.cn/post/6844903813929762824
16.webview 加载页面报错,net::ERR_BLOCKED_BY_RESPONSE。
这个原因是该地址不支持在 iframe 中使用。建议您将页面地址直接打开,不在 iframe 中使用。
【付款】
误认为出款接口响应码APPLY_SUCCESS为支付成功
问题:
收到出款接口响应码是APPLY_SUCCESS, 以为支付成功
解答:
响应码APPLY_SUCCESS只是说明当前协议响应是成功的;如果要查询是否支付成功,以服务端回调结果为准(商户传入或配置服务端回调地址)或以主动查询为准。
【参数配置】
1.如何生成密钥?
您可登录商户平台,通过「开发参数」频道生成和重置密钥。配置时,需注意区分测试环境和正式环境。
2.如何添加回调地址?
PayerMax支持两种方式设置回调地址:
- 拥有开发参数权限的操作员或超级管理员可在商户平台中的「开发参数」频道生成和修改回调地址。
- 在下单时传入回调地址。 注意:若您传入的回调地址和商户平台配置的回调地址有冲突,以您传入的回调地址为准。
3.为何没收到回调通知?
- 请确认是否设置回调地址。
- 请确认回调地址是否填写正确,若仍有问题,请联系PayerMax平台查明原因。