• 微信公众号支付H5-java版代码


    1,工具类

    package net.jeeshop.core.util;
    
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;
    
    import java.io.*;
    import java.math.BigDecimal;
    import java.net.ConnectException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.*;
    
    /**
     */
    public class PayCommonUtil {
        //微信参数配置
        public static String API_KEY = "xxxxxxxxxxxxxx";
        // APPID
        public static String APPID = "wx323323333333";
        // 商户ID
        public static String MCH_ID = "123232323";
    
        /**
         * 发起支付
         *
         * @param orderId 订单ID
         * @param amount  钱(元)
         * @param body    订单说明
         * @param openId  会员openID
         * @param ip      会员IP
         * @param url     回调URl
         * @return
         */
        public static SortedMap<String, String> pay(String orderId, BigDecimal amount, String body, String openId, String ip, String url) {
            String error = "";
            String prepayId = getPrepayId(orderId, amount, body, openId, url, ip);
    
            SortedMap<String, String> map = new TreeMap<String, String>();
            map.put("appId", PayCommonUtil.APPID);
            map.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            map.put("nonceStr", PayCommonUtil.getRandomString(32));
    
            if (prepayId == null) {
                error = "验签失败!";
                map.put("error", error);
            }
    
            map.put("package", "prepay_id=" + prepayId);
            map.put("signType", "MD5");
            String sign = PayCommonUtil.createSign("UTF-8", map);
            map.put("paySign", sign);
            return map;
        }
    
        /**
         * 返回微信预支付prepay_id
         *
         * @param orderId    订单ID
         * @param amount     钱(元)
         * @param body       订单说明
         * @param openid     会员openID
         * @param notify_url 回调URl
         * @param ip         会员IP
         * @return
         */
        public static String getPrepayId(String orderId, BigDecimal amount, String body, String openid, String notify_url, String ip) {
            SortedMap<String, String> para = new TreeMap<String, String>();
            para.put("appid", PayCommonUtil.APPID);
            para.put("mch_id", PayCommonUtil.MCH_ID);
            para.put("nonce_str", PayCommonUtil.getRandomString(32));
            para.put("body", body);
            para.put("out_trade_no", orderId);
            para.put("fee_type", "CNY");
    
            BigDecimal total = amount.multiply(new BigDecimal(100));
            java.text.DecimalFormat df = new java.text.DecimalFormat("0");
    
            para.put("total_fee", df.format(total));
            para.put("spbill_create_ip", ip);
            para.put("notify_url", notify_url);
            para.put("trade_type", "JSAPI");
            para.put("openid", openid);
            String sign = createSign("UTF-8", para);
            para.put("sign", sign);
            String requestXML = PayCommonUtil.getRequestXml(para);
            String result = PayCommonUtil.httpsRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", requestXML);
            Map<String, String> map = null;
            try {
                map = PayCommonUtil.doXMLParse(result);
    
    // 返回信息
                if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
                    return map.get("prepay_id");
                } else {
                    return null;
                }
            } catch (JDOMException e) {
                return null;
            } catch (IOException e) {
                return null;
            }
        }
    
        //随机字符串生成
        private static String getRandomString(int 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组装
        private static String getRequestXml(SortedMap<String, String> 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();
        }
    
        // 生成签名
        private static String createSign(String characterEncoding, SortedMap<String, String> parameters) {
            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=" + API_KEY);
            String sign = MD5.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
            return sign;
        }
    
        /**
         * 验证回调签名
         */
        public static boolean isTenpaySign(Map<String, String> map) {
            String charset = "utf-8";
            String signFromAPIResponse = map.get("sign");
    // API返回的数据签名数据不存在,有可能被第三方篡改!!!
            if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
                return false;
            }
    
    //过滤空 设置 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=" + API_KEY);
    //算出签名
            String resultSign = "";
            String tobesign = sb.toString();
            if (null == charset || "".equals(charset)) {
                resultSign = MD5.MD5Encode(tobesign, charset).toUpperCase();
            } else {
                resultSign = MD5.MD5Encode(tobesign, charset).toUpperCase();
            }
            String tenpaySign = ((String) packageParams.get("sign")).toUpperCase();
            return tenpaySign.equals(resultSign);
        }
    
        // 请求方法
        private static String httpsRequest(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) {
            } catch (Exception e) {
            }
            return null;
        }
    
        //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;
        }
    
        /**
         * 循环查找子节点
         *
         * @param children
         * @return
         */
        private 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();
        }
    }
    

     

    2,action

    package net.jeeshop.web.action.member.pay;
    
    import com.alibaba.fastjson.JSON;
    import net.jeeshop.core.AllinpayMain.StringUtils;
    import net.jeeshop.core.front.SystemManager;
    import net.jeeshop.core.util.PayCommonUtil;
    import net.jeeshop.services.front.account.bean.Account;
    import net.jeeshop.services.front.order.OrderService;
    import net.jeeshop.services.front.order.bean.Order;
    import net.jeeshop.services.front.orderpay.OrderpayService;
    import net.jeeshop.services.front.orderpay.bean.Orderpay;
    import net.jeeshop.web.util.LoginUserHolder;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.math.BigDecimal;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.SortedMap;
    import java.util.TreeMap;
    
    /**
     * Created by Administrator on 2017-02-24.
     */
    @Controller("WeiXinPayAction")
    @RequestMapping("/member/webchatPay")
    public class WeiXinPayAction {
    
        @Autowired
        private OrderService orderService;
        @Autowired
        private OrderpayService orderpayService;
    
        public static String wxnotify = "/api/json/money/wxpay/succ";
    
        @RequestMapping(value = "pay")
        @ResponseBody
        public String pay(HttpServletRequest request) throws Exception {
            HashMap<String, Object> map = new HashMap<String, Object>();
            Account acc = LoginUserHolder.getLoginAccount();
            if (LoginUserHolder.getLoginAccount() == null) {
                map.put("error","用户未登陆");
                return JSON.toJSONString(map);
            }
    
            String orderId = request.getParameter("orderId");
    
            // 没有订单ID
            if(StringUtils.isEmpty(orderId)){
                map.put("error","没有订单ID");
                return JSON.toJSONString(map);
            }
    
            Order order = orderService.selectById(orderId);
            if (order == null) {
                map.put("error","根据订单号查询不到订单信息!");
                return JSON.toJSONString(map);
            }
    
            // 订单状态不是未支付
            if(Order.order_paystatus_y.equals(order.getPaystatus())){
                map.put("error","订单已经支付!");
                return JSON.toJSONString(map);
            }
    
            SortedMap<String, String> retMap = new TreeMap<String, String>();
            retMap = PayCommonUtil.pay(orderId, new BigDecimal(order.getPtotal()), order.getRemark(), acc.getOpenId(), request.getRemoteAddr(), SystemManager.getInstance().getSystemSetting().getWww() + "member/webchatPay/success");
    
            if(!StringUtils.isEmpty(retMap.get("error"))){
                map.put("error",retMap.get("error"));
                return JSON.toJSONString(map);
            }
    
            return JSON.toJSONString(retMap);
        }
    
        @RequestMapping(value = "success")
        @ResponseBody
        public String success(HttpServletRequest request) throws Exception {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            String resultXml = new String(outSteam.toByteArray(), "utf-8");
            Map<String, String> params = PayCommonUtil.doXMLParse(resultXml);
            outSteam.close();
            inStream.close();
            if (PayCommonUtil.isTenpaySign(params) && "SUCCESS".equals(params.get("return_code")) && "SUCCESS".equals(params.get("result_code"))) {
                String orderId = params.get("out_trade_no");
                Orderpay orderpay = new Orderpay();
                orderpay.setOrderid(orderId);
                orderpay.setPaystatus(Orderpay.orderpay_paystatus_n);
                orderpay = orderpayService.selectOne(orderpay);
    
                // 获取订单ID
                Order order = orderService.selectById(orderId);
                if (order == null) {
                    return "success";
                }
    
                // 订单状态不是未支付
                if(Order.order_paystatus_y.equals(order.getPaystatus())){
                    return "success";
                }
    
                // 更新订单状态
                orderService.orderStatus("WAIT_SELLER_SEND_GOODS",orderpay,order);
                return "success";
            } else {
                // 支付失败
                return "fail";
            }
        }
    }
    

      



    3,页面JS
    <script>
        $(function () {
            $("#btnPay").click(function () {
                if (confirm("确认支付?")) {
                    onBridgeReady();
                }
                return false;
            });
        })
    
        function onBridgeReady(){
            if (typeof(WeixinJSBridge) == "undefined"){
                if( document.addEventListener ){
                    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                }else if (document.attachEvent){
                    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                }
            }
    
            $.ajax({
                dataType: "json",
                url: "${basepath}/member/webchatPay/pay",
                type: "POST",
                data: {orderId: "${payInfo.WIDout_trade_no!""}"},
                success: function (data) {
                    if (data.error != null && data.error != "") {
                        alert(data.error);
                        return;
                    }
                    else {
                        alert("appId:" + data.appId + ",timeStamp:" + data.timeStamp + ",nonceStr:" + data.nonceStr + ",package:" + data.package + "signType:" + data.signType + ",paySign:" + data.paySign);
                        // 微信支付
                        wxPay(data.appId ,data.timeStamp ,data.nonceStr ,data.package ,data.signType ,data.paySign);
                    }
                },
                error: function (data) {
                    alert("支付启动错误");
                }
            });
        }
    
        // 微信支付
        function wxPay(appId,timeStamp,nonceStr,package,signType,paySign){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":appId,     //公众号名称,由商户传入
                    "timeStamp":timeStamp,         //时间戳,自1970年以来的秒数
                    "nonceStr":nonceStr, //随机串
                    "package":package,
                    "signType":signType,         //微信签名方式:
                    "paySign":paySign //微信签名
                },
                function(res){
                    if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                        window.location.href = "${basepath}/member/account/orders";
                    }else{
                        alert('支付失败'+res.err_msg);
                    }
                }
            );
        }
    </script>
    

      

    4,相关配置

      1,微信支付->公众号支付->支付安全目录(注意:如果是ajax调用的话写的是调用的前的页面地址)

      2,公众号设置->功能设置->JS接口安全域名

      3,公众号设置->功能设置->网页授权域名

  • 相关阅读:
    双飞翼布局 & 圣杯布局
    php正则
    面向对象-object对象
    面向对象-赋值运算
    面向对象-作用域
    js高级-面向对象
    8.5学习笔记
    10.22
    10.19
    react路由
  • 原文地址:https://www.cnblogs.com/lckblog/p/6442414.html
Copyright © 2020-2023  润新知