支付,在微信小程序上面称为当一个用户使用该小程序,当进入到支付环节,我们需要调用微信支付接口过程,进行一系列的操作,并记录下来。
微信小程序与java接口实现支付操作,大致思路如下:
1.微信小程序调用Java后台方法获取参数,
2.java 后台设置参数等并且传递参数返回给微信小程序,
3.微信小程序支付成功,
4.调用设置的回调地址(订单存入数据库),
5.最后调用微信小程序的success方法。
对应代码如下:
1.微信小程序调用支付

   //得到openid(微信用户唯一的openid)//该步骤忽略。。。//得到价钱(自定义)String price = httpRequest.getParameter("price");int fee = 0;if (null != price) {fee = Integer.parseInt(price.toString());}//得到商品的ID(自定义)String goodsid=httpRequest.getParameter("goodsid");//订单标题(自定义)String title = httpRequest.getParameter("title");//时间戳String times = System.currentTimeMillis() + "";//订单编号(自定义 这里以时间戳+随机数)Random random = new Random();String did = times+random.nextInt(1000);SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();packageParams.put("appid",MapUtils.getString(configProperties, "appId"));//微信小程序IDpackageParams.put("mch_id", MapUtils.getString(configProperties, "mch_id"));//商户IDpackageParams.put("nonce_str", times);//随机字符串(32位以内) 这里使用时间戳packageParams.put("body", title);//支付主体名称 自定义packageParams.put("out_trade_no", did+goodsid);//编号 自定义以随机数+商品IDpackageParams.put("total_fee", PayUtil.getMoney(price));//价格 自定义//packageParams.put("spbill_create_ip", remoteAddr);packageParams.put("notify_url", "https://xxx.xx.xx.xx/xxxxx/buy.do");//支付返回地址要外网访问的到, localhost不行,调用下面buy方法。(订单存入数据库)packageParams.put("trade_type", "JSAPI");//这个api有,固定的packageParams.put("openid", openid);//用户的openid 可以要 可以不要//获取sign(第一次签名)String sign = PayUtil.createSign("UTF-8", packageParams, MapUtils.getString(configProperties, "mah_password"));//最后这个是自己在微信商户设置的32位密钥/*String mapStr = PayUtil.createLinkString(packageParams);String key = MapUtils.getString(configProperties, "mah_password");//MD5生成运算签名String sign = PayUtil.sign(mapStr,key,"utf-8").toUpperCase();*/packageParams.put("sign", sign);System.out.println(sign);//转成XMLString requestXML = PayUtil.getRequestXml(packageParams);System.out.println(requestXML);//得到含有prepay_id的XMLString resXml = HttpUtils.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);System.out.println(resXml);//解析XML存入MapMap map2 = null;try {map2 = XmlUtil.doXMLParse(resXml);} catch (Exception e) {e.printStackTrace();}System.out.println(map2);String return_code = (String) map2.get("return_code");//得到prepay_id 进行二次签名SortedMap<Object, Object> packageP = new TreeMap<Object, Object>();try{if(return_code.equals("SUCCESS")){//获取数据//List<PayInfo> payInfoList =  payService.selectPayInfoByOpenId(openid);//如果等于空,说明为第一次支付/*if(CollectionUtils.isEmpty(payInfoList)){PayInfo payInfo = new PayInfo();payInfo.setPayId(did+goodsid);//设置openidpayInfo.setOpenId(openid);//设置金额payInfo.setAmount(fee);//设置说明payInfo.setTitle(title);//设置支付状态payInfo.setPayStatus("0");//插入数据int count = payService.insertPayInfo(payInfo);//判断if(count==1){log.info("新增支付信息成功");}}else{//判断是否为第一条if(payInfoList.size() == 1){PayInfo payInfo = payInfoList.get(0);//更新该条的金额payInfo.setAmount(fee+payInfo.getAmount());//更新数据int count = payService.updateByPayInfo(payInfo);//判断if (count==1){log.info("修改支付信息成功");}}}*/PayInfo payInfo = new PayInfo();payInfo.setPayId(did+goodsid);//设置openidpayInfo.setOpenId(openid);//设置金额payInfo.setAmount(fee);//设置说明payInfo.setTitle(title);//设置支付状态payInfo.setPayStatus("0");//插入数据int count = payService.insertPayInfo(payInfo);//判断if(count==1){log.info("新增支付信息成功");}String prepay_id = (String) map2.get("prepay_id");//packageP = new TreeMap<Object, Object>();packageP.put("appId", MapUtils.getString(configProperties, "appId"));//!!!注意,这里是appId,上面是appidpackageP.put("nonceStr", times);//时间戳packageP.put("package", "prepay_id=" + prepay_id);//必须把package写成 "prepay_id="+prepay_id这种形式packageP.put("signType", "MD5");//paySign加密packageP.put("timeStamp", (System.currentTimeMillis() / 1000) + "");//得到paySign 用于请求微信/*String payStr = PayUtil.createLinkString(packageP);String paySign =  PayUtil.sign(payStr,key,"utf-8").toUpperCase();*/String paySign = PayUtil.createSign("UTF-8", packageP, MapUtils.getString(configProperties, "mah_password"));packageP.put("paySign", paySign);packageP.put("success", true);}else{packageP.put("success",false);}}catch (Exception e){e.printStackTrace();log.info("接口异常");}//将package 返回给小程序return packageP;

2.微信小程序支付成功后的回调(notify_url 写的地址)

        log.info("进入buy方法");BufferedReader br = new BufferedReader(new InputStreamReader(httpRequest.getInputStream()));String line = null;StringBuilder sb = new StringBuilder();while((line = br.readLine()) != null){sb.append(line);}br.close();//sb为微信返回的xmlString notityXml = sb.toString();String resXml = "";Map map = XmlUtil.doXMLParse(notityXml);System.out.println("map = " + map);String returnCode = (String) map.get("return_code");try{if("SUCCESS".equals(returnCode)){ //判断是否处理过//进行签名验证,看是否是从微信发送过来的,防止资金被盗SortedMap stringStringMap = PayUtil.paraFilter(map);String signMy = PayUtil.createSign("utf-8", stringStringMap, MapUtils.getString(configProperties, "mah_password"));System.out.println("signMy = " + signMy);System.out.println("flag = " + map.get("sign"));if(signMy.equals(map.get("sign"))){String out_trade_no=(String) map.get("out_trade_no");/** 存入数据库的逻辑*/resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";}else {resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"   + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";}BufferedOutputStream out = new BufferedOutputStream(httpResponse.getOutputStream());out.write(resXml.getBytes()); //告诉微信服务器,我收到了,不要再回调action方法了out.flush();out.close();}}catch (Exception e){e.printStackTrace();}

