访问连接下载银联SDK
https://open.unionpay.com/tjweb/acproduct/list?apiSvcId=448&index=5
1.拿到测试证书(下载银联的SDKjava包里边就有证书)

2. springboot项目依赖加

3.下载的SDK里拿到 acp_sdk.properties文件
说明: # 使用时请将此文件复制到src文件夹下替换原来的acp_sdk.properties。
#具体配置项请根据注释修改。
#入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址
##交易请求地址
acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do
acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do
acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do
acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do
acpsdk.fileTransUrl=https://filedownload.test.95516.com/
acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do
acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do

#以下缴费产品使用,其余产品用不到
acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do
acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do
acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do
acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do
acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do

########################################################################

#报文版本号,固定5.1.0,请勿改动
acpsdk.version=5.1.0

# 签名方式,证书方式固定01,请勿改动
acpsdk.signMethod=01

#是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
acpsdk.ifValidateCNName=false

# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
acpsdk.ifValidateRemoteCert=false

#后台通知地址,填写接收银联后台通知的地址,必须外网能访问
acpsdk.backUrl=http://277k12a704.qicp.vip:11947/ylpay/callback-asyn

#前台通知地址,填写银联前台通知的地址,必须外网能访问
acpsdk.frontUrl=http://277k12a704.qicp.vip:11947/ylpay/callback-front

######入网测试环境签名证书配置 ########### 多证书的情况证书路径为代码指定,可不对此块做配置。

#签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。

#windows样例:
acpsdk.signCert.path=D:/certs/acp_test_sign.pfx

#linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
#acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp700000000000001.pfx

#签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
acpsdk.signCert.pwd=000000

#签名证书类型,固定不需要修改
acpsdk.signCert.type=PKCS12

######加密证书配置########################
#敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer

####验签证书配置################################
#验签中级证书路径(银联提供)
acpsdk.middleCert.path=D:/certs/acp_test_middle.cer

#验签根证书路径(银联提供)
acpsdk.rootCert.path=D:/certs/acp_test_root.cer

(配置文件中注意:1.将证书路径改为磁盘绝对路径,2.同步回调和异步回掉地址改为自己的服务地址,但是必须内网穿透,可以免费注册个花生壳使用)
4.从SDK中拿到java文件

5.上代码
在启动类中初始化加载银联的配置文件

