• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

微信小程序-统一下单、微信支付(Java后台)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

1、首先分享 微信统一下单接口: 

      https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 

        微信接口 签名 对比网址:

      https://pay.weixin.qq.com/wiki/tools/signverify/

        微信小程序 微信支付 网址:

      https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-pay.html#wxrequestpaymentobject

 

2、微信小程序端 代码示例:

 1   payment:function(event){
 2     var that = this;
 3     console.log(\'去支付按钮点击事件\')
 4     wx.request({
 5       url: \'http://192.168.8.50:8080/matouwang/wechat/wechatAppletGolf/createUnifiedOrder\',
 6       method: \'POST\', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
 7       // 当method 为POST 时 设置以下 的header 
 8       header: { \'content-type\': \'application/x-www-form-urlencoded\' },
 9       data: {
10         amount: teamMoney,
11         openid: openId
12       },
13       success: function (res) {
14         if (res.data.prepayId != \'\'){
15           console.log(\'微信统一下单接口调用成功 数据包:\' + res.data.prepayId);
16           console.log(\'微信统一下单接口调用成功 订单号:\' + res.data.outTradeNo);
17           console.log(\'调用微信支付接口之前先生成签名\')
18           //保存订单号信息
19           var outTradeNo = res.data.outTradeNo;
20           wx.request({
21             url: \'http://192.168.8.50:8080/matouwang/wechat/wechatAppletGolf/generateSignature\',
22             method: \'POST\', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
23             // 当method 为POST 时 设置以下 的header 
24             header: { \'content-type\': \'application/x-www-form-urlencoded\' },
25             data: {
26               prepayId: res.data.prepayId
27             },
28             success: function (paryResult) {
29               if (paryResult.data.sign != \'\') {
30                 console.log(\'微信支付接口之前先生成签名成功\')
31                 console.log(\'签名:\' + paryResult.data.sign)
32                 console.log(\'随机串:\' + paryResult.data.nonceStr)
33                 console.log(\'时间戳:\' + paryResult.data.timeStamp)
34                 //这个applyId一定要大写 而且签名的参数和调用方法的参数值一定要统一
35                 wx.requestPayment({
36                   \'appId\': \'\',
37                   \'timeStamp\': paryResult.data.timeStamp,
38                   \'nonceStr\': paryResult.data.nonceStr,
39                   \'package\': paryResult.data.package,
40                   \'signType\': \'MD5\',
41                   \'paySign\': paryResult.data.sign,
42                   \'success\': function (paymentRes) {
43                     console.log(paymentRes)
44                     that.setData({
45                       notPay: true,
46                       paySuccess: false,
47                       teamNotPay: true,
48                       button:true,
49                       outTradeNo: outTradeNo,
50                       payDate:new Date()
51                     })
52                   },
53                   \'fail\': function (error) {
54                     console.log(error)
55                   }
56                 })
57               } else {
58                 console.log(\'微信支付接口之前先生成签名失败\')
59               }
60             }
61           })
62         }
63       }
64     });
65   },

3、分享微信 统一下单 后台代码示例:

  1     @Override
  2     public JSONObject createUnifiedOrder(HttpServletRequest request,HttpServletResponse response) {
  3         logger.info("微信 统一下单 接口调用");
  4         //设置最终返回对象
  5         JSONObject resultJson = new JSONObject();
  6         //创建条件
  7         Criteria criteria = new Criteria();
  8     
  9         //接受参数(金额)
 10         String amount = request.getParameter("amount");
 11         //接受参数(openid)
 12         String openid = request.getParameter("openid");
 13         //接口调用总金额单位为分换算一下(测试金额改成1,单位为分则是0.01,根据自己业务场景判断是转换成float类型还是int类型)
 14         //String amountFen = Integer.valueOf((Integer.parseInt(amount)*100)).toString();
 15         //String amountFen = Float.valueOf((Float.parseFloat(amount)*100)).toString();
 16         String amountFen = "1";
 17         //创建hashmap(用户获得签名)
 18         SortedMap<String, String> paraMap = new TreeMap<String, String>();
 19         //设置body变量 (支付成功显示在微信支付 商品详情中)
 20         String body = "啦啦啦测试";
 21         //设置随机字符串
 22         String nonceStr = Utils.getUUIDString().replaceAll("-", "");
 23         //设置商户订单号
 24         String outTradeNo = Utils.getUUIDString().replaceAll("-", "");
 25         
 26         
 27         //设置请求参数(小程序ID)
 28         paraMap.put("appid", APPLYID);
 29         //设置请求参数(商户号)
 30         paraMap.put("mch_id", MCHID);
 31         //设置请求参数(随机字符串)
 32         paraMap.put("nonce_str", nonceStr);
 33         //设置请求参数(商品描述)
 34         paraMap.put("body", body);
 35         //设置请求参数(商户订单号)
 36         paraMap.put("out_trade_no", outTradeNo);
 37         //设置请求参数(总金额)
 38         paraMap.put("total_fee", amountFen);
 39         //设置请求参数(终端IP)
 40         paraMap.put("spbill_create_ip", WebUtils.getIpAddress(request, response));
 41         //设置请求参数(通知地址)
 42         paraMap.put("notify_url", WebUtils.getBasePath()+"wechat/wechatAppletGolf/payCallback");
 43         //设置请求参数(交易类型)
 44         paraMap.put("trade_type", "JSAPI");
 45         //设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成\'JSAPI\'则必须传入openid)
 46         paraMap.put("openid", openid);
 47         //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序(字典序)
 48         String stringA = formatUrlMap(paraMap, false, false);
 49         //第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。(签名)
 50         String sign = MD5Util.MD5(stringA+"&key="+KEY).toUpperCase();
 51         //将参数 编写XML格式
 52         StringBuffer paramBuffer = new StringBuffer();
 53         paramBuffer.append("<xml>");
 54         paramBuffer.append("<appid>"+APPLYID+"</appid>");
 55         paramBuffer.append("<mch_id>"+MCHID+"</mch_id>");
 56         paramBuffer.append("<nonce_str>"+paraMap.get("nonce_str")+"</nonce_str>");
 57         paramBuffer.append("<sign>"+sign+"</sign>");
 58         paramBuffer.append("<body>"+body+"</body>");
 59         paramBuffer.append("<out_trade_no>"+paraMap.get("out_trade_no")+"</out_trade_no>");
 60         paramBuffer.append("<total_fee>"+paraMap.get("total_fee")+"</total_fee>");
 61         paramBuffer.append("<spbill_create_ip>"+paraMap.get("spbill_create_ip")+"</spbill_create_ip>");
 62         paramBuffer.append("<notify_url>"+paraMap.get("notify_url")+"</notify_url>");
 63         paramBuffer.append("<trade_type>"+paraMap.get("trade_type")+"</trade_type>");
 64         paramBuffer.append("<openid>"+paraMap.get("openid")+"</openid>");
 65         paramBuffer.append("</xml>");
 66         
 67         try {
 68             //发送请求(POST)(获得数据包ID)(这有个注意的地方 如果不转码成ISO8859-1则会告诉你body不是UTF8编码 就算你改成UTF8编码也一样不好使 所以修改成ISO8859-1)
 69             Map<String,String> map = doXMLParse(getRemotePortData(URL, new String(paramBuffer.toString().getBytes(), "ISO8859-1")));
 70             //应该创建 支付表数据
 71             if(map!=null){
 72                 //清空
 73                 criteria.clear();
 74                 //设置openId条件
 75                 criteria.put("openId", openid);
 76                 //获取数据
 77                 List<WechatAppletGolfPayInfo> payInfoList = appletGolfPayInfoMapper.selectByExample(criteria);
 78                 //如果等于空 则证明是第一次支付
 79                 if(CollectionUtils.isEmpty(payInfoList)){
 80                     //创建支付信息对象
 81                     WechatAppletGolfPayInfo appletGolfPayInfo = new  WechatAppletGolfPayInfo();
 82                     //设置主键
 83                     appletGolfPayInfo.setPayId(outTradeNo);
 84                     //设置openid
 85                     appletGolfPayInfo.setOpenId(openid);
 86                     //设置金额
 87                     appletGolfPayInfo.setAmount(Long.valueOf(amount));
 88                     //设置支付状态
 89                     appletGolfPayInfo.setPayStatus("0");
 90                     //插入Dao
 91                     int sqlRow = appletGolfPayInfoMapper.insert(appletGolfPayInfo);
 92                     //判断
 93                     if(sqlRow == 1){
 94                         logger.info("微信 统一下单 接口调用成功 并且新增支付信息成功");
 95                         resultJson.put("prepayId", map.get("prepay_id"));
 96                         resultJson.put("outTradeNo", paraMap.get("out_trade_no"));
 97                         return resultJson;
 98                     }
 99                 }else{
100                     //判断 是否等于一条
101                     if(payInfoList.size() == 1){
102                         //获取 需要更新数据
103                         WechatAppletGolfPayInfo wechatAppletGolfPayInfo = payInfoList.get(0);
104                         //更新 该条的 金额
105                         wechatAppletGolfPayInfo.setAmount(Long.valueOf(amount));
106                         //更新Dao
107                         int sqlRow = appletGolfPayInfoMapper.updateByPrimaryKey(wechatAppletGolfPayInfo);
108                         //判断
109                         if(sqlRow == 1){
110                             logger.info("微信 统一下单 接口调用成功 修改支付信息成功");
111                             resultJson.put("prepayId", map.get("prepay_id"));
112                             resultJson.put("outTradeNo", paraMap.get("out_trade_no"));
113                             return resultJson;
114                         }
115                     }
116                 }
117             }
118             //将 数据包ID 返回
119             
120             System.out.println(map);
121         } catch (UnsupportedEncodingException e) {
122             logger.info("微信 统一下单 异常:"+e.getMessage());
123             e.printStackTrace();
124         } catch (Exception e) {
125             logger.info("微信 统一下单 异常:"+e.getMessage());
126             e.printStackTrace();
127         }
128         logger.info("微信 统一下单 失败");
129         return resultJson;
130     }

4、生成 微信支付 签名后台 代码示例:

 1     @Override
 2     public JSONObject generateSignature(HttpServletRequest request,
 3             HttpServletResponse response) {
 4         logger.info("微信 支付接口生成签名 方法开始");
 5         //实例化返回对象
 6         JSONObject resultJson = new JSONObject();
 7         
 8         //获得参数(微信统一下单接口生成的prepay_id )
 9         String prepayId = request.getParameter("prepayId");
10         //创建 时间戳
11         String timeStamp = Long.valueOf(System.currentTimeMillis()).toString();
12         //创建 随机串
13         String nonceStr = Utils.getUUIDString().replaceAll("-", "");
14         //创建 MD5
15         String signType = "MD5";
16         
17         //创建hashmap(用户获得签名)
18         SortedMap<String, String> paraMap = new TreeMap<String, String>();
19         //设置(小程序ID)(这块一定要是大写)
20         paraMap.put("appId", APPLYID);
21         //设置(时间戳)
22         paraMap.put("timeStamp", timeStamp);
23         //设置(随机串)
24         paraMap.put("nonceStr", nonceStr);
25         //设置(数据包)
26         paraMap.put("package", "prepay_id="+prepayId);
27         //设置(签名方式)
28         paraMap.put("signType", signType);
29         
30         
31         //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序(字典序)
32         String stringA = formatUrlMap(paraMap, false, false);
33         //第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。(签名)
34         String sign = MD5Util.MD5(stringA+"&key="+KEY).toUpperCase();
35         
36         if(StringUtils.isNotBlank(sign)){
37             //返回签名信息
38             resultJson.put("sign", sign);
39             //返回随机串(这个随机串是新创建的)
40             resultJson.put("nonceStr", nonceStr);
41             //返回时间戳
42             resultJson.put("timeStamp", timeStamp);
43             //返回数据包
44             resultJson.put("package", "prepay_id="+prepayId);
45             
46             logger.info("微信 支付接口生成签名 设置返回值");
47         }
48         logger.info("微信 支付接口生成签名 方法结束");
49         return resultJson;
50     }

5、签名算法 将key Value 字典排序 代码示例:

 1     /** 
 2      *  
 3      * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序),并且生成url参数串<br> 
 4      * 实现步骤: <br> 
 5      *  
 6      * @param paraMap   要排序的Map对象 
 7      * @param urlEncode   是否需要URLENCODE 
 8      * @param keyToLower    是否需要将Key转换为全小写 
 9      *            true:key转化成小写,false:不转化 
10      * @return 
11      */  
12     private static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower){  
13         String buff = "";  
14         Map<String, String> tmpMap = paraMap;  
15         try  
16         {  
17             List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());  
18             // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)  
19             Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>()  
20             {  
21                 @Override  
22                 public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2)  
23                 {  
24                     return (o1.getKey()).toString().compareTo(o2.getKey());  
25                 }  
26             });  
27             // 构造URL 键值对的格式  
28             StringBuilder buf = new StringBuilder();  
29             for (Map.Entry<String, String> item : infoIds)  
30             {  
31                 if (StringUtils.isNotBlank(item.getKey()))  
32                 {  
33                     String key = item.getKey();  
34                     String val = item.getValue();  
35                     if (urlEncode)  
36                     {  
37                         val = URLEncoder.encode(val, "utf-8");  
38                     }  
39                     if (keyToLower)  
40                     {  
41                         buf.append(key.toLowerCase() + "=" + val);  
42                     } else  
43                     {  
44                         buf.append(key + "=" + val);  
45                     }  
46                     buf.append("&");  
47                 }  
48    
49             }  
50             buff = buf.toString();  
51             if (buff.isEmpty() == false)  
52             {  
53                 buff = buff.substring(0, buff.length() - 1);  
54             }  
55         } catch (Exception e)  
56         {  
57            return null;  
58         }  
59         return buff;  
60     }  

6、发送远程请求 获得数据 代码示例:

 1     
 2     /**
 3      * 方法名: getRemotePortData
 4      * 描述: 发送远程请求 获得代码示例
 5      * 参数:  @param urls 访问路径
 6      * 参数:  @param param 访问参数-字符串拼接格式, 例:port_d=10002&port_g=10007&country_a=
 7      * 创建人: Xia ZhengWei
 8      * 创建时间: 2017年3月6日 下午3:20:32
 9      * 版本号: v1.0   
10      * 返回类型: String
11     */
12     private String getRemotePortData(String urls, String param){
13         logger.info("港距查询抓取数据----开始抓取外网港距数据");
14         try {
15             URL url = new URL(urls);
16             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
17             // 设置连接超时时间
18             conn.setConnectTimeout(30000);
19             // 设置读取超时时间
20             conn.setReadTimeout(30000);
21             conn.setRequestMethod("POST");
22             if(StringUtil.isNotBlank(param)) {
23                 conn.setRequestProperty("Origin", "https://sirius.searates.com");// 主要参数
24                 conn.setRequestProperty("Referer", "https://sirius.searates.com/cn/port?A=ChIJP1j2OhRahjURNsllbOuKc3Y&D=567&G=16959&shipment=1&container=20st&weight=1&product=0&request=&weightcargo=1&");
25                 conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");// 主要参数
26             }
27             // 需要输出
28             conn.setDoInput(true);
29             // 需要输入
30             conn.setDoOutput(true);
31             // 设置是否使用缓存
32             conn.setUseCaches(false);
33             // 设置请求属性
34             conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
35             conn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
36             conn.setRequestProperty("Charset", "UTF-8");
37             
38             if(StringUtil.isNotBlank(param)) {
39                 // 建立输入流,向指向的URL传入参数
40                 DataOutputStream dos=new DataOutputStream(conn.getOutputStream());
41                 dos.writeBytes(param);
42                 dos.flush();
43                 dos.close();
44             }
45             // 输出返回结果
46             InputStream input = conn.getInputStream();
47             int resLen =0;
48             byte[] res = new byte[1024];
49             StringBuilder sb=new StringBuilder();
50             while((resLen=input.read(res))!=-1){
51                 sb.append(new String(res, 0, resLen));
52             }
53             return sb.toString();
54         } catch (MalformedURLException e) {
55             e.printStackTrace();
56             logger.info("港距查询抓取数据----抓取外网港距数据发生异常:" + e.getMessage());
57         } catch (IOException e) {
58             e.printStackTrace();
59             logger.info("港距查询抓取数据----抓取外网港距数据发生异常:" + e.getMessage());
60         }
61         logger.info("港距查询抓取数据----抓取外网港距数据失败, 返回空字符串");
62         return "";
63     }

7、XML 转换成 map 对象 代码示例:

 1     /**
 2      * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
 3      * @param strxml
 4      * @return
 5      * @throws JDOMException
 6      * @throws IOException
 7      */
 8     @SuppressWarnings("rawtypes")
 9     private Map<String,String> doXMLParse(String strxml) throws Exception {
10         if(null == strxml || "".equals(strxml)) {
11             return null;
12         }
13         
14         Map<String,String> m = new HashMap<String,String>();
 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
01_微信小程序支付发布时间:2022-07-18
下一篇:
微信小程序 使用微信支付功能实现在线订单支付发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap