Phonegap项目,做支付的时候,当把网站打包到ios或android端成app后,在app上通过wap调用银联在线存在一个问题:

就是当从银联支付成功后,再从服务器返回到app客户端就很难实现。

  wap银联支付流程是这样:客户端—> 服务器(构建支付请求)–> 银联支付 —> 返回到服务端(处理支付结果)。所以对于手机网站银联支付没有问题,但是对于ios端app和android端app, 再通过wap支付,发现支付成功后,很难在回到app客户端了。

所以这里就必须借助Phonegap的插件js脚本,通过js调用ios端或android端原生代码,然后再通过原生代码调用银联支付专门为移动客户端准备的sdk,去进行支付。支付成功后,银联会把支付结果一边通知到我们网站你的服务器,另一方面也会把给一个通知到ios或android客户端,这样就完美了!

  ——————————————————————————————————————————

  先上Phonegap项目ios端app如何调用银联在线的支付流程截图:

1、客户端请求银联支付,网站服务端构建银联支付请求;并从银联获得银联生成的系统流水号

2、通过Phonegap脚本插件,调用OC代码,OC调用银联支付接口,弹出银联支付控件,输入你的银联卡号和手机验证码等信息,完成支付

3、支付成功后,点击“返回商户”, 银联一边会回传一个信息到网站服务端,一边也会通知ios端app的代理控制器支付结果。

  然后ios端这边可以根据银联返回的支付信息,做自己的业务逻辑处理。

———————————— 大概代码如下: ——————————-

1、客户端选择银联支付,js端代码:

//模拟去服务器端构建银联请求, myApp是使用Framework7框架创建的一个js对象
function toPay() {var ServerDomain = "http://192.168.1.189"; //网站服务端地址var isApp = ServerDomain.indexOf(location.hostname) > 0 ? "0" : "1";  //是否来自app的请求$$.ajax({url: ServerDomain + "Payment/CreateOrderInfo",method: "post",dataType: "json",data: { "isApp": isApp },success: function (data) {if (data.success == "0") {myApp.alert(data.info); //弹窗提示信息return false;}//data.info 信息,如果是通过手机网站访问,则data.info是一个form表单html页面代码;//如果是移动客户端(ios或android),则data.info是来自银联的系统流水号:tnif (isApp == "0") { //来自wap的请求//针对手机网站的银联支付请求,直接构建get请求表单,跳转到银联那边document.write(data.info); }else if (myApp.device.ios) { //来自ios app的请求Cordova.exec(function (successInfo) { /*成功通知方法*/ }, function (errorInfo) { /*失败回调通知方法*/ }, "PluginName", "uppay", [data.info]);}else if (myApp.device.android) { //来自android app的请求UnionPayFunc(data.info);}}});
}

2、服务端构建银联支付请求代码,服务端使用C#的MVC

