当前位置: 首页 > news >正文

java对接银联商务扫码支付

java实现银联商务扫码支付----微信、支付宝

本文对接银联商务扫码支付,实现支付下单、订单查询、订单退款、退款查询和订单关闭几个功能,使用到银联商务的公众+服务窗支付接口规范,请自行百度下载。
一、接入前准备
创建maven项目,项目目录如下,各目录功能不再详细介绍,直接看接口和功能。
在这里插入图片描述
二、接口及代码实现
1.1接口规范
接口规范请查看下载的银联商务公众号+服务窗接口规范下单接口部分,这里不做展示。
1.2 代码实现
1.2.1 UnionPayScanController代码

@RestController
@CrossOrigin
@RequestMapping("/lay") 
public class UnifiedPayScanController {
 private final static Logger logger = LoggerFactory.getLogger(UnifiedPayScanController.class);
 @Autowired
 private UnifiedOrderServiceimpl unionpayserviceimpl;
 /**
  * 扫码付下单接口
  * @param request
  * @param response
  * @param jsonreq
  * @return
  */
 @RequestMapping(value = "/UnifiedOrder", method = RequestMethod.POST)
 public Map<String, Object> unionpayorder(HttpServletRequest request, HttpServletResponse response,
   @RequestBody String jsonreq) {
  
  Map<String,Object> reqmap = new HashMap<String,Object>(); //客户端原始请求map
  Map<String,Object> datamap = new HashMap<String,Object>(); //客户端原始请求Data数据
  Map<String,Object> resultmap = new HashMap<String,Object>(); //返回结果
  //接收客户端请求数据并转换成map
  reqmap = JsonUtils.JsonToMapObj(jsonreq);
  logger.info("unifiedquery reqmap = " + reqmap);
  
  datamap = (Map<String, Object>) reqmap.get("tradeParam"); //请求体数据
  logger.info("unifiedquery datamap = " + datamap);
  //---------------------step1  验证签名-----------------------------
  String sign = (String) reqmap.get("sign");  //获取sign
  String key = UnionPayConstants.GGMD5KEY;  //国光MD5密钥
try {
   if (!PayUtil.verifySign(datamap,key,sign)) {
    resultmap.put("returnInfo", "签名错误");
    resultmap.put("returnCode", "Bad_Sign");
    
    return resultmap;
   }
  //----------------------step2  验证消息类型  tradeType:UnifiedOrder--------
   if (!"UnifiedOrder".equals(reqmap.get("tradeType"))) {
    resultmap.put("returnCode", "TradeType_Error");
    resultmap.put("returnInfo", "消息类型不符");
    return resultmap;
   }
  //-----------------------step3  验证传参完整性-------------------------- 
   //验证公共参数完整性
   if(!PayUtil.verifyParameter(datamap)) {
    resultmap.put("returnCode", "Common_Value_Error");
    resultmap.put("returnInfo", "缺少必要公共参数");
    return resultmap;
   }
   //验证接口参数完整性
   if(datamap.get("totalAmount").equals("") || datamap.get("msgType").equals("") 
     || datamap.get("notifyUrl").equals("") || datamap.get("returnUrl").equals("") ||datamap.get("merOrderId").equals("") ) {
    resultmap.put("returnCode", "Value_Error");
    resultmap.put("returnInfo", "缺少必要接口参数");
    return resultmap;
   }
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   resultmap.put("returnCode", "System_Error");
   resultmap.put("returnInfo", "系统异常");
   return resultmap;
  }
  //-----------------------step4 传值并调用支付链接生成接口--------------------------------
  Map<String,Object> resultdatamap = new HashMap<String,Object>();
  resultdatamap.put("mid", datamap.get("mid"));         //商户号
  resultdatamap.put("tid", datamap.get("tid"));      //终端号
  resultdatamap.put("instMid", datamap.get("instMid"));    //机构商户号
  resultdatamap.put("msgSrc", datamap.get("msgSrc"));     //消息来源
  
//  //分转元
//  String Amount = PayUtil.changeF2Y(datamap.get("totalAmount").toString());
//  resultdatamap.put("totalAmount", Amount);       //支付总金额
  resultdatamap.put("totalAmount", datamap.get("totalAmount"));   //总金额
  resultdatamap.put("msgType", datamap.get("msgType"));    //支付类型
  resultdatamap.put("notifyUrl", datamap.get("notifyUrl"));   //支付结果通知
  resultdatamap.put("returnUrl", datamap.get("returnUrl"));   //网页跳转地址
  resultdatamap.put("merOrderId", datamap.get("merOrderId"));   //C端上送商户订单号
  Map<String, Object> urlmap = unionpayserviceimpl.CreateUrl(resultdatamap);   //生成支付链接,返回给前端生成二维码
  //-----------------------step5 返回报文,支付链接--------------------------------
  resultmap.put("returnCode", "SUCCESS"); 
  //resultmap.put("returnInfo","生成支付链接成功");
  Map<String,Object> urldatamap = new HashMap<String,Object>();
  urldatamap.put("url", urlmap.get("url"));
  //urldatamap.put("merOrderId", urlmap.get("merOrderId"));
  urldatamap.put("merOrderId", datamap.get("merOrderId"));

resultmap.put("data", urldatamap);

return resultmap;
}

1.2.2 UnionpayScanServiceimpl代码
本部分代码为银联商务支付下单接口实现类。本案例对接银联商务支付下单接口,并对接口进行封装,返回给测试网页一个URL支付链接,前端接收到url后,对其进行qrCode转为二维码,用户扫描二维码后完成支付。
包括UnifiedOrder方法和CreateUrl方法,其中UnifiedOrder方法为调起银联商务支付下单的支付链接,CreateUrl方法为返回到前端用于生成支付二维码的实现类。

/**
  *  银联商务支付下单
  * return map
  * @throws UnsupportedEncodingException 
  */
 @Override
 public String UnifiedOrder(Map<String,Object> map) throws UnsupportedEncodingException {
  // TODO Auto-generated method stub
  Map<String, Object> reqmap = new HashMap<String, Object>(); //请求银联商务map
   reqmap.put("mid", map.get("mid"));   //商户号
   reqmap.put("tid", map.get("tid"));   //终端号
   reqmap.put("instMid", map.get("instMid"));
   reqmap.put("msgSrc", map.get("msgSrc")); //消息来源
   reqmap.put("msgId", "UnionPay_F001");  //自定义
   reqmap.put("msgType", map.get("msgType")); //支付类型,前端传入
   
   //报文请求时间
   String aligetTime = PayUtil.aligetTime();
   logger.info("end_time = " + aligetTime);
   reqmap.put("requestTimestamp", aligetTime); 
   
   //商户订单号
   //reqmap.put("msgSrcId", this.msgSrcId); //来源编号
//   String orderid = GGitUtil.createOrderID();
//   StringBuffer buff = new StringBuffer(); 
//   buff.append(this.msgSrcId);
//   buff.append(orderid);
   reqmap.put("merOrderId", map.get("merOrderId"));
   
   reqmap.put("originalAmount", map.get("totalAmount")); //前端传入
   reqmap.put("totalAmount",map.get("totalAmount")); //订单金额
   reqmap.put("notifyUrl", map.get("notifyUrl")); //支付结果通知地址
   reqmap.put("returnUrl", map.get("returnUrl")); //网页跳转地址
   
   //生成待签名字符串并进行MD5加密
   String builderSignStr = "";
   try {
      builderSignStr = PayUtil.builderSignStr(reqmap,UnionPayConstants.MD5KEY);
    //signString = PayUtil.generateSignature(reqmap, UnionPayConstants.MD5KEY);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   reqmap.put("sign", builderSignStr);
   logger.info("reqmap= " + reqmap);
   
   //拼接请求URL
   StringBuffer url = new StringBuffer();
   try {
    url.append("https://qr-test2.chinaums.com/netpay-portal/webpay/pay.do?");
    url.append("requestTimestamp=" + URLEncoder.encode((String) reqmap.get("requestTimestamp"), "UTF-8") +
      "&mid=" + URLEncoder.encode((String) reqmap.get("mid"), "UTF-8") + 
      "&tid="+ URLEncoder.encode((String) reqmap.get("tid"), "UTF-8") + 
      "&instMid=" + URLEncoder.encode((String) reqmap.get("instMid"), "UTF-8") + 
      "&msgSrc=" + URLEncoder.encode((String) reqmap.get("msgSrc"), "UTF-8") + 
      "&merOrderId=" + URLEncoder.encode((String) reqmap.get("merOrderId"), "UTF-8") + 
      "&totalAmount=" + URLEncoder.encode((String) reqmap.get("totalAmount"), "UTF-8") + 
      "&msgId=" + URLEncoder.encode((String) reqmap.get("msgId"), "UTF-8") + 
      "&msgType=" + URLEncoder.encode((String) reqmap.get("msgType"), "UTF-8") + 
      "&originalAmount=" + URLEncoder.encode((String) reqmap.get("originalAmount"), "UTF-8") + 
      "&notifyUrl=" + URLEncoder.encode((String) reqmap.get("notifyUrl"), "UTF-8") + 
      "&returnUrl=" + URLEncoder.encode((String) reqmap.get("returnUrl"), "UTF-8") + 
      "&sign=" + URLEncoder.encode((String) reqmap.get("sign"), "UTF-8"));
    logger.info("银联商务下单url = " + url);
   } catch (Exception e) {
    // TODO: handle exception
    return "缺少必要参数,请核实后再进行下单";
   }
  return url.toString();
 }
 /**
  * 生成支付链接+商户号
  */
 @Override
 public Map<String, Object> CreateUrl(Map<String, Object> reqmap) {
  // TODO Auto-generated method stub
  
  //生成商户订单号
  //reqmap.put("msgSrcId", this.msgSrcId); //来源编号
//  String orderid = GGitUtil.createOrderID();
//  StringBuffer buff = new StringBuffer(); 
//  buff.append(this.msgSrcId);
//  buff.append(orderid);
//  String merOrderId = buff.toString();
  
  //拼接请求URL
  String mid = (String) reqmap.get("mid");
  String tid = (String) reqmap.get("tid");
  String instMid = (String) reqmap.get("instMid");
  String msgSrc = (String) reqmap.get("msgSrc");
  String totalAmount = (String) reqmap.get("totalAmount");
  String msgType = (String) reqmap.get("msgType");
  String notifyUrl = (String) reqmap.get("notifyUrl");
  String returnUrl = (String) reqmap.get("returnUrl");
  String merOrderId = (String) reqmap.get("merOrderId");
  StringBuffer url = new StringBuffer();
  url.append("http://www.ggzzrj.cn:8081/unionpay/lay/unifiedpay?");
  url.append("mid=" + mid + "&tid=" + tid + "&instMid=" + instMid + "&msgSrc=" + msgSrc 
    + "&totalAmount=" + totalAmount + "&msgType=" + msgType + "&notifyUrl=" + notifyUrl +"&returnUrl=" + returnUrl + "&merOrderId=" + merOrderId);
  
  Map<String,Object> respmap = new HashMap<String,Object>();
  respmap.put("merOrderId", merOrderId);
  respmap.put("url", url.toString());
  return respmap;
 }

1.3 支付结果截图
在下单接口中,使用测试网页进行测试,用户扫描测试网页生成的支付二维码,然后调起支付页面,用户支付完成时,点击“完成”按钮,跳转到程序中指定的returnurl地址中,支付结果通知到notifyurl地址中,测试网页截图如图示。
在这里插入图片描述
支付页面
在这里插入图片描述

相关文章:

  • 报错:Invalid bound statement (not found): com.wshy.example.dao.UserDao.getUsers
  • Field userDao ....service.impl...'com.lzj.springcloud.dao.UserDao' that could not be found
  • java对接银联商务扫码支付(银联商务扫码支付文档)
  • Java中拦截器的使用
  • 记项目中出现的数据库若干问题和注意事项
  • 工行icbc 在线支付jar包下载及maven导入本地库
  • 工行聚合支付二维码扫码付对接流程及代码实现
  • Java常量类配置--json文件方式
  • Java中File类的常用操作及项目中的使用
  • Java Utils工具类--jsonmap
  • Java Utils工具类--MD5加密
  • Java Utils工具类--DateUtils
  • “停车场一码付”的一些思考与尝试
  • MySQL数据库表从一个数据库复制到另一个数据库
  • 对接银联商务微信公众号支付遇到的坑
  • canvas 绘制双线技巧
  • git 常用命令
  • JavaScript创建对象的四种方式
  • java第三方包学习之lombok
  • jQuery(一)
  • leetcode386. Lexicographical Numbers
  • Linux CTF 逆向入门
  • MySQL几个简单SQL的优化
  • Node + FFmpeg 实现Canvas动画导出视频
  • Redis的resp协议
  • Spark RDD学习: aggregate函数
  • Vue 动态创建 component
  • webpack+react项目初体验——记录我的webpack环境配置
  • 编写符合Python风格的对象
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 给初学者:JavaScript 中数组操作注意点
  • 观察者模式实现非直接耦合
  • 后端_MYSQL
  • 记一次删除Git记录中的大文件的过程
  • 讲清楚之javascript作用域
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 跳前端坑前,先看看这个!!
  • 智能合约Solidity教程-事件和日志(一)
  • 《天龙八部3D》Unity技术方案揭秘
  • elasticsearch-head插件安装
  • ionic入门之数据绑定显示-1
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 从如何停掉 Promise 链说起
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #HarmonyOS:Web组件的使用
  • #Z2294. 打印树的直径
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (day6) 319. 灯泡开关
  • (vue)页面文件上传获取:action地址
  • (二)丶RabbitMQ的六大核心
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (六)软件测试分工
  • (转)程序员疫苗:代码注入