- 手机网银Android接入开发包
- 手机网银IOS接入开发包
iOS-手机银行API移动端对接
一、app配置银行Scheme
银行Scheme | 银行名称 |
---|---|
cmbmobilebank | 招商银行 |
cmbnetpay | 招商银行 |
com.icbc.iphoneclient | 工商银行 |
ccbmbsylunionpay | 建设银行 |
ccbmbswebunionpay | 建设银行 |
bocpay | 中国银行 |
bankabc | 农业银行 |
paesuperbank | 平安银行 |
cmbc | 民生银行 |
cebbank | 光大银行 |
credit | 广发银行 |
citicbankpay | 中信银行 |
二、跳转银行方式
1、app跳转网银
判断是否安装银行app
- (BOOL)openBanAppWithAppScheme:(NSString *)scheme
{
NSURL *url = [NSURL URLWithString:scheme];
BOOL isCanOpen = [[UIApplication sharedApplication] canOpenURL:url];
if (isCanOpen) {
#ifdef NSFoundationVersionNumber_iOS_10_0
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
#else
[[UIApplication sharedApplication] openURL:url];
#endif
[self goBackToRoot];
}else
{
[[BFMobileQuickPayAlertView sharedInstance] showAlertController:self title:nil message:@"请下载APP" cancelTitle:@"确定" actionBlock:^(NSInteger buttonTag) {
} otherButtonTitles:nil, nil];
return YES;
}
return isCanOpen;
}
判断打开app还是h5支付
- (void)openBankWithParams:(id)params reqUrl:(NSString *)reqUrl orderId:(NSString *)orderId
{
if ([reqUrl hasPrefix:@"https://"] || [reqUrl hasPrefix:@"http://"]) {
//h5链接 走WKWebView
NSMutableArray *paramsMutable = [NSMutableArray arrayWithArray:params];
if ([self.selectedModel.functionId isEqualToString:gsBank_debit]||[self.selectedModel.functionId isEqualToString:gsBank_credit]) {
// 工商银行特殊处理
NSURL *url = [NSURL URLWithString:@"com.icbc.iphoneclient://"];
BOOL isCanOpen = [[UIApplication sharedApplication] canOpenURL:url];
if (isCanOpen) {
[paramsMutable addObject:@{@"fieldName":@"clientType",@"filedValue":@"1"}];
}else
{
[paramsMutable addObject:@{@"fieldName":@"clientType",@"filedValue":@"0"}];
}
}
BFMobileQuickPayWebViewController *webVC = [BFMobileQuickPayWebViewController new];
webVC.urlString = reqUrl;
webVC.postParams = paramsMutable;
webVC.bankPay = YES;
[self.navigationController pushViewController:webVC animated:YES];
}else
{
//唤醒app
if ([params count]>0) {
//app柜台
NSDictionary *paramsDict = params[0];
NSString *fieldName = paramsDict[@"fieldName"];
NSString *filedValue = paramsDict[@"filedValue"];
NSString * charaters = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:charaters] invertedSet];
filedValue = [filedValue stringByAddingPercentEncodingWithAllowedCharacters:set];;
if ([self.selectedModel.functionId isEqualToString:paBank_debit]||[self.selectedModel.functionId isEqualToString:paBank_credit]) {
// 平安银行兼容处理
NSString *url = @"https%3A%2F%2Fb.pingan.com.cn%2Fpay%2Fpeps%2Fgateway%2Fkoudai-payment.html";
reqUrl = [NSString stringWithFormat:@"paesuperbank://?url=%@&extra=1&AD=0&%@=%@",url,fieldName,filedValue];
}else
{
reqUrl = [NSString stringWithFormat:@"%@&%@=%@",reqUrl,fieldName,filedValue];
}
}
if (![self openBanAppWithAppScheme:reqUrl]) {
BFMobileQuickPayWebViewController *webVC = [BFMobileQuickPayWebViewController new];
webVC.urlString = reqUrl;
webVC.postParams = params;
webVC.bankPay = YES;
[self.navigationController pushViewController:webVC animated:YES];
}
}
}
2、内置H5打开银行付款页面
表单提交JS
#define POST_JS @"function my_post(path, params) {\
var method = \"POST\";\
var form = document.createElement(\"form\");\
form.setAttribute(\"method\", method);\
form.setAttribute(\"action\", path);\
for(var key in params){\
if (params.hasOwnProperty(key)) {\
var hiddenFild = document.createElement(\"input\");\
hiddenFild.setAttribute(\"type\", \"hidden\");\
hiddenFild.setAttribute(\"name\", key);\
hiddenFild.setAttribute(\"value\", params[key]);\
}\
form.appendChild(hiddenFild);\
}\
document.body.appendChild(form);\
form.submit();\
}"
打开WKWebView
//self.urlString self.postParams都是 下单返回的网联 银联参数
//加载H5
-(void)loadWebView
{
[BFMobileQuickPayWebViewController clear];
if (self.urlString.length==0) {
return;
}
self.urlString = [NSString URLEncodedString:self.urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:self.urlString]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:5];
[_webView loadRequest:request];
NSArray *array = (NSArray *)self.postParams;
NSMutableDictionary *jsonRequestData = @{}.mutableCopy;
for (NSDictionary *paramsDict in array) {
NSString *fieldName = paramsDict[@"fieldName"];
NSString *filedValue = paramsDict[@"filedValue"];
[jsonRequestData setObject:filedValue forKey:fieldName];
}
if (jsonRequestData.count>0) {
// 要传递的参数,(在开发中可以字典转成json字符串即可)
NSString *jsonString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:jsonRequestData options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSString * dataStr = jsonString;
// 发送的地址
// 最终要执行的JS代码
NSString * js = [NSString stringWithFormat:@"%@my_post(\"%@\", %@)",POST_JS,self.urlString,dataStr];
DebugLog(@"js = %@",js);
// 执行JS代码
[self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
if (!error) { // 成功
DebugLog(@"post成功:%@",response);
} else { // 失败
DebugLog(@"post失败:%@",error);
}
}];
}
}
3、H5跳转APP支付
在WKWebView代理里面进行操作
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
DebugLog(@"请求的地址是:%@",navigationAction.request.URL.absoluteString);
if ([navigationAction.request.URL.absoluteString rangeOfString:@"http://gwrecv.baofoo.com/b2cbank/page/nucc"].location != NSNotFound) {
//返回商户
[self goBack];
decisionHandler(WKNavigationActionPolicyCancel);
}else if ([navigationAction.request.URL.absoluteString rangeOfString:@"https://mobile.abchina.com"].location != NSNotFound&&[navigationAction.request.URL.absoluteString rangeOfString:@"TOKEN="].location != NSNotFound)
{
农行特殊处理 需要提前引入农行的sdk
NSString *tokenString = @"";
NSArray *array = [navigationAction.request.URL.absoluteString componentsSeparatedByString:@"?"];
if (array.count>1) {
tokenString = array[1];
NSArray *tokenArray = [tokenString componentsSeparatedByString:@"="];
if (tokenArray.count>1) {
NSString *TokenID = tokenArray[1];
if ([[ABCAppCaller sharedAppCaller] isABCePayAvailable:@"bankabc://"]) {
[[ABCAppCaller sharedAppCaller] callBankABC:@"bankabc" param:[NSString stringWithFormat:@"CallbackID=mobile_quick_pay_app_demo&TokenID=%@&Method=pay",TokenID]];//如果已安装掌银则调起掌银,两个参数分别为掌银的URL标示以及送的参数,参数格式参考标准url传参格式
[self goBack];
}
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
else if (([navigationAction.request.URL.absoluteString rangeOfString:@"cmbnetpay://"].location != NSNotFound)||([navigationAction.request.URL.absoluteString rangeOfString:@"ccbmbswebunionpay://"].location != NSNotFound)||([navigationAction.request.URL.absoluteString rangeOfString:@"bocpay://"].location != NSNotFound)||([navigationAction.request.URL.absoluteString rangeOfString:@"com.icbc.iphoneclient://"].location != NSNotFound)||([navigationAction.request.URL.absoluteString rangeOfString:@"cebbank://"].location != NSNotFound))
{
BOOL isCanOpen = [[UIApplication sharedApplication] canOpenURL:navigationAction.request.URL];
if (isCanOpen) {
#ifdef NSFoundationVersionNumber_iOS_10_0
kWeakSelf(self)
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{} completionHandler:^(BOOL success) {
kStrongSelf(self)
}];
#else
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
#endif
[self goBack];
}
decisionHandler(WKNavigationActionPolicyCancel);
}
else
{
decisionHandler(WKNavigationActionPolicyAllow);
}
}
安卓-手机银行API移动端对接
1.需要单独判断是否安装APP,如果已安装则跳转APP,如果未安装则需要通过WebView进行加载处理。
2.WebView加载处理,(农业银行需要再Webview中特殊处理)跳转逻辑由银行H5进行处理。
一.通用Webview加载
1.WebView加载需要对返回参数进行处理,然后通过表单模式提交
/**
* 加载H5
* @param bankWebBean
* @param intentRequestWay
*/
private void loadUrl(BankWebBean bankWebBean,String intentRequestWay){
Map<String, String> map = new HashMap<>();
map.put(bankWebBean.getFieldName(), bankWebBean.getFiledValue());
String vaule = JsonUtils.toJsondisableHtmlEscaping(map);
showProgess();
if (intentRequestWay.equals("GET")) {
wvShow.loadUrl(intentUrl + "?" + intentParams);//get请求
} else if (intentRequestWay.equals("POST")) {
wvShow.loadUrl("javascript:" + Constants.H5FormSubmit);
wvShow.loadUrl("javascript:my_post('" + intentUrl + "','" + vaule + "')");
} else {
Toast.makeText(this, "请求方式参数错误", Toast.LENGTH_SHORT).show();
}
}
public static final String H5FormSubmit = "function my_post(path, params) {\n" +
"var datas = JSON.parse(params);\n" +
"var method = \"POST\";\n" +
"var form = document.createElement(\"form\");\n" +
"form.setAttribute(\"method\", method);\n" +
"form.setAttribute(\"action\", path);\n" +
"form.setAttribute(\"enctype\", \"application/x-www-fom-urlencoded\");\n" +
"for(var key in datas){\n" +
" if (datas.hasOwnProperty(key)) {\n" +
" var hiddenFild = document.createElement(\"input\");\n" +
" hiddenFild.setAttribute(\"type\", \"hidden\");\n" +
" hiddenFild.setAttribute(\"name\", key);\n" +
" hiddenFild.setAttribute(\"value\", datas[key]);\n" +
" }\n" +
" form.appendChild(hiddenFild);\n" +
"}\n" +
"document.body.appendChild(form);\n" +
"form.submit();\n" +
"}";
2.在webview shouldOverrideUrlLoading中判断url是否为Http或者 https开头,如果是继续加载,如果不是,则跳转通过Uri跳转原生
二.农业银行
跳转农行APP需提前报备,相关报备信息请查看农业银行快e付报备模板.xlsx
1.引入农行jar包 bankabccaller.jar
2.再shouldINterceptRequest中拦截判断,然后跳转
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (request.getUrl().toString().contains("http://gwrecv.baofoo.com/b2cbank/page/nucc")) {
finishCurrentActivity();
}
String url = request.getUrl().toString();
if (url.contains("https://mobile.abchina.com") && //判断农业银行跳转
url.contains("TOKEN=")) {
JumpToBankApp.jumpToABCAPP(activity,request.getUrl().toString());
}
return super.shouldInterceptRequest(view, request);
}
/**
* H5判断农行跳转
* @param url
*/
public static void jumpToABCAPP(Activity activity,String url){
if (JumpToBankApp.isABCAppInstaller(activity)) { //农行逻辑处理
String tokenId = url.split("=")[1];
BankABCCaller.startBankABC(activity,
activity.getPackageName(),
"com.baofu.mobilequickpay.ui.activity.MobileBankPayActivity",
"pay",
tokenId);
activity.setResult(EnvConfig.MOBILE_BANK_PAY_RESULT_CODE);
activity.finish();
}
}
/**
* 判断农行是否安装
* @param context
* @return
*/
public static boolean isABCAppInstaller(Context context){
/**
* 判断手机上是否具备调起农行掌银的条件
*/
if (BankABCCaller.isBankABCAvaiable((Activity) context)) {
return true;
} else {//客户手机未安装农行掌银APP的处理逻辑,由第三方APP自行实现
return false;
}
}
三.招商银行
1.根据包名判断是否安装app
public static boolean checkApkExist(Context context, String packageName){
PackageManager manager = context.getPackageManager();
List<PackageInfo> pkgList = manager.getInstalledPackages(0);
for (int i = 0; i < pkgList.size(); i++) {
PackageInfo pI = pkgList.get(i);
if (pI.packageName.equalsIgnoreCase(packageName))
return true;
}
return false;
}
2.如果已安装APP则通过跳转外部浏览器跳转招商APP
public static void callBankApp(Activity context,String url) {
try {
Intent intent = new Intent();
Uri data = Uri.parse(url);
intent.setData(data);
intent.setAction("android.intent.action.VIEW");
context.startActivityForResult(intent, EnvConfig.MOBILE_NATIVE_BANK_PAY_REQUEST_CODE);
} catch (Exception e) {
e.printStackTrace();
}
}
3.未安装APP
跳转webview打开地址
四.平安银行
1.根据包名判断是否安装平安银行APP(同招商银行判断方式)
2.已安装,跳转平安银行app(跳转方式同招商银行)
平安银行跳转路径已经参数需要重新组装
public static String assemblyPingAnUrl(MobileBankPayResponse response){
String pingAnURL = "paesuperbank://?url=https%3A%2F%2Fb.pingan.com.cn%2Fpay%2Fpeps%2Fgateway%2Fkoudai-payment.html&extra=1&AD=0&";
for(int i = 0;i<response.getReqParams().size();i++){
if(i == response.getReqParams().size()-1){
pingAnURL = pingAnURL+response.getReqParams().get(i).getFieldName()+
"="+ URLEncoder.encode(response.getReqParams().get(i).getFiledValue());
}else{
pingAnURL = pingAnURL+response.getReqParams().get(i).getFieldName()+"="+
URLEncoder.encode(response.getReqParams().get(i).getFiledValue())+"&";
}
}
return pingAnURL;
}
3.未安装通过webview加载
作者:xiaofeng 创建时间:2023-06-12 19:45
最后编辑:xiaofeng 更新时间:2025-01-09 17:41
最后编辑:xiaofeng 更新时间:2025-01-09 17:41