public class PaymentController : Controller{/// <summary>测试构建银联支付请求:如果是wap请求,则构建form表单;若是app请求,则获取银联系统流水号/// </summary>/// <param name="isApp">是否来自app的请求【0表示来自wap, 1表示来自android】</param>/// <returns></returns>public JsonResult CreateOrderInfo(int isApp){//以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考// **************演示前台交易的请求***********************Dictionary<string, string> param = new Dictionary<string, string>();//生成订单编号Random rnd = new Random();string orderID = DateTime.Now.ToString("yyyyMMddHHmmss") + (rnd.Next(900) + 100).ToString().Trim(); param["version"] = "5.0.0";//版本号param["encoding"] = "UTF-8";//编码方式param["certId"] = CertUtil.GetSignCertId(); //证书ID(签名私钥证书的Serial Number)param["txnType"] = "01";//交易类型:00=查询交易,01=消费,04=退货,12=代付,21=批量交易,22=批量查询param["txnSubType"] = "01";//交易子类,依据实际交易类型填写param["bizType"] = "000201";//产品类型:000201=B2C网关支付,000401=代付,000501=代收,000601=账单支付,000901=绑定支付,000202=B2Bparam["frontUrl"] = "http://192.168.1.189/Payment/UppayFront"; //前台通知地址(前台返回商户结果时使用,前台类交易需上送)     param["backUrl"] = "http://192.168.1.189/Payment/UnppayBack";  //后台通知地址,改自己的外网地址(后台返回商户结果时使用,如上送,则发送商户后台交易结果通知)//param["frontFailUrl"] = "http://192.168.1.189/Payment/UnppayFail";//失败交易前台跳转地址(可选:支付失败时,页面跳转至商户该URL,不带交易信息,仅跳转)param["signMethod"] = "01";//签名方法(01:表示采用RSA)param["channelType"] = "08";//渠道类型: 05=语音,07=互联网(PC),08=移动(手机)param["accessType"] = "0";//接入类型:0=商户直连接入,1=收单机构接入,2=平台商户接入param["merId"] = "111111111111111";//商户代码(请填入已被批准加入银联互联网系统的商户代码)param["orderId"] = orderID;//商户订单号(不能含”-“或”_")param["txnTime"] = DateTime.Now.ToString("yyyyMMddHHmmss");//订单发送时间param["txnAmt"] = "1";//交易金额,单位分param["currencyCode"] = "156";//交易币种(币种格式必须为3位代码,默认取值:156(人民币))//param["orderDesc"] = "订单描述";//订单描述,暂时不会起作用param["reqReserved"] = "";//请求方保留域,透传字段,查询、通知、对账文件中均会原样出现//将参数进行签名SDKUtil.Sign(param, Encoding.UTF8);string returnInfo = ""; //返回信息string isSuccess = "1"; //if (isApp == 0)//wap请求,则返回form表单请求请求{// 将SDKUtil产生的Html文档写入页面,从而引导用户浏览器重定向   returnInfo = SDKUtil.CreateAutoSubmitForm(SDKConfig.FrontTransUrl, param, Encoding.UTF8) + "<script type='text/javascript'>OnLoadSubmit();</script>";}else if (isApp == 1)//app请求,则返回银联生成的系统流水号{// 初始化通信处理类HttpClient hc = new HttpClient(SDKConfig.AppRequestUrl);//// 发送请求获取通信应答int status = hc.Send(param, Encoding.UTF8);// 返回结果string result = hc.Result;if (status != 200){isSuccess = "0";returnInfo = "请求银联失败";return Json(new { success = isSuccess, info = returnInfo }, JsonRequestBehavior.AllowGet);}Dictionary<string, string> resData = SDKUtil.CoverstringToDictionary(result);if (!SDKUtil.Validate(resData, Encoding.UTF8)){returnInfo = "验证失败";isSuccess = "0";return Json(new { success = isSuccess, info = returnInfo }, JsonRequestBehavior.AllowGet);}string respCode = resData["respCode"];string respMsg = resData["respMsg"];returnInfo = resData["tn"]; //银受理订单号:商户推送订单后银联移动支付系统返回该流水号,商户调用支付控件时使用}return Json(new { success = isSuccess, info = returnInfo }, JsonRequestBehavior.AllowGet);}///........
}

3、ios端代码,js脚本调用OC代码需要Phonegap提供的一个脚本插件支持: cordova.js (下载链接)

  创建一个类Plugin, 继承Phonegap插件类:CDVPlugin,

  还需要在配置文件config.xml中配置一下,才能使用js调用Plugin类里面的方法

#import <UIKit/UIKit.h>
#import <Cordova/CDVPlugin.h>@interface Plugin : CDVPlugin@property (nonatomic, copy) NSString* callbackID;//支付
- (void)uppay:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;@end
#import "Plugin.h"
#import "MainViewController.h"
#import "UPPayPlugin.h"@interface Plugin ()@end@implementation Plugin@synthesize callbackID;- (void)uppay:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options{// 这是classid,在下面的PluginResult进行数据的返回时,将会用到它self.callbackID = [arguments pop];NSString *tn = [arguments objectAtIndex:0]; //获取银联生成返回的系统流水号MainViewController *controller = (MainViewController *)self.viewController;//调用银联支付接口[UPPayPlugin startPay:tn mode:@"00" viewController:controller delegate:controller];
}@end

  代理控制器设置银联支付结束后的代理方法:

#import <Cordova/CDVViewController.h>
#import <Cordova/CDVCommandDelegateImpl.h>
#import <Cordova/CDVCommandQueue.h>
#import "UPPayPluginDelegate.h"@interface MainViewController : CDVViewController <UPPayPluginDelegate>//..........@end
#import "MainViewController.h"
#import "AppDelegate.h"@implementation MainViewController#pragma mark - 支付结束后代理方法
//success、fail、cancel,分别代表:支付成功、支付失败、用户取消支付
-(void)UPPayPluginResult:(NSString*)result
{NSLog(@"支付结果:%@", result);//调用脚本方法,处理支付完成后的逻辑[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"unipayPayResult('%@');", result]];
}//.......@end

4、支付成功后,ios 控制器收到银联的支付结果,调用js脚本方法,处理后面逻辑: 

// ios支付成功后,收到银联通知跳转到其他页面去, info参数有三种状态:success, fail, cancl
function unipayPayResult(info) {var textTip = "";if (info == "success") {textTip = "支付成功";}else if (info == "fail") {textTip = "支付失败";}else {textTip = "取消支付";}myApp.alert(textTip);//弹窗提示后,跳到主页面去mainView.loadPage("index.html");
}

