微信接口(小程序订单付款/退款以及商户号提现)(二)

1:基本工具类

  1. IpUtils(获得ip)
    /**
     * @author zhangz
     * Create time 2019-11-17 17:53
     */
    public class IpUtil {
    
    
        private static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php?ip=%s";
    
        private static final Integer SUCCESS_CODE = 0;
    
        /**
         * IpUtils工具类方法
         * 获取真实的ip地址
         * @param request
         * @return
         */
        public static String getIpAddr(HttpServletRequest request) {
            String ip = request.getHeader("X-Forwarded-For");
            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
                //多次反向代理后会有多个ip值,第一个ip才是真实ip
                int index = ip.indexOf(",");
                if(index != -1){
                    return ip.substring(0,index);
                }else{
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
                return ip;
            }
            return request.getRemoteAddr();
        }
    
        public static IpAddrVO getIpInfo(String ip) {
            if (ip.equals("0:0:0:0:0:0:0:1")) {
                ip = "127.0.0.1";
            }
            if ("127.0.0.1".equals(ip)) {
                ip = "127.0.0.1";
            }
            String url = String.format(IP_URL, ip);
            String result = Https.get(url);
            IpAddrVO ipAddrVO = Jsons.toObject(result, IpAddrVO.class);
            if (!ipAddrVO.getCode().equals(0)) {
                throw new ServiceException("获取用户地址失败");
            }
            return ipAddrVO;
        }
    
        public static String getIpAddr(String ip) {
            IpAddrVO ipAddrVO = getIpInfo(ip);
            if (ipAddrVO != null) {
                Data data = ipAddrVO.getData();
                return data.getCountry()+data.getRegion()+data.getCity();
            }
            return "";
        }
    
    }

    3.退款付款相应的工具类

    public class PayCommonUtil {  
        //微信参数配置
        public static String API_KEY="1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik9";
    
        //随机字符串生成  
        public static String getRandomString(int length) { //length表示生成字符串的长度      
               String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";         
               Random random = new Random();         
               StringBuffer sb = new StringBuffer();         
               for (int i = 0; i < length; i++) {         
                   int number = random.nextInt(base.length());         
                   sb.append(base.charAt(number));         
               }         
               return sb.toString();         
            }
        //请求xml组装  
          public static String getRequestXml(SortedMap<String,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 key = (String)entry.getKey();  
                    String value = (String)entry.getValue();  
                    if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {  
                        sb.append("<"+key+">"+"<![CDATA["+value+"]]></"+key+">");  
                    }else {  
                        sb.append("<"+key+">"+value+"</"+key+">");  
                    }  
                }  
                sb.append("</xml>");  
                return sb.toString();  
            }  
          //生成签名  
          public static String createSign(String characterEncoding,SortedMap<String,Object> parameters,String t_API_KEY){  
                StringBuffer sb = new StringBuffer();  
                Set es = parameters.entrySet();  
                Iterator it = es.iterator();  
                while(it.hasNext()) {  
                    Map.Entry entry = (Map.Entry)it.next();  
                    String k = (String)entry.getKey();  
                    Object v = entry.getValue();  
                    if(null != v && !"".equals(v)  
                            && !"sign".equals(k) && !"key".equals(k)) {  
                        sb.append(k + "=" + v + "&");  
                    }  
                }  
                sb.append("key=" + t_API_KEY);  
                String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
                return sign;  
            }  
          //请求方法  
          public static String paraFilter(String requestUrl, String requestMethod, String outputStr) {
                try {  
                     
                    URL url = new URL(requestUrl);  
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
                    
                    conn.setDoOutput(true);  
                    conn.setDoInput(true);  
                    conn.setUseCaches(false);  
                    // 设置请求方式(GET/POST)  
                    conn.setRequestMethod(requestMethod);  
                    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");  
                    // 当outputStr不为null时向输出流写数据  
                    if (null != outputStr) {  
                        OutputStream outputStream = conn.getOutputStream();  
                        // 注意编码格式  
                        outputStream.write(outputStr.getBytes("UTF-8"));  
                        outputStream.close();  
                    }  
                    // 从输入流读取返回内容  
                    InputStream inputStream = conn.getInputStream();  
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
                    String str = null;  
                    StringBuffer buffer = new StringBuffer();  
                    while ((str = bufferedReader.readLine()) != null) {  
                        buffer.append(str);  
                    }  
                    // 释放资源  
                    bufferedReader.close();  
                    inputStreamReader.close();  
                    inputStream.close();  
                    inputStream = null;  
                    conn.disconnect();  
                    return buffer.toString();  
                } catch (ConnectException ce) {  
                    System.out.println("连接超时:{}"+ ce);  
                } catch (Exception e) {  
                    System.out.println("https请求异常:{}"+ e);  
                }  
                return null;  
            }  
          //退款的请求方法  
          public static String httpsRequest2(String requestUrl, String requestMethod, String outputStr) throws Exception {  
                KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
                StringBuilder res = new StringBuilder("");  
                FileInputStream instream = new FileInputStream(new File("/home/apiclient_cert.p12"));  
                try {  
                    keyStore.load(instream, "".toCharArray());  
                } finally {  
                    instream.close();  
                }  
      
                // Trust own CA and all self-signed certs  
                SSLContext sslcontext = SSLContexts.custom()  
                        .loadKeyMaterial(keyStore, "1313329201".toCharArray())  
                        .build();  
                // Allow TLSv1 protocol only  
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(  
                        sslcontext,  
                        new String[] { "TLSv1" },  
                        null,  
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
                CloseableHttpClient httpclient = HttpClients.custom()  
                        .setSSLSocketFactory(sslsf)  
                        .build();  
                try {  
      
                    HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");  
                    httpost.addHeader("Connection", "keep-alive");  
                    httpost.addHeader("Accept", "*/*");  
                    httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");  
                    httpost.addHeader("Host", "api.mch.weixin.qq.com");  
                    httpost.addHeader("X-Requested-With", "XMLHttpRequest");  
                    httpost.addHeader("Cache-Control", "max-age=0");  
                    httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");  
                     StringEntity entity2 = new StringEntity(outputStr ,Consts.UTF_8);  
                     httpost.setEntity(entity2);  
                    System.out.println("executing request" + httpost.getRequestLine());  
      
                    CloseableHttpResponse response = httpclient.execute(httpost);  
                     
                    try {  
                        HttpEntity entity = response.getEntity();  
                          
                        System.out.println("----------------------------------------");  
                        System.out.println(response.getStatusLine());  
                        if (entity != null) {  
                            System.out.println("Response content length: " + entity.getContentLength());  
                            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));  
                            String text = "";
                            res.append(text);  
                            while ((text = bufferedReader.readLine()) != null) {  
                                res.append(text);  
                                System.out.println(text);  
                            }  
                             
                        }  
                        EntityUtils.consume(entity);  
                    } finally {  
                        response.close();  
                    }  
                } finally {  
                    httpclient.close();  
                }  
                return  res.toString();  
                  
            }  
          //xml解析  
          public static Map doXMLParse(String strxml) throws JDOMException, IOException {  
                strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");  
      
                if(null == strxml || "".equals(strxml)) {  
                    return null;  
                }  
                  
                Map m = new HashMap();  
                  
                InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));  
                SAXBuilder builder = new SAXBuilder();  
                Document doc = builder.build(in);  
                Element root = doc.getRootElement();  
                List list = root.getChildren();  
                Iterator it = list.iterator();  
                while(it.hasNext()) {  
                    Element e = (Element) it.next();  
                    String k = e.getName();  
                    String v = "";  
                    List children = e.getChildren();  
                    if(children.isEmpty()) {  
                        v = e.getTextNormalize();  
                    } else {  
                        v = getChildrenText(children);  
                    }  
                      
                    m.put(k, v);  
                }  
                  
                //关闭流  
                in.close();  
                  
                return m;  
            }  
            
          public static String getChildrenText(List children) {  
                StringBuffer sb = new StringBuffer();  
                if(!children.isEmpty()) {  
                    Iterator it = children.iterator();  
                    while(it.hasNext()) {  
                        Element e = (Element) it.next();  
                        String name = e.getName();  
                        String value = e.getTextNormalize();  
                        List list = e.getChildren();  
                        sb.append("<" + name + ">");  
                        if(!list.isEmpty()) {  
                            sb.append(getChildrenText(list));  
                        }  
                        sb.append(value);  
                        sb.append("</" + name + ">");  
                    }  
                }  
                  
                return sb.toString();  
            }  
           
          /**
           * 验证回调签名
           * @return
           */
          public static boolean isTenpaySign(Map<String, String> map,String key) {
        	  String charset = "utf-8";
        	  String signFromAPIResponse = map.get("sign");
        	  if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
        		  System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
        		  return false;
        	  }
        	  System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
        	  //过滤空 设置 TreeMap
        	  SortedMap<String,String> packageParams = new TreeMap<String, String>();
        	  for (String parameter : map.keySet()) {
        		  String parameterValue = map.get(parameter);
        		  String v = "";
        		  if (null != parameterValue) {
        			  v = parameterValue.trim();
        		  }
        		  packageParams.put(parameter, v);
        	  }
    
                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=" + key);
    
                //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
    
                //算出签名
                String resultSign = "";
                String tobesign = sb.toString();
                if (null == charset || "".equals(charset)) {
                    resultSign = MD5Util.MD5Encode(tobesign, "UTF-8").toUpperCase();
                } else {
                    resultSign = MD5Util.MD5Encode(tobesign, charset).toUpperCase();
                }
                String tenpaySign = packageParams.get("sign").toUpperCase();
                return tenpaySign.equals(resultSign);
          }
    
        public static String createLinkString(Map<String, String> params) {
              List<String> keys = new ArrayList<String>(params.keySet());
              Collections.sort(keys);
              String prestr = "";
              for (int i = 0; i < keys.size(); i++) {
                  String key = keys.get(i);
                  String value = params.get(key)==null ? "" : params.get(key);
                  if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
                      prestr = prestr + key + "=" + value;
                  } else {
                      prestr = prestr + key + "=" + value + "&";
                  }
              }
              return prestr;
          }
    }  

    2:微信下单付款

