银联与财付通、支付宝一样都是提供给第三方APP的支付集成提供了嵌入式的集成渠道接口,因此总体来说我们依然可以借助银联的接入规则文档和银联的集成接口完成我们对银联支付渠道接口的集成,但是集成接入包依然需要修改。
银联支付渠道接口分两个模块,第一个为Unionpay负责启动与返回结果,第二个部分UnionpayAction,为银联支付渠道接口的整体设计,以集成接入包为蓝本整体设计分为三部分,即接入部分、支付部分与返回部分。
1、Unionpay模块
本文并不涉及支付服务器,因此本接口设计只讨论设计流程图中如何发送关键参数以及接收与处理同步返回的结果。银联支付渠道接口的整体设计模块主要功能函数,payRequest()和JPayManager.getJPayManager()。
·payRequest()
//将商户信息传递给UnionpayAction.payRequest,启动UnionpayAction。
UnionpayAction payRequest = new UnionpayAction(this cpInfo);
payAction.payRequest();
·JPayManager getJPayManager()
//返回最终支付结果。
Return mManager.
2、UnionpayAction模块
UnionpayAction模块是使用银联提供的集成接入模块,在借助其帮助的同时,我们需要对它进行一定的修改;
使其能够匹配我们第三方集成支付平台的需要,因为与财付通/微信支付流程类似,在接支付结果入部分我们同样增加payRequest(),requestPrePayInfo()和PayCallBack()向集成平台服务器请求、获取调用银联支付需要的Union sign信息的功能;
在返回部分也需要增加将支付结果通知集成平台的功能,对PayReturnResultActivity()进行了少许修改。
1.接入部分
接入部分需要获取调用银联接口时根据业务规则需要传递Union sign的请求参数,如表1银联支付请求接口参数列表所示,调用接口开始支付。
表1 银联支付请求接口参数列表
payRequest()开始请求前往银联进行支付,首先要获取支付前必要的参数信息。
//获取支付前必要的参数信息。
requestPrePayInfo().
requestPrePayInfo()实现的是获取前往银联支付平台支付前,向集成平台服务器获取必要的财付通请求参数。表2为财付通前期支付请求参数表。
表2 银联前期支付准备请求参数表
//将发送给集成平台支付服务器的请求参数组装,并使用MD5完成签名
long time = System.currentTimeMillis();
String sign = "" + JPayManager.TENPAY + JPayManager.FLAG + time;
sign = SignUtil.getMDS(sign);
//将请求参数发送给集成平台支付服务器
JPayment payReq = new JPaymentImpl(mContext);
payReq.keyInfoRequest(JPayManager.UNION,JPayManager.FLAG,String.value0f(time),CPInfo.getOrderId(),sign,mCallPayCallBack).
PayCallBack()从集成平台支付服务器获取返回的请求Union sign的关键参数,从支付服务器获得的数据返回的格式为Json,表3为银联前期支付请求返回参数表。
表3 银联前期支付请求返回参数表
主要功能代码如下:
//检查签名
Checksign();
//将返回的Json格式的结果进行解析,获取MerchantId,key,PayRequest_Url
JSONObject jo;
jo = new JSONObject (response);
String message = jo.getString ("secret");
o = new JSONObject (message);
mMerchantId = jo.getString ("MerchantId");
mKey = jo.getString ("key");
mPayRequestUrl = jo.getString ("PayRequest Url");
//判断返回的是不是有空值
Cheek message();
//开始进入请求Union sign的步骤
requestUnionSign (mCPInfo).
reQuestUnionSign()将支付订单信息完整获取并组装后,使用MD5进行签名发送,向银联支付平台请求Union sign,请求发送的参数如表4请求Union sign参数orderInfo列表所示。
表4 请求Union sign参数orderInfo列表
核心代码如下:
//按照文档标准获取支付参数
String orderInfo = orderInfo + sign + time;
//向银联支付平台请求获取Union sign
unionSignRequest (orderInfo).
unionSignRequest()从集成支付平台获取到Union sign。
2.支付部分
UNION_SIGN_REPONSE()将Union sign以请求参数的形式发送,调用银联支付接口开始支付。按照银联接口的规则我们选xml,以Bundle数据块进行参数传递。核心代码如下:
//将Union sign传递给银联支付接口,调用该接口开始支付
String sign = jo.getString(UNION_SIGN);
String Time = jo.getString(MERCHANT_ORDER_TIME);
//将数据以xml格式传递
String xm1 = buildXmlStr(sign,orderTime);
Bundle xmlData = new Bundle();
//调用支付界面
xmlData.putString("ActivityName","com.joygor.jpay.unionpay.PayReturnResultActivity");
xmlData.putString ("xml", xml);
//放入数据里
intent.putExtras(xmlData);
//进行支付
mContext.startActivity().
3.返回部分
返回部分分为异步通知和同步返回两部分,异步返回通过直接与集成支付平台的支付服务器进行互动,但是由于本文不涉及集成平台支付服务器的设计,因
此异步返回通知不在本文返回部分的设计范围内。
异步返回部分返回结果前,银联以同步的方式直接将结果返回给银联支付渠道接口,其返回的结果只有支付结果的最终状态,我们将对结果进行解析,并将最终的结果通知给银联支付管理功能函数(返回的数据格式依然是xml)。因此我们是以这一部分进行研究和讨论。表5为银联平台支付结果返回列表。
表5 为银联平台支付结果返回列表
PayReturnResultActivity()的功能是取出最终的支付结果,对签名进行验证,如正确进行与服务器二次确认,通知银联支付渠道的Unionpay模块,返回最终结果。
//取出最终的支付结果
Bundle xmlData = getIntent().getExtras();
String response = xmlData.getString("xml");
//检查签名的正确,获取RESP_CODE
ResultChecker resultChecker = new ResultChecker(strRet,mkey);
checksign();
String respCode = result.get(UnionPayArgument.RESP_CODE);
//与支付集成平台的支付服务器进行确认
CheckOrder.recheckOrderWithServer(mCPInfo,RESP_CODE);
//通知银联支付渠道的Unionpay模块,返回最终结果。
Unionpay.getJPayManager().PayCallBack(RESP_CODE,PayManager.Union).