PayUtil工具类:

    /*** 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。* @return boolean*/public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while(it.hasNext()) {Map.Entry entry = (Map.Entry)it.next();String k = (String)entry.getKey();String v = (String)entry.getValue();if(!"sign".equals(k) && null != v && !"".equals(v)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);//算出摘要String mysign = MD5.MD5Encode(sb.toString(), characterEncoding).toLowerCase();String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();//System.out.println(tenpaySign + "    " + mysign);return tenpaySign.equals(mysign);}/*** @author* @Description:sign签名* @param characterEncoding*            编码格式*            请求参数* @return*/public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = entry.getKey().toString();String v = entry.getValue().toString();if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);String sign = MD5.MD5Encode(sb.toString(), characterEncoding).toUpperCase();return sign;}/*** 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串* @param params 需要排序并参与字符拼接的参数组* @return 拼接后字符串*/public static String createLinkString(Map<Object, Object> params) {List<String> keys = new ArrayList<String>();Collections.sort(keys);String prestr = "";for (int i = 0; i < keys.size(); i++) {String key = keys.get(i);Object value = params.get(key);if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符prestr = prestr + key + "=" + value;} else {prestr = prestr + key + "=" + value + "&";}}return prestr;}/*** @author* @Description:将请求参数转换为xml格式的string* @param parameters*            请求参数* @return*/public static String getRequestXml(SortedMap<Object, Object> parameters) {StringBuffer sb = new StringBuffer();sb.append("<xml>");Set es = parameters.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = entry.getKey().toString();String v = entry.getValue().toString();if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {sb.append("<" + k + ">"  + v + "</" + k + ">");} else {sb.append("<" + k + ">" + v + "</" + k + ">");}}sb.append("</xml>");return sb.toString();}/*** 验证签名,判断是否是从微信发过来* 验证方法:接收微信服务器回调我们url的时候传递的xml中的参数 然后再次加密,看是否与传递过来的sign签名相同* @param map* @return*/public static boolean verifyWeixinNotify(Map<Object, Object> map,String key) {//根据微信服务端传来的各项参数 进行再一次加密后  与传过来的 sign 签名对比String mapStr = createLinkString(map);String signOwn = PayUtil.sign(mapStr, key, "utf-8").toUpperCase();         //根据微信端参数进行加密的签名String signWx = (String) map.get("sign");                //微信端传过来的签名if(signOwn.equals(signWx)){//如果两个签名一致,验证成功return true;}return false;}/*** 签名字符串*  @param text 需要签名的字符串* @param sign 签名结果* @param key 密钥* @param input_charset 编码格式* @return 签名结果*/public static boolean verify(String text, String sign, String key, String input_charset) {text = text +"&key="+ key;String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));System.out.println("mysign = " + mysign);if (mysign.equals(sign)) {return true;} else {return false;}}/*** 元转换成分* @param amount* @return*/public static String getMoney(String amount) {if(amount==null){return "";}// 金额转化为分为单位String currency =  amount.replaceAll("\\$|\\¥|\\,", "");  //处理包含, ¥ 或者$的金额int index = currency.indexOf(".");int length = currency.length();Long amLong = 0l;if(index == -1){amLong = Long.valueOf(currency+"00");}else if(length - index >= 3){amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));}else if(length - index == 2){amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);}else{amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");}return amLong.toString();}/*** 获取随机字符串 (采用截取8位当前日期数  + 4位随机整数)* @return*/public static String getNonceStr() {//获得当前日期Date now = new Date();SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");String currTime = outFormat.format(now);//截取8位String strTime = currTime.substring(8, currTime.length());//得到4位随机整数int num = 1;double random = Math.random();if (random < 0.1) {random = random + 0.1;}for (int i = 0; i < 4; i++) {num = num * 10;}num = (int)random * num;return strTime + num;}/*** MD5 加密,转为指定类型* @param text* @param key* @param input_charset* @return*/public static String sign(String text, String key, String input_charset) {text = text + key;return DigestUtils.md5Hex(getContentBytes(text, input_charset));}public static byte[] getContentBytes(String content, String charset) {if (charset == null || "".equals(charset)) {return content.getBytes();}try {return content.getBytes(charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);}}/*** 除去数组中的空值和签名参数* @param sArray 签名参数组* @return 去掉空值与签名参数后的新签名参数组*/public static SortedMap<Object, Object> paraFilter(Map<String, String> sArray) {SortedMap<Object, Object> result = new TreeMap<Object, Object>();if (sArray == null || sArray.size() <= 0) {return result;}for (String key : sArray.keySet()) {String value = sArray.get(key);if (value == null || value.equals("") || key.equalsIgnoreCase("sign")|| key.equalsIgnoreCase("sign_type")) {continue;}result.put(key, value);}return result;}

支付就可以实现了,如果大家有什么问题,可以随时留言。。。

觉得棒的话,赶紧打赏小编吧!

微信小程序+java后台实现支付(java操作)相关推荐

  1. 微信小程序netcore后台api支付结果通知接口的坑

    终于搞定回调通知了,这里总结下几个暗坑 1.回调通知一定是post接口,且可以直接访问 2.需要解析回调的HttpContext内容才能知道结果 3.收到信息一定要进行验证判断是否来自于微信渠道 4. ...

  2. 微信小程序获取用户手机号码,Java后台servlet解密(微信小程序调用微信支付也是大致的流程)

    本篇记录说明 微信小程序获取用户手机号码,Java后台servlet解密(微信小程序调用微信支付也是大致的流程,详细内容可私信交流) (第一次写博客,写得不好的地方见谅,面向新手,大佬请无视,不喜勿喷 ...

  3. 小程序数据怎么传输到服务器,微信小程序怎么将数据传输到Java后台

    微信小程序怎么将数据传输到Java后台 发布时间:2020-12-10 14:19:49 来源:亿速云 阅读:124 作者:Leah 今天就跟大家聊聊有关微信小程序怎么将数据传输到Java后台,可能很 ...

  4. 基于java springboot的小说阅读微信小程序含后台管理系统源码

    系统运行环境 开发工具 eclipse(idea),mysql5.7(大于5.5),navicat,小程序开发工具 硬件要求 windows操作系统 cpu:2.4GHz 内存:4G 硬盘:100G ...

  5. 微信小程序实现用户登录授权java代码

    1.微信官方文档 auth.code2Session | 微信开放文档 2.我们来实现这个登录功能, 直接上完整代码  controller <!-- 工具类-JSONUtil --> & ...

  6. 微信小程序记事本+后台管理系统

    <微信小程序记事本+后台管理系统>该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序做的记事本前台和Java做的后台管理系统: 微信小程序--记事 ...

  7. 微信小程序菜谱+后台管理系统

    <微信小程序菜谱+后台管理系统>该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序做的菜谱前台和Java做的后台管理系统: 微信小程序--菜谱前台 ...

  8. 微信小程序中使用JSAPI支付

    微信小程序中使用JSAPI支付 在微信小程序中使用微信支付api[wx.requestPayment]需要传递以下字段 如何获取支付所需要的值 在微信小程序中使用微信支付api[wx.requestP ...

  9. 微信小程序与后台PHP交互

    在去年的时候,参加过学校的一个创业活动,在团队决定做一个关于图书的微信小程序以后,我负责做微信小程序的后台程序,因为初次接触,决定选用较为简单的PHP作为后台语言,实现了微信小程序的一些基本功能,例如 ...

  10. 微信小程序链接后台接口,进行数据交互

    微信小程序链接后台接口,进行数据交互 新手学微信小程序,设计页面还可以,有没有让进行数据交互的时候就不知道怎么弄了,下面就记录一下我是怎么进行交互的 1.登陆微信小程序平台,进入首页,点击开发设置 2 ...

最新文章

  1. C#共享内存实例 附源码
  2. Android入门教程 (二) 第一个App HelloWorld
  3. Win32_16来看看标准菜单和右键菜单的玩法
  4. 【风控场景】互利网上数字金融典型场景: 网络支付
  5. Uva_105 (类并查集)
  6. Java无处不在:使用DukeScript在任何地方运行一次编写
  7. c++驱动键鼠源码_DD驱动级虚拟键鼠套装
  8. one stage 与two stage解释
  9. Zookeeper原理架构
  10. 【代码笔记】iOS-竖状图
  11. 六石编程学:方便调试输出的标准C代码
  12. BZOJ 2839: 集合计数 解题报告
  13. 拍照怎么搜题?(上)
  14. DLL注入与DLL劫持注入
  15. 学画画软件app推荐_一步一步教画画的app有哪些_2018手机画画软件哪个好呢_96u手游网...
  16. 交换基础之生成树协议
  17. 将一个对象转换成数组
  18. TypeScript——Web前端开发的救赎
  19. Swift 检查版本更新 itunes
  20. Apache Impala —— 3.4.0版本官方文档百度网盘下载链接

热门文章

  1. Transferable Sparse Adversarial Attack
  2. Backlog 讨论
  3. 计算机主板不认硬盘怎么回事,电脑不识别硬盘怎么办_硬盘无法识别如何修复...
  4. 中国口岸统计资料 2001-2015年
  5. QGIS编译(跨平台编译)之十六:Expat编译(Windows、Linux、MacOS环境下编译)
  6. 横版表格加入竖向页码
  7. flutter 项目实战四 列表数据展示
  8. html布局 跨行,3种方案实现跨行或跨列布局
  9. ABP 使用SwaggerUI汉化
  10. 见证海马S7手动型的高配置