public WeChatPayVO weChatPay(String token, String jsCode,Long saleOrderId, HttpServletRequest request) {
        Long customerId = miniSignerUtil.customerId(token);
        //Long customerId = 4L;
        Customer customer = customerService.getEX(customerId);
        String openId = miniAppUtil.getOpenid(jsCode);
        //String openId = "otIEG0XKBsAtJiJkZ2Hmw1FBULQ8";
        SaleOrder saleOrder = getEX(saleOrderId);
        if (saleOrder.getState()!=1)
            throw new ServiceException("订单状态发生改变,请确认后再支付!");
        PayVO payVO = new PayVO();
        if (saleOrder.getType()==1){
            payVO = goToPay(token,saleOrderId,null);
        }else{
            payVO = goToPaygene(token,saleOrderId,null);
        }
        // 调用微信接口进行支付
        WeChatPayVO json = new WeChatPayVO();
        try{
            //生成的随机字符串
            String nonce_str = StringRandomUtils.generateEnNum(32);
            //商品名称
            String body = WeChatPay.BODY;
            //获取本机的ip地址
            String spbill_create_ip = IpUtil.getIpAddr(request);
            String orderNo = saleOrder.getOrderNumber();
            String money = "2";
            /*if (System.getProperty("profile").equals("prod")){
                money = payVO.getPayMoney().multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString();//支付金额,单位:分,这边需要转成字符串类型,否则后面的签名会失败
            }else{
                money = "2";
            }*/
            SortedMap<String, Object> packageParams = new TreeMap<String, Object>();
            packageParams.put("appid", coreProperties.getMiniapp().getAppid());
            packageParams.put("mch_id", coreProperties.getWechat().getMchid());
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", orderNo);//商户订单号
            packageParams.put("total_fee", money);//支付金额,这边需要转成字符串类型,否则后面的签名会失败
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", coreProperties.getWechat().getNotifyUrl());
            packageParams.put("trade_type", WeChatPay.TRADETYPE);
            packageParams.put("openid", openId);

            // 除去数组中的空值和签名参数
            // packageParams = PayUtil.paraFilter(packageParams);
            //String prestr = PayCommonUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串

            //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
            String mysign = PayCommonUtil.createSign("utf-8",packageParams, coreProperties.getWechat().getKey()).toUpperCase();
            log.info("=======================第一次签名:" + mysign + "=====================");

            //拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
            String xml = "<xml>" + "<appid>" + coreProperties.getMiniapp().getAppid() + "</appid>"
                    + "<body><![CDATA[" + body + "]]></body>"
                    + "<mch_id>" + coreProperties.getWechat().getMchid() + "</mch_id>"
                    + "<nonce_str>" + nonce_str + "</nonce_str>"
                    + "<notify_url>" + coreProperties.getWechat().getNotifyUrl() + "</notify_url>"
                    + "<openid>" + openId + "</openid>"
                    + "<out_trade_no>" + orderNo + "</out_trade_no>"
                    + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
                    + "<total_fee>" + money + "</total_fee>"
                    + "<trade_type>" + WeChatPay.TRADETYPE + "</trade_type>"
                    + "<sign>" + mysign + "</sign>"
                    + "</xml>";

            System.out.println("调试模式_统一下单接口 请求XML数据:" + xml);

            //调用统一下单接口,并接受返回的结果
            String result = PayCommonUtil.paraFilter(WeChatPay.pay_url, "POST", xml);

            log.info("调试模式_统一下单接口 返回XML数据:" + result);

            // 将解析结果存储在HashMap中
            Map map = PayCommonUtil.doXMLParse(result);

            String return_code = (String) map.get("return_code");//返回状态码

            //返回给移动端需要的参数
            SortedMap<String, Object> response = new TreeMap<String, Object>();
            if(return_code == "SUCCESS" || return_code.equals(return_code)){
                // 业务结果
                String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
                response.put("appId", coreProperties.getMiniapp().getAppid());
                response.put("nonceStr", nonce_str);
                response.put("package", "prepay_id=" + prepay_id);
                response.put("signType", WeChatPay.SIGNTYPE);
                Long timeStamp = System.currentTimeMillis() / 1000;
                response.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误

               // String stringSignTemp = "appId=" + coreProperties.getWeChat().getAppid() + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id+ "&signType=" + WxPayConfig.SIGNTYPE + "&timeStamp=" + timeStamp;
                //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                String paySign = PayCommonUtil.createSign("utf-8",response, coreProperties.getWechat().getKey()).toUpperCase();
                log.info("=======================第二次签名:" + paySign + "=====================");

                response.put("paySign", paySign);
                //业务逻辑代码
            }else{
                throw new ServiceException("微信支付失败!");
            }
            response.put("appid", coreProperties.getMiniapp().getAppid());

            json.setSuccess(true);
            json.setResponse(response);
        }catch(Exception e){
            e.printStackTrace();
            json.setSuccess(false);
            json.setMsg("微信支付失败");
        }
        return json;

    }

回调接口(在回调接口中处理支付成功的业务逻辑)

@RequestMapping(value="/wxNotify")
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文:" + notityXml);

        Map map = PayCommonUtil.doXMLParse(notityXml);
        log.info(map);
        String returnCode = (String) map.get("return_code");
        if("SUCCESS".equals(returnCode)){
            //验证签名是否正确
            if(PayCommonUtil.isTenpaySign(map,coreProperties.getWechat().getKey())){
                /**此处添加自己的业务逻辑代码start**/
                String saleOrderCode = (String) map.get("out_trade_no");
                log.info(saleOrderCode);
                // 通过订单编号查找订单
                SaleOrder saleOrder = saleOrderService.searchOne("orderNumber",saleOrderCode).orElseThrow(()->new ServiceException("未查到订单信息"));
                if (saleOrder.getState()!=2){
                    // 订单状态没发生改变才调用下面的业务逻辑(因为微信回回调多次,避免多次调用业务逻辑代码)
                    log.info(saleOrder.toString());
                    Customer customer = customerService.getEX(saleOrder.getCustomerId());
                    // 付款金额
                    Integer total_fee = Integer.valueOf((String) map.get("total_fee"));
                    BigDecimal realTotalMoney = new BigDecimal(total_fee).divide(new BigDecimal(100));
                    //更新订单信息
                    saleOrder.setRealTotalMoney(realTotalMoney);
                    saleOrder.setState(2);
                    saleOrder.setPayTime(LocalDateTime.now());
                    saleOrderService.updateEX(saleOrder);
                    // 荔芝币功能以及积分
                    lizhiCoinItemService.payLizhiCoin(saleOrder.getId());
                    // 更新商品付款人数
                    commodityService.changePayTime(saleOrder.getId());
                    // 支付日志
                    payLogsService.createEX(PayLogs.builder().payMoney(saleOrder.getRealTotalMoney()).customerId(saleOrder.getCustomerId()).customerName(saleOrder.getCustomerName())
                            .saleOrderCode(saleOrderCode).build());
                    OrderTracking orderTracking = OrderTracking.builder().tracking("支付订单").saleOrderId(saleOrder.getId()).build();
                    orderTrackingService.createEX(orderTracking);
                    // 操作者信息
                    SaleOrderOperate saleOrderOperate = SaleOrderOperate.builder().saleOrderId(saleOrder.getId()).orderStatus(2).operater(StringUtils.isNotBlank(customer.getName())?customer.getName():customer.getMobile()).payStatus(2).transStatus(1).remarks("付款成功").build();
                    saleOrderOperateService.createEX(saleOrderOperate);
                }
                /**此处添加自己的业务逻辑代码end**/
                //通知微信服务器已经支付成功
                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> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

3:订单退款(退款回调接口有没有无所谓)

public Map<String,String> wechatRefund(BigDecimal refundMoney,BigDecimal totalMoney,String saleOrderCode){
        //生成的随机32位字符串
        String nonce_str = PayCommonUtil.getRandomString(32);
        String out_refund_no = UUID.randomUUID().toString();//商户退款单号
        //签名算法
        SortedMap<String, Object> paramMap = new TreeMap<String, Object>();
        paramMap.put("appid", coreProperties.getMiniapp().getAppid());
        paramMap.put("mch_id", coreProperties.getWechat().getMchid());
        paramMap.put("nonce_str", nonce_str);
        paramMap.put("out_trade_no", saleOrderCode);
        paramMap.put("out_refund_no", out_refund_no);
        paramMap.put("total_fee", totalMoney.intValue());
        paramMap.put("refund_fee", refundMoney.intValue());
        paramMap.put("notify_url", coreProperties.getWechat().getNotifyUrl());
        String sign = PayCommonUtil.createSign("utf-8",paramMap,coreProperties.getWechat().getKey()).toUpperCase();
        //获取最终待发送的数据
        String requestXml = "<xml>" +
                "<appid>" + coreProperties.getMiniapp().getAppid() + "</appid>" +
                "<mch_id>" + coreProperties.getWechat().getMchid() + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<out_trade_no>" + saleOrderCode + "</out_trade_no>" +
                "<out_refund_no>" + out_refund_no + "</out_refund_no>" +
                "<total_fee>" + totalMoney.intValue() + "</total_fee>" +
                "<refund_fee>" + refundMoney.intValue() + "</refund_fee>" +
                "<notify_url>" + coreProperties.getWechat().getNotifyUrl() + "</notify_url>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";
        //定义本函数返回值:
        Map<String,String> returnMap = new HashMap<>();
        try {
            //建立连接并发送数据
            String result = PayCommonUtil.httpsRequest2(WeChatPay.REFUND,coreProperties.getWechat().getMchid(),"POST",requestXml,coreProperties.getWechat().getMchid(),coreProperties.getWechat().getClientCert());
            //解析返回的xml
            Map<String,String> resultMap = PayCommonUtil.doXMLParse(result);
            log.info("退款返回xml:"+resultMap);
            //退款返回标志码
            String return_code = resultMap.get("return_code").toString();
            String result_code = resultMap.get("result_code").toString();
            if("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)){
                //code...
                returnMap.put("status","success");
                returnMap.put("msg","发起微信退款成功");
                returnMap.put("transactionId",resultMap.get("transaction_id"));
                returnMap.put("outTradeNo",resultMap.get("out_trade_no"));
                returnMap.put("outRefundNo",resultMap.get("out_refund_no"));
                // 退款成功

                return returnMap;
            }else if(return_code.equals("SUCCESS") && result_code.equals("FAIL")){
                returnMap.put("status","fail");
                returnMap.put("msg","微信原路返款失败!");
                return returnMap;
            }else{
                returnMap.put("status","fail");
                returnMap.put("msg","微信原路返款失败!");
                return returnMap;
            }
        }catch (Exception e){
            e.printStackTrace();
            returnMap.put("status","fail");
            returnMap.put("msg",e.getMessage());
            return returnMap;
        }
    }

4:商户提现(暂未调试)

/**
     * 提现
     * @param orderCode 提现订单号
     * @param openId 微信用户openid
     * @param amount 提现金额
     * @param remarks 处理备注
     * @param request request
     */
    public void getCash(String orderCode,String openId,Integer amount,String remarks,HttpServletRequest request){
        String nonce_str = PayCommonUtil.getRandomString(32);
        //签名算法
        SortedMap<String, Object> paramMap = new TreeMap<String, Object>();
        paramMap.put("mch_appid", coreProperties.getMiniapp().getAppid());
        paramMap.put("mchid", coreProperties.getWechat().getMchid());
        paramMap.put("nonce_str", nonce_str);
        paramMap.put("partner_trade_no",orderCode);
        paramMap.put("openid",openId);
        paramMap.put("check_name","NO_CHECK");
        paramMap.put("amount", amount);
        paramMap.put("desc",remarks);
        paramMap.put("spbill_create_ip", IpUtil.getIpAddr(request));
        String sign = PayCommonUtil.createSign("utf-8",paramMap,coreProperties.getWechat().getKey()).toUpperCase();
        //获取最终待发送的数据
        String requestXml = "<xml>" +
                "<mch_appid>" + coreProperties.getMiniapp().getAppid() + "</appid>" +
                "<mchid>" + coreProperties.getWechat().getMchid() + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<partner_trade_no>" + orderCode + "</out_trade_no>" +
                "<openid>" + openId + "</out_refund_no>" +
                "<check_name>" + "NO_CHECK" + "</total_fee>" +
                "<amount>" + amount + "</refund_fee>" +
                "<desc>" + remarks + "</notify_url>" +
                "<spbill_create_ip>" + IpUtil.getIpAddr(request) + "</refund_fee>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";
        //定义本函数返回值:
        Map<String,String> returnMap = new HashMap<>();
        try{
            String result = PayCommonUtil.paraFilter(WeChatPay.TRANSFEI,"POST",requestXml);
            log.info("调试提现接口 返回XML数据:" + result);
            // 将解析结果存储在HashMap中
            returnMap = PayCommonUtil.doXMLParse(result);
            String return_code = (String) returnMap.get("return_code");//返回状态码
            if ("SUCCESS".equals(return_code)){
                // 提现成功 #TODO 提现成功后的逻辑
            }else{
                // 提现失败
                // 失败原因
                String err_code_des = (String) returnMap.get("err_code_des");//错误代码
                throw new ServiceException(err_code_des);
            }
        }catch (Exception e){
            throw new ServiceException("提现失败,请重试!");
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值