@SpringBootApplication
@Slf4j
public class SpringbootApplication
{public static void main(String[] args){SDKConfig.getConfig().loadPropertiesFromSrc();log.warn("执行加载银联证书和配置信息");SpringApplication.run(SpringbootApplication.class, args);}
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Slf4j
@RestController
@RequestMapping("/ylpay")
public class YLPayController
{
@Autowired
private YLPayService ylPayService;

/*** 银联支付* @param request* @param response* @throws IOException*/
@RequestMapping("/pay")
public void pay(HttpServletRequest request, HttpServletResponse response) throws IOException
{response.setContentType("text/html;chartset=utf-8");String pay = ylPayService.pay(yinLianPayEntity,request, response);PrintWriter out = response.getWriter();out.println(pay);out.close();
}/*** 同步回调* @param request* @param response* @return* @throws IOException* @throws ServletException*/
@RequestMapping("/callback-front")
public String frontCallback(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{return ylPayService.frontCallback(request,response);}/*** 异步回调* @param request* @param response* @return*/
@RequestMapping("/callback-asyn")
public String asynCallback(HttpServletRequest request, HttpServletResponse response)
{return  ylPayService.asynCallback(request, response);}

}

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class YLPayServiceImpl implements YLPayService
{

@Override
public String pay(PayDto yinLianPayEntity, HttpServletRequest req, HttpServletResponse resp)
{resp.setContentType("text/html; charset=" + DemoBase.encoding);Map<String, String> requestData = new HashMap<String, String>();/***银联全渠道系统,产品参数,除了encoding自行选择外其他不需修改***/requestData.put("version", DemoBase.version);              //版本号,全渠道默认值requestData.put("encoding", DemoBase.encoding);              //字符集编码,可以使用UTF-8,GBK两种方式requestData.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法requestData.put("txnType", "01");                          //交易类型 ,01:消费requestData.put("txnSubType", "01");                          //交易子类型, 01:自助消费requestData.put("bizType", "000201");                      //业务类型,B2C网关支付,手机wap支付requestData.put("channelType", "07");                      //渠道类型,这个字段区分B2C网关支付和手机wap支付;07:PC,平板  08:手机/***商户接入参数***/requestData.put("merId", "777493289999");                              //商户号码,请改成自己申请的正式商户号或者open上注册得来的777测试商户号requestData.put("accessType", "0");                          //接入类型,0:直连商户requestData.put("orderId", "2019783219");             //商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则requestData.put("txnTime", DemoBase.getCurrentTime());        //订单发送时间,取系统时间,格式为yyyyMMddHHmmss,必须取当前时间,否则会报txnTime无效requestData.put("currencyCode", "156");         //交易币种(境内商户一般是156 人民币)requestData.put("txnAmt", 8);                              //交易金额,单位分,不要带小数点//requestData.put("reqReserved", "透传字段");                     //请求方保留域,如需使用请启用即可;透传字段(可以实现商户自定义参数的追踪)本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回,商户可以按需上传,长度为1-1024个字节。出现&={}[]符号时可能导致查询接口应答报文解析失败,建议尽量只传字母数字并使用|分割,或者可以最外层做一次base64编码(base64编码之后出现的等号不会导致解析失败可以不用管)。requestData.put("riskRateInfo", "{commodityName= 服务费}");//前台通知地址 (需设置为外网能访问 http https均可),支付成功后的页面 点击“返回商户”按钮的时候将异步通知报文post到该地址//如果想要实现过几秒中自动跳转回商户页面权限,需联系银联业务申请开通自动返回商户权限//异步通知参数详见open.unionpay.com帮助中心 下载  产品接口规范  网关支付产品接口规范 消费交易 商户通知requestData.put("frontUrl", DemoBase.frontUrl);//后台通知地址(需设置为【外网】能访问 http https均可),支付成功后银联会自动将异步通知报文post到商户上送的该地址,失败的交易银联不会发送后台通知//后台通知参数详见open.unionpay.com帮助中心 下载  产品接口规范  网关支付产品接口规范 消费交易 商户通知//注意:1.需设置为外网能访问,否则收不到通知    2.http https均可  3.收单后台通知后需要10秒内返回http200或302状态码//    4.如果银联通知服务器发送通知后10秒内未收到返回状态码或者应答码非http200,那么银联会间隔一段时间再次发送。总共发送5次,每次的间隔时间为0,1,2,4分钟。//    5.后台通知地址如果上送了带有?的参数,例如:http://abc/web?a=b&c=d 在后台通知处理程序验证签名之前需要编写逻辑将这些字段去掉再验签,否则将会验签失败requestData.put("backUrl", DemoBase.backUrl);// 订单超时时间。// 超过此时间后,除网银交易外,其他交易银联系统会拒绝受理,提示超时。 跳转银行网银交易如果超时后交易成功,会自动退款,大约5个工作日金额返还到持卡人账户。// 此时间建议取支付时的北京时间加15分钟。// 超过超时时间调查询接口应答origRespCode不是A6或者00的就可以判断为失败。requestData.put("payTimeout", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date().getTime() + 15 * 60 * 1000));/**请求参数设置完毕,以下对请求参数进行签名并生成html表单,将表单写入浏览器跳转打开银联页面**/Map<String, String> submitFromData = AcpService.sign(requestData, DemoBase.encoding);  //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl();  //获取请求银联的前台地址:对应属性文件acp_sdk.properties文件中的acpsdk.frontTransUrlString html = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData, DemoBase.encoding);   //生成自动跳转的Html表单log.info("打印请求HTML,此为请求报文,为联调排查问题的依据:" + html);//将生成的html写到浏览器中完成自动跳转打开银联支付页面;这里调用signData之后,将html写到浏览器跳转到银联页面之前均不能对html中的表单项的名称和值进行修改,如果修改会导致验签不通过return html;// resp.getWriter().write(html);
}@Override
public String asynCallback(HttpServletRequest req, HttpServletResponse response)
{log.info("后台通知================BackRcvResponse接收后台通知开始=================");String encoding = req.getParameter(SDKConstants.param_encoding);// 获取银联通知服务器发送的后台通知参数Map<String, String> reqParam = getAllRequestParam(req);System.err.println("支付成功返回的参数========" + reqParam);LogUtil.printRequestLog(reqParam);//重要!验证签名前不要修改reqParam中的键值对的内容,否则会验签不过if (!AcpService.validate(reqParam, encoding)){log.error("验证签名结果[失败].");//验签失败,需解决验签问题}else{log.info("验证签名结果[成功].");//【注:为了安全验签成功才应该写商户的成功处理逻辑】交易成功,更新商户订单状态String orderId = reqParam.get("orderId"); //获取后台通知的数据,其他字段也可用类似方式获取String respCode = reqParam.get("respCode");String queryId = reqParam.get("queryId");  //交易流水号//判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。System.err.println("异步请求通知orderId=" + orderId);System.err.println("异步请求通知queryId=" + queryId);//拿到orderId就证明支付成功了,可以对数据库的订单修改了}log.warn("后台通知==================BackRcvResponse接收后台通知结束================");//返回给银联服务器http 200  状态码return "ok";
}@Override
public R frontCallback(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
{log.info("前台通知===================FrontRcvResponse前台接收报文返回开始======================");String encoding = req.getParameter(SDKConstants.param_encoding);log.info("返回报文中encoding=[" + encoding + "]");Map<String, String> respParam = getAllRequestParam(req);// 打印请求报文LogUtil.printRequestLog(respParam);Map<String, String> valideData = null;StringBuffer page = new StringBuffer();if (null != respParam && !respParam.isEmpty()){Iterator<Map.Entry<String, String>> it = respParam.entrySet().iterator();valideData = new HashMap<String, String>(respParam.size());while (it.hasNext()){Map.Entry<String, String> e = it.next();String key = (String) e.getKey();String value = (String) e.getValue();value = new String(value.getBytes(encoding), encoding);page.append("<tr><td width=\"30%\" align=\"right\">" + key + "(" + key + ")</td><td>" + value + "</td></tr>");valideData.put(key, value);}}if (!AcpService.validate(valideData, encoding)){page.append("<tr><td width=\"30%\" align=\"right\">验证签名结果</td><td>失败</td></tr>");log.error("验证签名结果[失败].");}else{page.append("<tr><td width=\"30%\" align=\"right\">验证签名结果</td><td>成功</td></tr>");log.info("验证签名结果[成功].");System.out.println(valideData.get("orderId")); //其他字段也可用类似方式获取String respCode = valideData.get("respCode");//判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。}req.setAttribute("result", page.toString());log.info("前台通知================FrontRcvResponse前台接收报文返回结束=================")return    "支付成功";
}public 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))){// System.out.println("======为空的字段名===="+en);res.remove(en);}}}return res;
}

}

