java实现微信公众号的支付技能

java实现微信公众号的支付技能

前沿,环境的配置:
1.首先,这个项目需要有对应的公众号,以及在公众平台上注册公众号支付的权限,也就是开通微信商户平台,
并且将商户平台和对用的公众号进行绑定
至此开发人员将获取到必要字段:

2.其次,开发人员需要登录微信商户平台,添加支付授权目录,
还需要在商户平台设置授权域名:xx.xxx.cn (注:这个域名相当于Java项目运行时的ip:端口号)
具体参考微信开发文档:微信开发文档

然后,我们开始代码开发部分:
第一步:微信授权功能,不详细讲解,不清楚可以看我的–>另一篇微信授权登录的文章
主要是为了获取微信用户的openid
我们还需要知道的静态参数有:
参数: //下面是支付需要的一些参数,设为静态,方便不同方法调用
private static String APPID = “wxxxxxxxxxxxxxxxxxxxx51”; //微信公众号id
private static String SECRET = “2xxxxxxxxxxxxxxxxxc”; //微信公众号密钥id
private static String MCHID = “1xxxxxxxxx”; //微信支付商户号
private static String KEY = “xxxxxxxxxxxxxxxxxxxxx”; //商户号对应的密钥
private static String UNURL = “https://api.mch.weixin.qq.com/pay/unifiedorder”; //微信统一下单链接
private static String TRADETYPE=“JSAPI”;//jsapi代表公众号支付
public static String NOTIFY_URL_DC = “https://xxx.com/projects/wx/home/weixin_notify”;//回调函数url
public static String CREATE_IP = “122.110.110.110”;//发起支付ip(微信白名单的ip)
第二步:获取prepay_id
//这个是统一下单接口调用方法

