1. 准备工作

首先在银联开放平台注册一个测试账号,地址https://open.unionpay.com/ajweb/index

注册完成后可以根据自己所用的编程语言选择对应的demo下载,我下载了java通用版。

2.创建springmvc项目,将demo中的sdk包copy进项目,编写controller。

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import com.ccdproject.bean.UnionpayBean;
import com.ccdproject.unionpay.DemoBase;
import com.ccdproject.util.DateUtil;
import com.ccdproject.util.ZxingQrcode;
import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.LogUtil;
import com.unionpay.acp.sdk.SDKConfig;
import com.unionpay.acp.sdk.SDKConstants;/*** 银联扫码支付* 1.获取二维码值* 主扫申请二维码交易* @author Austin**/
@Controller
@RequestMapping("/unionpay")
public class Unionpay extends HttpServlet {/*** 序列化*/private static final long serialVersionUID = 1L;@RequestMapping("/unionpayqrcode")protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {SDKConfig.getConfig().loadPropertiesFromSrc();// 从classpath加载acp_sdk.properties文件String merId = UnionpayBean.merId;String txnAmt = req.getParameter("txnAmt");// 生成商户订单号  orderIdString  orderId = DateUtil.OrderId();orderId += String.valueOf(4);String txnTime = DateUtil.ordertxnTime(); //订单时间Map<String, String> contentData = new HashMap<String, String>();/***银联全渠道系统,产品参数,除了encoding自行选择外其他不需修改***/contentData.put("version", DemoBase.version);            //版本号 全渠道默认值contentData.put("encoding", DemoBase.encoding);     //字符集编码 可以使用UTF-8,GBK两种方式contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法  默认01contentData.put("txnType", "01");                         //交易类型 01:消费contentData.put("txnSubType", "07");                    //交易子类 07:申请消费二维码contentData.put("bizType", "000000");                   //填写000000contentData.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("txnAmt", txnAmt);                      //交易金额 单位为分,不能带小数点contentData.put("currencyCode", "156");                 //交易币种 境内商户固定 156 人民币// 请求方保留域,// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
//      contentData.put("reqReserved", "透传信息1|透传信息2|透传信息3");// 2. 内容可能出现&={}[]"'符号时:// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);// 2) 如果对账文件没有显示要求,可做一下base64(如下)。//    注意控制数据长度,实际传输的数据长度不能超过1024位。//    查询、通知等接口解析时使用new String(Base64.decodeBase64(reqReserved), DemoBase.encoding);解base64后再对数据做后续解析。
//      contentData.put("reqReserved", Base64.encodeBase64String("任意格式的信息都可以".toString().getBytes(DemoBase.encoding)));//后台通知地址(需设置为外网能访问 http https均可),支付成功后银联会自动将异步通知报文post到商户上送的该地址,【支付失败的交易银联不会发送后台通知】//后台通知参数详见open.unionpay.com帮助中心 下载  产品接口规范  网关支付产品接口规范 消费交易 商户通知//注意:1.需设置为外网能访问,否则收不到通知    2.http https均可  3.收单后台通知后需要10秒内返回http200或302状态码 //    4.如果银联通知服务器发送通知后10秒内未收到返回状态码或者应答码非http200或302,那么银联会间隔一段时间再次发送。总共发送5次,银联后续间隔1、2、4、5 分钟后会再次通知。//    5.后台通知地址如果上送了带有?的参数,例如:http://abc/web?a=b&c=d 在后台通知处理程序验证签名之前需要编写逻辑将这些字段去掉再验签,否则将会验签失败contentData.put("backUrl", DemoBase.backUrl);System.out.println(SDKConfig.getConfig().getBackUrl()+"=SDKConfig.getConfig().getBackUrl()");/**对请求参数进行签名并发送http post请求,接收同步应答报文**/Map<String, String> reqData = AcpService.sign(contentData,DemoBase.encoding);             //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。String requestAppUrl = SDKConfig.getConfig().getBackRequestUrl();                               //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrlMap<String, String> rspData = AcpService.post(reqData,requestAppUrl,DemoBase.encoding);  //发送请求报文并接受同步应答(默认连接超时时间30秒,读取返回结果超时时间30秒);这里调用signData之后,调用submitUrl之前不能对submitFromData中的键值对做任何修改,如果修改会导致验签不通过System.out.println("rspData="+rspData);/**对应答码的处理,请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**///应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》if(!rspData.isEmpty()){if(AcpService.validate(rspData, DemoBase.encoding)){LogUtil.writeLog("验证签名成功");String respCode = rspData.get("respCode");if(("00").equals(respCode)){//成功,获取tn(银联订单号)String orderId2 = rspData.get("orderId");System.out.println(orderId2);String qrCode = rspData.get("qrCode");System.out.println(qrCode);ZxingQrcode.zxingqrcode(qrCode, resp);}else{//其他应答码为失败请排查原因或做失败处理//TODO}}else{LogUtil.writeErrorLog("验证签名失败");System.out.println("验证签名失败");//TODO 检查验证签名失败的原因}}else{//未返回正确的http状态LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");System.out.println("未获取到返回报文或返回http状态码非200");}String reqMessage = DemoBase.genHtmlResult(reqData);String rspMessage = DemoBase.genHtmlResult(rspData);resp.getWriter().write("请求报文:<br/>"+reqMessage+"<br/>" + "应答报文:</br>"+rspMessage+"");}/**** unionpay 异步通知支付结果* @param req* @param resp* @throws IOException*/@RequestMapping("/Notify")public void Notifyunionpay(HttpServletRequest req,HttpServletResponse resp) throws IOException{// 获取银联post过来的信息System.out.println("BackRcvResponse接收后台通知开始");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();valideData.put(key, value);}}//重要!验证签名前不要修改reqParam中的键值对的内容,否则会验签不过if (!AcpService.validate(valideData, encoding)) {LogUtil.writeLog("验证签名结果[失败].");System.out.println("验证签名结果[失败].");//验签失败,需解决验签问题} else {LogUtil.writeLog("验证签名结果[成功].");System.out.println("验证签名结果[成功].");//【注:为了安全验签成功才应该写商户的成功处理逻辑】交易成功,更新商户订单状态String orderId =valideData.get("orderId"); //获取后台通知的数据,其他字段也可用类似方式获取String respCode = valideData.get("respCode");//判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。}LogUtil.writeLog("BackRcvResponse接收后台通知结束");//返回给银联服务器http 200  状态码resp.getWriter().print("ok");}/*** 获取请求参数中所有的信息* * @param request* @return*/public static 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);//在报文上送时,如果字段的值为空,则不上送<下面的处理为在获取所有参数数据时,判断若值为空,则删除这个字段>//System.out.println("ServletUtil类247行  temp数据的键=="+en+"     值==="+value);if (null == res.get(en) || "".equals(res.get(en))) {res.remove(en);}}}return res;}}
访问  /unionpay/unionpayqrcode?txnAmt=100出现 二维码  由于是测试账号,无法使用手机扫码支付,然后可以自己在学一个支付程序
3.其中txmtime,orderid的生成自己设定,其中一些参数也在官方Demo上也有,具体可以参考官网。

银联二维码支付java 实现相关推荐

