长话短说,本文根据银联官方说明文档,简单总结下,并且说明下中途碰到问题该如何解决。

一、开发前的准备工作
1. 打开https://open.unionpay.com/,后续说的文档下载、FAQ查询等都在这个平台操作。
2. 下载规范和开发包。帮助中心-下载-产品接口规范-手机控件支付产品接口规范,帮助中心-下载-产品接口规范-手机控件支付产品技术开发包。
3. 开发人员都请先看下6.2的消费的交易流程。

流程图说明:
(1)用户在客户端中点击购买商品,客户端发起订单生成请求到商户后台;
(2)商户后台收到订单生成请求后,按照《手机控件支付产品接口规范》组织并推送订单信息至银联后台;
(3)银联后台接收订单信息并检查通过后,生成对应交易流水号(即TN),并回复交易流水号至商户后台(应答要素:交易流水号等);
(4)商户后台接收到交易流水号,将交易流水号返回给客户端;
(5)客户端通过交易流水号(TN)调用支付控件;
(6)用户在支付控件中输入相关支付信息后,由支付控件向银联后台发起支付请求;
(7)支付成功后,银联后台将支付结果通知给商户后台;
(8)银联将支付结果通知支付控件;
(9)支付控件显示支付结果并将支付结果返回给客户端;
注: 本文档主要关注上述流程中(5)、(9)部分的实现
目前各个平台支持的设备情况如下:
Android平台SDK主要适用于Android 2.1及以上版本的终端设备;
iOS版本支付控件适用iOS 6.0及以上版本终端设备。

4. 相关测试参数:
如果已签约,有自己的测试商户,则直接用自己的商户号测试,测试证书开发包里都有。* 尽量用真实商户号测试,防止有时候参数配错能尽早发现。
如果没有签约,或者商户号尚未分配,请在平台里自行获取商户并且开交易权限,方法为:
a) 左上角注册;
b) 登陆后右上角我的测试-测试参数
c) 我的测试-产品-选下自己集成的。

测试卡号信息:(此类信息仅供测试,不会发生正式交易)
借记卡:6226090000000048
手机号:18100000000
密码:111101
短信验证码:123456
(短信验证码记得点下获取验证码之后再输入)--如果提示短信验证码错误[8100201],要看下是测试环境还是生产环境,另外控件版本是否是最新的

贷记卡:6226388000000095;
手机号:18100000000;
cvn2:248;
有效期:1219;
短信验证码:123456
(短信验证码记得点下获取验证码之后再输入)

二、客户端开发步骤
1. 参考文档《中国银联手机支付控件使用指南》(该文档位于前台开发包的doc目录下),建立一下工程。
2. 在后台开发实现消费(获取tn)请求前,App开发可以看看demo代码怎么调起控件的,demo里默认由银联的一个商户仿真获取tn(http://202.101.25.178:8080/sim/gettn或http://101.231.204.84:8091/sim/getacptn),之后需要改从商户自己的后台那里获取tn的。
3. 后台开发完成消费请求后,与后台开发商讨一下后台和app间传递tn的方式。
4. 改为从自己后台tn做测试。
5. 自行增加其他业务逻辑。

这里介绍下,客户端整合jar包的方式,如下图,一目了然

控件的调用(BYbrid插件方式):

public class PayPlugin extends CordovaPlugin {

    @Override
public boolean execute(String action, JSONArray args,
CallbackContext callbackContext) throws JSONException { String tn = args.getString(0); if(action.equals("unionPay")) {
UPPayAssistEx.startPayByJAR(cordova.getActivity(),
PayActivity.class, null, null, tn, "00");
} return super.execute(action, args, callbackContext);
} }

返回结果处理(在MainActivity里面处理):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
/*************************************************
* 步骤3:处理银联手机支付控件返回的支付结果
************************************************/
if (data == null) {
return;
} String msg = "";
/*
* 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消
*/
String str = data.getExtras().getString("pay_result");
if (str.equalsIgnoreCase("success")) {
msg = "支付成功!";
} else if (str.equalsIgnoreCase("fail")) {
msg = "支付失败!";
} else if (str.equalsIgnoreCase("cancel")) {
msg = "用户取消了支付";
} Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}

集成方式说明:

安卓分为静态库集成和apk接入两种方式:Apk接入方式、静态库集成。
Apk接入方式:调用startPay方法,调起手机中单独安装的控件。
静态库集成:调用startPayByJar方法,调起内置在商户app里的控件。

