java(服务端)-集成银联支付,含代码
2017-12-06 15:23
609 查看
百度银联支付,基本在喷银联代码烂,要不就是拿官方的代码贴上来,都没有仔细的说集成过程,用处实在不大
这里记录我集成过程,希望能帮到大家
这一步如果不想看,直接跳过,但是demo依然要下载,我们要用里面的代码
demo下载地址:
导入eclipse,将
修改
启动,发布到tomcat,浏览器运行
前端拿tn支付
前端支付完成后,银联会调你设置的url,并给你相应的参数
后台根据银联给的参数,验证签名,根据相应的业务逻辑判断加金币
Config,UnionpayController,UnionpayService都是我自己写的,Config乃com.unionpay.acp.demo下的DemoBase
代码如下,要修改的地方写了TODO
此处有坑:银联调你的接口,1. 必须是外网,2. 如果你返回的状态码是200,它就不继续调,如果不是200,他就会继续调你的接口,这也是我有的地方抛异常,有的地方直接返回的理由
这里记录我集成过程,希望能帮到大家
官方demo
都说银联代码没有规范,文档也烂。但是人家挺用心的,提供了demo,稍微修改就可以直接运行。这一步如果不想看,直接跳过,但是demo依然要下载,我们要用里面的代码
demo下载地址:
https://open.unionpay.com/ajweb/index,帮助中心>下载>网关支付>网关支付铲平技术开发包
导入eclipse,将
src/assets/测试环境证书里面的证书拷贝到
E:/certs下,(最新版是有4个文件,不管那个版本,里面文件都拷贝,等会修改就行了)
修改
acp_sdk.properties,将下面的修改成刚刚拷贝的文件地址
acpsdk.signCert.path=E:/certs/acp_test_sign.pfx acpsdk.encryptCert.path=E:/certs/acp_test_enc.cer acpsdk.middleCert.path=E:/certs/acp_test_middle.cer acpsdk.rootCert.path=E:/certs/acp_test_root.cer
启动,发布到tomcat,浏览器运行
localhost:8080/ACPSample_B2C发起请求,多试试,熟悉逻辑
开始集成
支付流程
前端请求自己服务器,自己服务器请求银联,设置后台通知的url,获取到tn号前端拿tn支付
前端支付完成后,银联会调你设置的url,并给你相应的参数
后台根据银联给的参数,验证签名,根据相应的业务逻辑判断加金币
将demo中sdk包拷贝到自己项目中
Config,UnionpayController,UnionpayService都是我自己写的,Config乃com.unionpay.acp.demo下的DemoBase
获取tn
自己前端将用户id,商品id传过来代码如下,要修改的地方写了TODO
` public Result getOrder(Integer pid,Integer shopId){ //TODO 根据pid,shopId 做一些自己业务逻辑 Map<String, String> contentData=new HashMap<String, String>(); contentData.put("version", Config.version); //版本号 全渠道默认值 contentData.put("encoding", Config.encoding); //字符集编码 可以使用UTF-8,GBK两种方式 contentData.put("signMethod", "01"); //签名方法 目前只支持01:RSA方式证书加密 contentData.put("txnType", "01"); //交易类型 01:消费 contentData.put("txnSubType", "01"); //交易子类 01:消费 contentData.put("bizType", "000201"); //填写000201 contentData.put("channelType", "08"); //渠道类型 08手机 contentData.put("merId", merId); //商户号码,请改成自己申请的商户号或者open上注册得来的777商户号测试 contentData.put("accessType", "0"); //接入类型,商户接入填0 ,不需修改(0:直连商户, 1: 收单机构 2:平台商户) contentData.put("orderId", orderId); //商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则 contentData.put("txnTime", txnTime); //订单发送时间,取系统时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效 contentData.put("accType", "01"); //账号类型 01:银行卡02:存折03:IC卡帐号类型(卡介质) contentData.put("txnAmt", txnAmt); //交易金额 单位为分,不能带小数点 contentData.put("currencyCode", "156"); //境内商户固定 156 人民币 contentData.put("backUrl", Config.backUrl); //TODO 支付成功后银联会调此接口,必须是外网接口 Map<String, String> reqData = AcpService.sign(contentData,Config.encoding); //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。 String requestAppUrl = SDKConfig.getConfig().getAppRequestUrl(); //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrl Map<String, String> rspData = AcpService.post(reqData,requestAppUrl,Config.encoding); //发送请求报文并接受同步应答(默认连接超时时间30秒,读取返回结果超时时间30秒);这里调用signData之后,调用submitUrl之前不能对submitFromData中的键值对做任何修改,如果修改会导致验签不通过 String tn=null;//流水号 if(!rspData.isEmpty()){ if(AcpService.validate(rspData, Config.encoding)){ LogUtil.writeLog("验证签名成功"); String respCode = rspData.get("respCode") ; if(("00").equals(respCode)){ tn = rspData.get("tn"); } } }else{ //未返回正确的http状态 } if(tn==null) throw new BuzException(-1,"失败,请重试"); return new Result(200,tn); } `
前端拿tn号支付,略
银联回调的接口
此处参照com.unionpay.acp.demo.BackRcvResponse
此处有坑:银联调你的接口,1. 必须是外网,2. 如果你返回的状态码是200,它就不继续调,如果不是200,他就会继续调你的接口,这也是我有的地方抛异常,有的地方直接返回的理由
` @RequestMapping(value="backRcvResponse",method=RequestMethod.POST) public Result backRcvResponse(HttpServletRequest req, HttpServletResponse response) throws IOException { Map<String, String> map = getAllRequestParam(req);//TODO 这里下面提供两个方法,如果一个获取不到值,请换另一个 if (!AcpService.validate(map, map.get(SDKConstants.param_encoding))) { throw new BuzException(-2,"signature verification failure"); } else { String respCode = map.get("respCode"); if(respCode.equals("00")){//付款成功 String ordersn = map.get("orderId");//你在请求tn时设置的orderId String queryId = map.get( 4000 "queryId");//银联给你的唯一标识 //TODO 根据你的业务逻辑,判断 return new Result(200,"success",tokenPackage.getToken_count()); }else{ throw new BuzException(-2,"error-->respCode:"+respCode); } return new Result(); } private Map<String, String> getAllRequestParam( final HttpServletRequest request) { Map<String, String> res = new HashMap<String, String>(); Enumeration<?> temp = request.getParameterNames(); if (null != temp) { while (temp.hasMoreElements()) { String en = (String) temp.nextElement(); String value = request.getParameter(en); res.put(en, value); if (res.get(en) == null || "".equals(res.get(en))) { res.remove(en); } } } return res; } private Map<String, String> getAllRequestParamStream(HttpServletRequest request) { Map<String, String> res = new HashMap<String, String>(); try { String notifyStr = new String(IOUtils.toByteArray(request.getInputStream()), Config.encoding); String[] kvs = notifyStr.split("&"); for (String kv : kvs) { String[] tmp = kv.split("="); if (tmp.length >= 2) { String key = tmp[0]; String value = URLDecoder.decode(tmp[1], Config.encoding); res.put(key, value); } } } catch (UnsupportedEncodingException e) { LogUtil.writeLog("getAllRequestParamStream.UnsupportedEncodingException error: " + e.getClass() + ":" + e.getMessage()); } catch (IOException e) { LogUtil.writeLog("getAllRequestParamStream.IOException error: " + e.getClass() + ":" + e.getMessage()); } return res; } `
由于银联到处都是map传参,要用的时候还要输出看看有哪些参数,这里跟客户要了一个文档,可以参照看看
http://download.csdn.net/download/gege87417376/10147779
相关文章推荐
- Java 银联支付官网demo测试及项目整合代码
- 支付宝APP支付集成,服务端(JAVA)
- java--springboot支付宝新版app支付服务端代码
- java集成paypal支付,含Android,服务端代码
- app支付宝支付java服务端代码
- 微信支付(网站支付,APP支付,扫码支付)并充值钻石 Java服务端代码 xml解析 map排序
- 支付宝APP支付集成,服务端(JAVA)
- IOS IAP APP内支付 Java服务端代码
- java--spring boot微信支付服务端实现含代码(app支付、扫码支付等)
- Java 银联支付官网demo测试及项目整合代码
- 支付宝支付(网站支付,APP支付,扫码支付) Java服务端代码
- java服务端,支付宝支付代码笔记
- 环信服务端java集成代码示例
- Java 银联支付官网demo测试及项目整合代码
- [置顶] 支付宝支付Java代码
- 苹果支付成功后,JAVA服务端二次验证
- Android集成银联支付闪退
- 极光推送JPush java服务端代码
- iOS开发 支付之银联支付集成
- Android支付(支付宝,微信,银联)集成使用