  1. 银联二维码支付与微信支付相比,哪个好用?

    2019独角兽企业重金招聘Python工程师标准>>> 近日,中国银联联合40多家商业银行正式推出了二维码支付产品.扫码支付你应该早就不陌生了.现在即使是摆在街边的水果摊也有二维码让 ...

  2. 微信支付--商户二维码支付(JAVA)

    先创建Springboot项目 已上传至github库 https://github.com/gaoruiqiang2017/weixinpay.git pom文件添加依赖 <!--微信支付SD ...

  3. PHP开发银联云闪付二维码支付

    你好,是我琉忆.最近刚好有在研究银联云闪付的支付模块,所以就写篇总结分享给大家. 这算是第二次接触支付的东西了,接触得最多的是接入微信支付,自己也有相关的总结文章,可以去segmentfault搜索& ...

  4. 银联押宝二维码支付 背后还有一片纷争江湖

    昨天银联二维码支付标准正式发布了.这被市场看做,此前存在安全隐患.饱受争议的二维码支付终于合规化了.各位以后去商家扫码,会有不同选择了:支付宝的.微信的.还有银联的.不过我估计各位还是哪个方便.哪个优 ...

  5. Java 支付对接之银联电子商务(海南)聚合二维码支付(POS 通插件 C 扫 B 业务)