2种方式对比:

Apk接入方式:控件为独立安装。把demo代码中未安装控件时的代码修改为从银联官网下载控件apk后,商户就可以不用关心控件的版本了。控件apk下载地址:http://mobile.unionpay.com/getclient?platform=android&type=securepayplugin。

静态库集成:安装完商户app之后不需要再安装一次控件,但是商户需关心控件版本是否升级。另外iOS也是静态库集成,同时需要集成iOS的推荐用此方法,2边一致。

* 遇到问题可到https://open.unionpay.com/先自行看看能否解决:
1) 如果是代码异常:帮助中心-FAQ中把异常拷贝一小段搜索;或可以到FAQ的开发问题类别下,搜“安卓”或“iOS”可搜到对应的全量开发问题。
2) 如果是控件出错,报错信息有7位数字:技术集成-应答码,输入7位数字搜索。
3) 如果是控件出错,没有报错信息或没有7位数字:帮助中心-FAQ-测试问题,搜“app”可搜到控件的全量测试问题。
* 开发包中有pro和不带pro的,请使用不带pro的开发包,pro的开发包因包含一般接入方不使用的特殊功能,有些代码需要特殊处理。
* 安卓用startPay还是用startPayByJar的问题参考FAQ“apk方式和jar方式有何区别”。

三、后台开发步骤
1. 打开后台开发包,找到对应语言\示例代码文件夹,看下readme.txt,按步骤部署、修改配置文件等。
2. 其中Form_6_2_AppConsume的接口可获取tn,请跟客户端开发确定一下后台和app间传递tn的方式,最简单的方法就是直接在页面打印tn,不过部分语言直接仅打印tn的时候会带换行符,建议手机开发在收到tn的时候trim一下。
3. 后续参考readme完成。

简单介绍下后台获取tn的方法:

// 参考Form_6_2_AppConsume.java