public Map<String,Object> weixin_pay(CarOrder carOrder) {
           try {							
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();    //填装支付参数map
			String out_trade_no = Order.getOrderNo();    //订单号
			String openid = Order.getCustomerId();       //openid
			String key =KEY ;              // 商户号对应的密钥
			String currTime = PayToolUtil.getCurrTime();//时间戳
			String nonce_str = currTime.substring(8, currTime.length()) + PayToolUtil.buildRandom(4) + "";  //随机字符串
			String trade_type = TRADETYPE;                //微信调用接口的方式(js)
			
			String money = Order.getTotalPrice();               //支付金额
			double total_price = Double.parseDouble(money)*100;    //转换成该币种的最小单位
			int totalPrice = (int)total_price;
			
			//接着就将这些需要传递给微信的参数进行装载,然后生成xml格式数据
			packageParams.put("appid", APPID );   //微信公众号id
			packageParams.put("mch_id", MCHID); // 商户号
			packageParams.put("nonce_str", nonce_str);//随机字符串
			packageParams.put("total_fee", String.valueOf(totalPrice)); //价格的单位为分
			packageParams.put("spbill_create_ip", CREATE_IP); // 获取发起电脑 ip
			packageParams.put("notify_url", NOTIFY_URL_DC);    // 回调接口方法(后台)
			packageParams.put("out_trade_no",out_trade_no);        // 商户订单号
			packageParams.put("body", "订单微信支付");            // 商品或支付单简要描述
			packageParams.put("trade_type", trade_type);
			packageParams.put("openid", openid);
			packageParams.put("attach", out_trade_no);
			String sign = this.createSign("UTF-8", packageParams, key);//根据商户的支付密钥和参数生成签名
			packageParams.put("sign", sign);        //将签名也放入到map集合中
			
			//接着就是将这些参数全部转换成xml格式数据
			String requestXML=this.toxml(packageParams);
			//然后就可以想微信发送请求,获取prepare_id了
			String resXml=this.sendRequest(UNURL,requestXML,null);
			//然后将微信返回的xml数据转换成map格式进行获取
			Map map = XMLUtil4jdom.doXMLParse(resXml);

			最后将map中的数据添加key生成签名,返回到页面进行调取支付页面
				SortedMap<Object,Object> returnMap = new TreeMap<Object, Object>();

			if(returnMap !=null){
				if(map.get("return_code").equals("SUCCESS")){    //返回成功
					if(map.get("result_code").equals("SUCCESS")){
						returnMap.put("package","prepay_id="+map.get("prepay_id"));
						String timestamp = currTime.substring(0, 10);
						returnMap.put("appId",WeixinConfig.APPID);
						returnMap.put("timeStamp",timestamp);
						returnMap.put("nonceStr",nonce_str);
						returnMap.put("signType","MD5");
						String paySign = this.createSign("UTF-8", returnMap, key);
						returnMap.put("paySign",paySign);
						resultMap.put("returnMap",returnMap);
						resultMap.put("status",1);
					}
				}else{
					resultMap.put("status",0);
					resultMap.put("errorMsg","微信支付失败");
				}
			}

第三步:页面获取参数后调用微信支付,输密码付钱
data里面装载上文的entity,也就是需要里面的参数进行调用输密码支付页面

function doWxpay(data) {
        if (data.code == 0) {
            myTip.show("1", "success");
            $('#msg').fadeIn(100, function () {
                $.toast(data.msg, 'forbidden', 2000);
            })
        } else {
            myTip.show("2", "success");
            //支付
            if (typeof WeixinJSBridge == "undefined") {
                myTip.show("3", "success");
                if (document.addEventListener) {
                    document.addEventListener('WeixinJSBridgeReady',
                            jsApiCall(data), false);
                } else if (document.attachEvent) {
                    document.attachEvent('WeixinJSBridgeReady',
                            jsApiCall(data));
                    document.attachEvent('onWeixinJSBridgeReady',
                            jsApiCall(data));
                }
            } else {
                myTip.show("4", "success");
                jsApiCall(data);
            }
        }
    }
    function jsApiCall(data) {
        myTip.show("5", "success");
        WeixinJSBridge.invoke('getBrandWCPayRequest', {
            "appId" : data.returnMap.appId, //公众号名称
            "timeStamp" : data.returnMap.timeStamp, //时间戳,自1970年以来的秒数
            "nonceStr" :data.returnMap.nonceStr, //随机串
            "package" : data.returnMap.package,
            "signType" : data.returnMap.signType, //微信签名方式
            "paySign" :data.returnMap.paySign
        }, function(res) {
            if(res.err_msg == "get_brand_wcpay_request:ok"){ //支付成功
                $.toast("支付成功",2000);
            } else if(res.err_msg == "get_brand_wcpay_request:cancel"){ //支付取消
                $.toast("支付取消",'forbidden', 2000);
            }else if(res.err_msg == "get_brand_wcpay_request:fail"){ //支付失败
                alert(JSON.stringify(res));
                $.toast("支付失败",'forbidden', 2000);
            }
        });
    }

以下是前文用到的两个工具方法

    public static String toxml(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 = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

//将xml转换成map集合
public static Map<String,String> xmlToMap(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if(null == strxml || "".equals(strxml)) {
            return null;
        }

        Map<String, String> m = new HashMap<String, String>();
        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 = XMLUtil4jdom.getChildrenText(children);
            }
           m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }

//像微信携带参数发送请求			
  public static String sendRequest(String urlStr, String data, String contentType){  
        BufferedReader reader = null;  
        try {  
            URL url = new URL(urlStr);  
            URLConnection conn = url.openConnection();  
            conn.setDoOutput(true);  
            conn.setConnectTimeout(CONNECT_TIMEOUT);  
            conn.setReadTimeout(CONNECT_TIMEOUT);  
            if(contentType != null)  
                conn.setRequestProperty("content-type", contentType);  
            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);  
            if(data == null)  
                data = "";  
            writer.write(data);   
            writer.flush();  
            writer.close();    
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));  
            StringBuilder sb = new StringBuilder();  
            String line = null;  
            while ((line = reader.readLine()) != null) {  
                sb.append(line);  
                sb.append("\r\n");  
            }
            return sb.toString();  
        } catch (IOException e) {  
            //logger.error("Error connecting to " + urlStr + ": " + e.getMessage());  
        } finally {  
            try {  
                if (reader != null)  
                    reader.close();  
            } catch (IOException e) {  
            }  
        }  
        return null;  
    }  


//创建签名的方法
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 = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }

猜你喜欢

转载自blog.csdn.net/yang_zeng/article/details/87883021
今日推荐