原文链接地址:http://www.cnblogs.com/tandaxia/p/4964753.html

cordova for iOS 通过js调用OC原生代码demo:

github地址:https://github.com/xiaotanit/Tan_CordovaPlugin

csdn地址: http://download.csdn.net/detail/tandaxia/9524576

Phonegap 之 iOS银联在线支付(js调用ios端银联支付控件相关推荐

  1. asp.net页面回传与js调用服务端事件,Postback的原理

    Asp.net 中在客户端触发服务器端事件分为两种情况: 一.   WebControls中的Button 和HtmlControls中的Type为submit的HtmlInputButton 这两种 ...

  2. asp.net页面回传与js调用服务端事件、PostBack的原理详解(转)

    Asp.net中服务端控件事件是如何触发的 Asp.net 中在客户端触发服务器端事件分为两种情况: 一.   WebControls中的Button 和HtmlControls中的Type为subm ...

  3. asp.net页面回传与js调用服务端事件、PostBack的原理详解

    ASP.ENT中,有两种实现页面PostBack的机制,不管是哪种回传方式,最终均是Form表单提交. 一.原始的Form表单提交 WebControls中的Button和ImageButton控件, ...

  4. 15 ArcGIS JS API 4.17更改测量控件黄白相间的默认样式

    问题描述 在使用ArcGIS API for JavaScript 4.17开发项目时,有一个需求是需要在地图上添加距离测量和面积测量的控件,这其实很简单,直接调用ArcGIS JS API自带的测量 ...

  5. C# winform中一个类中如何调用另一个窗体的控件或方法

    转载地址:http://blog.csdn.net/ichenqingyun/article/details/52622340 一种是创建窗体对象的方式,通过对象调用控件或方法 例如: Form1 f ...

  6. 解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件的问题

    解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件的问题 参考文章: (1)解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件的问题 ( ...

  7. 在一个窗体中调用另一个窗体的控件或方法(C#)

    在一个窗体中调用另一个窗体的控件或方法 解决方案:从构造函数中传递参数(Form). 1.将Form1中的控件改成public属性 具体实现过程请参看一下代码(在form1的textbox1中输入然后 ...

  8. html页面美化代码时间,CSS+JS美化过漂亮的日历控件

    CSS+JS美化过漂亮的日历控件 - www.webdm.cn var months = new Array("一", "二", "三",& ...

  9. Qt开发Activex笔记(二):Qt调用Qt开发的Activex控件

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/113789693 长期持续带来更多项目与技术分 ...

  10. js调用ios的方法

    摘要 在做h5应用的时,有时有些功能js并不能实现的特别完美.比如下载进度条或上传文件进度等.如果能调用ios或者android的方法,实现进度,以及文件上传或者下载列表更好一些.如果使用第三方的js ...

最新文章

  1. Effective C++ 1.0 -- 概述
  2. (一)七种AOP实现方法
  3. 伽卡他卡电子教室 百度百科_怎么创建人物百度百科?人物百度百科创作技巧...
  4. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
  5. C#中的thread和task之Task
  6. [CF1082E] Increasing Frequency
  7. C++中判断在字符串中是否存在空格 以及 如何输入带空格的字符串
  8. 2019年的web前端领域
  9. NOIP201208同余方程
  10. 魅族17系列渲染图曝光:“防爆盾”后盖引网友无限吐槽
  11. Kali学习笔记15:防火墙识别、负载均衡识别、WAF识别
  12. Java神鬼莫测之MyBatis多表操作延迟加载(四)
  13. android 仿qq it蓝豹,十大Android开源项目-IT蓝豹
  14. 计算机视觉常用图像软件对比和分析
  15. 商务周刊:手机新三国演义
  16. 简单一步解决网页内容无法复制
  17. 【Axure高保真原型】上传表格数据
  18. 深入理解Nginx:java业务逻辑层都用什么技术
  19. Linux 安装ssh和配置ssh
  20. FL Studio乐理教程之调式音阶

热门文章

  1. 【VISIO安装问题】无法安装64位版本的office,因为在您的PC上找到以下32位程序
  2. 已知函数ex可以展开为幂级数。现给定一个实数x,要求利用此幂级数部分和求ex的近似值,求和一直继续到最后一项的绝对值小于0.00001。
  3. Scratch3.0 保存缩略图
  4. php7.4中让gd库支持jpeg格式
  5. Excel基础知识(3):工作表两种隐藏方法,第2种只能进入VBA解决
  6. movielens数据集简述
  7. JavaScript获取浏览器高度和宽度值
  8. 2019深圳杯获奖论文_深圳杯数学建模A题获奖论文
  9. 一个时代的剪影-----汉 (作者:金立扬)
  10. 51单片机c语言延时一秒,单片机C语言的延时