/**
* 组装请求报文
*/
Map<String, String> data = new HashMap<String, String>();
// 版本号
data.put("version", "5.0.0");
// 字符集编码 默认"UTF-8"
data.put("encoding", "UTF-8");
// 签名方法 01 RSA
data.put("signMethod", "01");
// 交易类型 01-消费
data.put("txnType", "01");
// 交易子类型 01:自助消费 02:订购 03:分期付款
data.put("txnSubType", "01");
// 业务类型
data.put("bizType", "000201");
// 渠道类型,07-PC,08-手机
data.put("channelType", "08");
// 前台通知地址 ,控件接入方式无作用
data.put("frontUrl", "http://localhost:8080/ACPTest/acp_front_url.do");
// 后台通知地址
data.put("backUrl", "http://222.222.222.222:8080/ACPTest/acp_back_url.do");
// 接入类型,商户接入填0 0- 商户 , 1: 收单, 2:平台商户
data.put("accessType", "0");
// 商户号码,请改成自己的商户号
data.put("merId", "888888888888888");
// 商户订单号,8-40位数字字母
data.put("orderId", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
// 订单发送时间,取系统时间
data.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
// 交易金额,单位分
data.put("txnAmt", "1");
// 交易币种
data.put("currencyCode", "156");
// 请求方保留域,透传字段,查询、通知、对账文件中均会原样出现
// data.put("reqReserved", "透传信息");
// 订单描述,可不上送,上送时控件中会显示该信息
// data.put("orderDesc", "订单描述"); data = signData(data); // 交易请求url 从配置文件读取
String requestAppUrl = SDKConfig.getConfig().getAppRequestUrl(); Map<String, String> resmap = submitUrl(data, requestAppUrl); System.out.println("请求报文=["+data.toString()+"]");
System.out.println("应答报文=["+resmap.toString()+"]");

如上 resmap.get("tn"); 就是我们所需要的交易流水号。

后台银联回调方法实现:

// 参考BackRcvResponse.java

protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { LogUtil.writeLog("BackRcvResponse接收后台通知开始"); req.setCharacterEncoding("ISO-8859-1");
String encoding = req.getParameter(SDKConstants.param_encoding);
// 获取请求参数中所有的信息
Map<String, String> reqParam = getAllRequestParam(req);
// 打印请求报文
LogUtil.printRequestLog(reqParam); Map<String, String> valideData = null;
if (null != reqParam && !reqParam.isEmpty()) {
Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
valideData = new HashMap<String, String>(reqParam.size());
while (it.hasNext()) {
Entry<String, String> e = it.next();
String key = (String) e.getKey();
String value = (String) e.getValue();
value = new String(value.getBytes("ISO-8859-1"), encoding);
valideData.put(key, value);
}
} // 验证签名
if (!SDKUtil.validate(valideData, encoding)) {
LogUtil.writeLog("验证签名结果[失败].");
} else {
System.out.println(valideData.get("orderId")); //其他字段也可用类似方式获取
LogUtil.writeLog("验证签名结果[成功].");
       // 这里写你的业务逻辑。。。
} LogUtil.writeLog("BackRcvResponse接收后台通知结束");
}

另外,支付回调有可能出现一次不会回调成功的情况,所以往往我们还需要在后台配置定时器来对你的支付数据表进行轮询,在轮询代码里面再次对银联全渠道平台发起交易状态查询,得到交易成功的信息之后才将支付表的临时数据删除:

// 参考 Form_6_5_Query.java

/**
* 组装请求报文
*/
Map<String, String> data = new HashMap<String, String>();
// 版本号
data.put("version", "5.0.0");
// 字符集编码 默认"UTF-8"
data.put("encoding", "UTF-8");
// 签名方法 01 RSA
data.put("signMethod", "01");
// 交易类型
data.put("txnType", "00");
// 交易子类型
data.put("txnSubType", "00");
// 业务类型
data.put("bizType", "000000");
// 渠道类型,07-PC,08-手机
data.put("channelType", "08");
// 接入类型,商户接入填0 0- 商户 , 1: 收单, 2:平台商户
data.put("accessType", "0");
// 商户号码,请改成自己的商户号
data.put("merId", "888888888888888");
// 商户订单号,请修改被查询的交易的订单号
data.put("orderId", "20150211215817604");
// 订单发送时间,请修改被查询的交易的订单发送时间
data.put("txnTime", "20150211215817"); data = signData(data); // 交易请求url 从配置文件读取
String url = SDKConfig.getConfig().getSingleQueryUrl(); Map<String, String> resmap = submitUrl(data, url); System.out.println("请求报文=["+data.toString()+"]");
System.out.println("应答报文=["+resmap.toString()+"]");

注意点:

1 如果支付成功但没有到账,有可能是回调方法出了问题,比如回调方法可能根本没进去(检查方法权限),或者回调方法可能抛出异常;

2 如果支付成功但没有马上到账,而是过了一个有规律的时间到账,那同意可能是回调方法出了问题,到账的原因是你的轮询方法起了作用。

* 遇到问题可到https://open.unionpay.com/先自行看看能否解决:
1) 如果是代码异常:帮助中心-FAQ中把异常拷贝一小段搜索;或可以到FAQ的开发问题类别下,搜“java”、“c#”、“php”可搜到对应的全量开发问题。
2) 如果是正常收到应答respcode非00,可以看一下respMsg,里面的7位数字在平台上技术集成-应答码搜索。
3) 如果是其他错,在FAQ的测试问题类别下看看是否有自己遇到的问题。

最重要的一点:

开发过程中难免碰到一些难点无法独立解决,这时可以联系银联的客服:

https://open.unionpay.com/ajweb/help?id=291

入网流程问题

业务申请和咨询,可发送邮件至operation@unionpay.com或电话021-50362428,银联有专门的人员进行处理。其他专项服务:请见《业务运营服务指引(商户) 》日常业务运营服务

入网测试问题
您可发送邮件到acpservice@unionpay.com邮箱,(邮件标题为:商户号+商户名称+联系QQ),提供商户号和联系QQ,银联测试服务专员会将商户接口人的联系QQ加入到银联统一服务QQ中提供支持服务(商户也可以通过服务电话021-38929999-2049,来提供自己的商户号和联系QQ)

代收、订购、无跳转支付产品暂不支持自助测试,请见谅。

人工服务时间:工作日9:00-11:30,13:00-17:00