java对接银联在线网关支付(已测试)相关推荐

  1. PHP接入银联在线网关支付

    网站支付:一般接入微信支付.支付宝支付.银联支付,本文介绍的是如何接入中国银联在线网关支付 银联介绍 银联在线支付网关是中国银联联合各商业银行为持卡人提供的集成化.综合性互联网支付工具,主要支持输入卡 ...

  2. 银联在线网关支付,快速接入指南

    银联在线支付网关是中国银联联合各商业银行为持卡人提供的集成化.综合性互联网支付工具,主要支持输入卡号付款.用户登录支付.网银支付.迷你付(IC卡支付)等多种支付方式,为持卡人提供境内外网上购物支付服务 ...

  3. 银联批量结算 java_银联在线 网关支付 (JAVA版)

    这一版本的编写是在我上一次博客的基础上写的,有不懂得童鞋可以先看下我的原先在线支付的博客,熟悉下:http://blog.csdn.net/yulei_qq/article/details/45197 ...

  4. 银联在线支付 java_银联在线 网关支付 (JAVA版)

    这一版本的编写是在我上一次博客的基础上写的,有不懂得童鞋可以先看下我的原先在线支付的博客,熟悉下:http://blog.csdn.net/yulei_qq/article/details/45197 ...

  5. 银联在线 网关支付(中国银联全渠道系统商户接入 测试指引-银联网关支付产品)

    https://blog.csdn.net/yulei_qq/article/details/49025045 中国银联全渠道系统商户接入 测试指引-银联网关支付产品 https://blog.csd ...

  6. 银联支付(一)申请测试环境,并运行测试demo(在线网关支付)

    1.注册账号 点击进入银联支付开放平台地址 注册账号 选择普通用户登录账号 登录后点击前往商户测试中心 进入后产品列表中选择在线网关支付,然后要点击操作中的集成测试申请支付权限,10分钟后生效(这里如 ...

  7. java对接银联商务公众号+服务窗支付(5)

    java实现银联商务公众号+服务窗对接----订单撤销 本文对接银联商务公众号+服务窗支付,实现支付下单.订单查询.订单退款.退款查询和订单关闭几个功能,使用到银联商务的公众+服务窗支付接口规范,请自 ...

  8. Java对接银联支付

    一.下载银联sdk: 二.将所需的jar包导入项目中: 三.将示例代码拷贝到项目中来: 四.修改SDKConfig.java中加载公钥和私钥的位置,用动态加载的方式: path.substring(0 ...

  9. java对接银联商务公众号+服务窗支付(4)

    java实现银联商务公众号+服务窗对接----退款查询 本文对接银联商务公众号+服务窗支付,实现支付下单.订单查询.订单退款.退款查询和订单关闭几个功能,使用到银联商务的公众+服务窗支付接口规范,请自 ...

最新文章

  1. jdbc mysql查询显示图片_在实现JDBC时如何显示存储引擎-MySQL CONNECTION查询?
  2. Android启动屏全屏显示
  3. JavaScript中匿名函数的作用和用法
  4. NODE_PATH的疑难杂症(转)
  5. 【NLP】GPT-3问世这一年,给世界带来的困扰与希望
  6. 90后码农可以拯救互联网吗?
  7. python集合类型的操作符_Python 语言学习 第一篇:数据类型(数字,集合,布尔类型,操作符)...
  8. ios macos_设计师可以从iOS 14和macOS Big Sur中学到什么?
  9. NPOI 将DataGridView导出到Excel
  10. mysql galera haproxy_安装配置Haproxy代理MySQL Galera集群
  11. python图形化编程工具哪个好_mPython(图形化编程软件) V0.5.0 官方版
  12. 均值滤波计算_从零学美颜算法保边滤波
  13. java 数字的进制转换
  14. 没有找到 AUTOBACKUP
  15. Node.js:中间件——配置静态资源中间件
  16. Android音频术语
  17. matlab 取虚数单位,四元数解算姿态Matlab程序代码
  18. .net mysql 博客_asp.net搭建博客,使用BlogEngine.NET+MySql搭建博客
  19. 目标检测算法之CVPR 2019 Guided Anchoring
  20. 工作十年,我是如何达到年薪40W以上

热门文章

  1. C#将数据库连接方式写到配置文件中
  2. 暴雪的hash算法[翻译]
  3. 钉钉OA审批可以设计项目施工管理和工程项目管理吗?
  4. 【Java】驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接
  5. Java开发手册学习与详解-实习第1,2天
  6. 润乾报表----模板报表制作
  7. mysql三大特性_数据库四大特性
  8. pyqt 控件焦点_PyQt5(2)——调整布局(布局管理器)第一个程序
  9. 内部泄露版!互联网大厂的最新薪资和职级一览
  10. 积木创意:互联网巨头们如何下新零售这盘棋