    写在前面: 二维码支付宝有两种表现形式:第一种是动态的二维码,就是每生成一个订单就会生成一个二维码:第二种是固定的二维码,就是每个订单都是同一个二维码作为入口.本文主要描述的是如何使用银联的线下C扫B ...

  6. 银联云闪付二维码支付对接流程和测试

    因为公司已经支持了支付宝支付和微信支付,所以需要加上一个银联的云闪付,主要是二维码支付. 银联商务的官方文档其实已经很清楚了,但是因为之前对接支付宝和微信,有一个保存商户信息的表,表结构已经确定了,再 ...

  7. JAVA实现的微信扫描二维码支付

    支付项目采用springMvc+Dubbo架构实现,只对外提供接口. 话说,为什么微信支付比支付宝来的晚了那么一点,一句话,那一阵挺忙的,然后就没有时间整理,最近做完支付宝支付,顺便也把微信支付的也整 ...

  8. Java支付宝二维码支付和退款,微信二维码支付

    在蚂蚁金服开发平台下载demo 打开 TradePayDemo 项目,里面的main可以直接运行,在配置文件zfbinfo.properties中改为自己支付宝的信息 # 支付宝网关名.partner ...

  9. java实现微信支付宝等多个支付平台合一的二维码支付(SSM框架)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] ♪ 点击上方绿标 收听java实现微信支付宝等多个支付平台合一的二维码支付(SSM框架) 整体思路: 实现微信支付宝等支付平台合多为一的二 ...

  10. java实现微信支付宝等多个支付平台合一的二维码支付(maven+spring springmvc mybatis框架)

    首先申明,本人实现微信支付宝等支付平台合多为一的二维码支付,并且实现有效时间内支付有效,本人采用的框架是spring springmvc mybatis 框架,maven管理.其实如果支付,不需要my ...

最新文章

  1. 多项NLP任务新SOTA,Facebook提出预训练模型BART​
  2. spring中事件发布设计与实现
  3. ruby 工程的创建 使用JetBrains RubyMine建立rails 工程
  4. OpenCV尺寸调整函数resize
  5. 字符串分割 函数实现
  6. python创建access表_Access创建表
  7. 计算机文化基础第二章,计算机文化基础(第二章Windows2000操作系统)
  8. AE一键快速生成MG爆炸图形动画插件:Burst Box for Mac
  9. java 定义方法_java如何定义方法
  10. python人工智能能干啥_人工智能首选什么语言 Python能做哪些事情
  11. 惠斯通电桥信号调理芯片_基于精密分流电阻器的惠斯通电桥校准
  12. 求整数n次方以及矩阵n次方快速解法
  13. P2668 斗地主 贪心+深搜
  14. SSM面试题及相关答案
  15. ObjectiveC基础教程(第2版)
  16. 前端导航栏的几种写法
  17. redis数据类型命令
  18. 通俗的解释云计算 公有云 私有云 混合云
  19. 如何用云计算搭建服务器,如何搭建一个云服务器
  20. 咋样回复计算机桌面删除的东西,电脑桌面上的便签怎么删除及桌面便签删除后还能恢复吗...

热门文章

  1. dtcms配置多参数
  2. 2020电工(初级)证考试及电工(初级)考试软件
  3. 隐马尔可夫python_隐马尔可夫模型原理和python实现
  4. 手机播放云服务器中的视频文件在哪里,手机播放云服务器中的视频文件
  5. 湖北省湖泊河流ArcGIS地形图shp图层文件下载
  6. sublime 快捷键
  7. Freeradius安装和配置
  8. Segger systemview STM32移植
  9. 【kali技巧】kali更新系统
  10. springboot版的微信公众号,订阅号