手机APP支付--整合银联支付控件的更多相关文章

  1. 银联手机支付控件官方使用指南(ios版)

    目录 版本信息... 2 目录      3 1       概述... 1 2       支付流程介绍... 1 3       测试帐号... 2 4       iOS客户端... 3 4.1 ...

  2. 一个类似抖音 APP 拍摄按钮效果的控件

    TouchButton 一个类似抖音 APP 拍摄按钮效果的控件 效果图预览 用法 <net.angrycode.library.TouchButton android:id="@+i ...

  3. 手机APP支付--整合支付宝支付控件

    长话短说,本文根据支付宝官方说明文档,简单总结下,并且说明下开发过程碰到的问题以及该如何解决. 整合步骤: 1 登录商家服务网站,下载开发包,地址:https://b.alipay.com/order ...

  4. iOS----支付(微信支付、支付宝支付、银联支付控件集成支付)(转)

    资料 支付宝 //文档idk都包含了安卓.iOS版 银 联 银联官网资料 Demo Demo给了一个订单号,做测试使用,若出现支付失败什么的,可能是已经被别人给支付了,或者是服务器订单过期了 ~ 一. ...

  5. iOS开发 支付之银联支付集成

    iOS开发之银联支付集成 最近在做支付这一块的东西,就记录下来以便以后参考和各位交流学习,这里是银联支付 银联官网在这里,这里能下载SDK或者是看文档.文档嘛,对银联来说,还是不要看的太仔细的好,以前 ...

  6. iOS第三方支付-银联支付

    #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "UPPayPluginDeleg ...

  7. Windows App开发之经常使用控件与应用栏

    控件的属性.事件与样式资源 怎样加入控件 加入控件的方式有多种,大家更喜欢以下哪一种呢? 1)使用诸如Blend for Visual Studio或Microsoft Visual Studio X ...

  8. angularjs 整合bootstrap 时间控件

    一.引入js <link href="${basePath}/static/plugin/bootstrap/css/bootstrap-datetimepicker.min.css& ...

  9. APP端有原生态的控件,但嵌入了H5页面,怎么定位到H5页面的元素

    appium 通常有很多种定位元素方法,例如xpath,driver.find_element_by_accessibility_id等,安卓sdk自带的uiautomatorviewer但是对于H5 ...

随机推荐

  1. [sed] linux sed 批量替换字符串

    比如,要将目录/modules下面所有文件中的zhangsan都修改成lisi,这样做: sed -i "s/zhangsan/lisi/g" `grep zhangsan -rl ...

  2. IIS 7上部署PHP

    前言 前段时间整了一个挂Q的平台.源代码是从网上下载的,后期稍微调整了一下链接和title之类的文字就上线了.详细在这里. 运行了一段时间,除了偶尔出现QQ下线上线,整体效果基本上符合预期,个人感觉很 ...

  3. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

    启动两个client,过了一会,停了其中一个,访问注册中心时,界面上显示了红色粗体警告信息: 查阅了很多资料,终于了解了中间的问题.现将理解整理如下: Eureka server和client之间每隔 ...

  4. beansbinding NetBeans IDE 中 Swing数据绑定插件

    http://my.oschina.net/u/127459/blog/111486 https://kenai.com/projects/betterbeansbinding/pages/Home ...

  5. etl的表输入时精度问题

    SELECT RecipeID, IngredientID as ingre_id, ROUND(Quantity, 5) Quantity, Preparation, RecipeIngredien ...

  6. webpack2--webpack 4.X 快速创建demo

    准备工作 1.新建文件夹:webpack-demo(下面我们简称该文件夹为根目录),在根目录下面建两个文件夹,分别为src和dist. 1).src文件夹:用来存放我们编写的javascript代码, ...

  7. 关于Unity3D中鼠标移动指定物体的解决方案

    一.鼠标拾取物体的原理 在Unity3D当中,想要在观察面(Aspect)中拾取物体(有碰撞属性)的方法一般如下: 1.声明一个观察的摄像机.一个从摄像机原点出发的射线Ray以及一个用于检测碰撞的Ra ...

  8. wifi 通过omnipeek 查看 pmf是否生效

    给android的wifi设备添加PMF支持时,抓取omnipeek分析. 从assoc req 中发现相关标志位没有使能,说明STA 没有使能PMF RSN Capabilities: %00000 ...

  9. vi 打开文件,行末尾有^M

    原因: Windows下的文本文件的每一行结尾,都有一个回车符('\n')和一个换行符('\r') Linux下的文本文件的每一行结尾,只有一个回车符('\n') Mac下的文本文件的每一行结尾,只有 ...

  10. rqalpha-自动量化交易系统(一)

    因为最近做的东西牵涉到自动计算这一块,在网上搜了一下,基本上python做自动量化交易成了一个趋势,于是花了两天学习一下. 目标很简单,学习,使用. rqalpha看起来是比较成熟的,这儿看重的是自带 ...