微信公众号支付,为什么你找了那么多关于微信支付博客案例依然跑不通......两步带你完成支付,看完还做不出来你找我

看完还做不出来你找我

看文档是件烦人的事,你现在做支付,我就假设你肯定已经尝试过了微信公众号的基本接口,例如:获取token,获取用户信息,......那你就会明白,公众号的文档是需要逐字的去看,一扫而过,只会让你坠入深坑

很多博客甚至视频,讲解支付的时候,都是一律跟着文档走,和看文档的区别不大,我个人犯错一般比较低级,另类,奇葩.....下面内容我会提出一些不常见的问题

正题

前置条件

1.商户平台==>产品中心==>开发者配置==>公众号支付,设置支付授权目录,有说明注意看.(tomcat配置了访问域名直接访问项目.例:域名/控制器/方法名.action(http://xxx.xxx.com/index/pay.action),应该配成:域名/控制器/(http://xxx.xxx.com/index/))

2.都做支付了,其余的就不废话了,该配的自己都配了就行

3.明确商户key,公众号的配置比较多,这个商户key是指在商户平台安装证书时设置的api秘钥.记住这个key才是你后面两次签名用到的key,明确这个key你才算真正的做了支付的第一步(帐户中心——API安全——设置API密钥——提示会影响——确认——新密钥——手机验证码——登录密码)

大概流程

很多人不愿意看文档,没关系,我明确的告诉你,只需要看这两个地方就足够了,第一步:统一下单.第二步微信H5调起支付

第一步:统一下单

这个是啥意思就不过多解释了,结果就是做完这步,你能获取到一个prepay_id(预支付交易会话标识),公众号赋予的含义我们不去管它,只要知道做完这两步你就能支付成功了就可以

首先我们都知道我们需要传一个xml字符串给微信,什么参数要传,什么参数不传文档都有讲,但是其中openid在做公众号支付的时候是必须要传的

完成统一下单的决定性技巧

照做文档:

这是文档中对于签名的说明或者说是帮助,强烈建议,把他这三步复制照做,对比结果(签名)是否和文档一致跟着做一遍,统一下单你就完成了一半了

 上面这步昨晚,其实应该已经成功了,剩下的就是注意事项了(坑)

统一下单注意事项

1.参数尽量使用<![CDATA[]]>包裹,提供的代码已经实现,直接用就行

2.body(商品描述),当你在本地一切代码就绪,放上服务器确失败了,提示参数校验失败,很有可能是你在body中传入了中文(当然,还有个detail应该也能传中文,只不过我没有尝试传这个参数),而你的服务环境导致中文乱码了(微信验证你传过去的参数是乱码后的中文内容),解决方法当然是修改服务器环境了

3.签名类型,生成签名重要的就是明确最后传入的key,根据之前调用接口的经验.开始我以为是开发者秘钥或者api秘钥(没有仔细看文档,大概意思是误以为key是使用在某个设置时我选择了采用SHA-512生成的秘钥),那么就得采用SHA-512方式去做这个签名,其实人家写的很清楚,只支持MD5和HMAC-SHA256方式.

最重要的是,我在做的过程中,使用SHA-512生成签名,竟然成功了,成功的获取到了prepay_id,继而导致后续唤起支付一错再错.在后续唤起支付时提示请求参数校验错误,个人感觉,这也说明了第二步唤起支付,会去找到第一步统一下单时的参数,并且再次对参数校验.

所以,一点要对照文档,按他的提示去做,很多人都对微信文档不满,但就这次支付经历来说,个人感觉人家文档说的很精准,并没有不对的地方,包括上面说的openid不能为空的事,人家说明也很对啊,只有在trade_type=JSAPI时(即公众号支付),此参数必传,所以分情况的话当然不能说openid是必填项

4.必填参数中,不必非要传真实值的参数有(随便填):

4.1  spbill_create_ip   终端IP

4.2  notify_url     通知地址

第二步:微信H5调起支付

这步没啥好说的,文档有,复制粘贴,然后ok

微信H5调起支付注意事项

还是那句注意看文档

1.参与签名参数为:appId、timeStamp、nonceStr、package、signType,请注意参数大小写。

只要照着文档做这步出错的几率还是很小的,只有一小部分的朋友不知道怎么从哪写的这几个参数,没有注意大小写

2.有些朋友说前台获取支付参数时,必须要写在onBridgeReady()方法里面,不然获取不到,应该是不正确的,所有的js像普通项目一样正常写,没有啥可特别注意的(我的就写在外面了,专门放到方法里测试过,也可以,没区别)

此时一切完毕效果图

码一步到位

这个是主类

package cn.kdzy.controller.pay;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.kdzy.wechat.utils.AnalysisXml;
import cn.kdzy.wechat.utils.VisitUrl;

  /**
  * @author zl 2018年4月29日上午9:27:33
  */

@Controller
@Scope("prototype")
@RequestMapping("/pay")
public class PayZL {

    @ResponseBody
    @RequestMapping("/jsapi")
    public Map<String, String> jsapi(Model model, HttpSession session, HttpServletRequest request) throws Exception {
        String out_trade_no = UUID.randomUUID().toString().replaceAll("-", "");
        System.out.println("商户订单号:" + out_trade_no);

        Map<String, String> signMap = new HashMap<>();
        signMap.put("appid", "你的APPID");
        signMap.put("mch_id", "你的商户id");
        signMap.put("nonce_str", "FB3930C5C94002262724CFEEAB6335EE");
        signMap.put("body", "xk-在线咨询费用");
        signMap.put("out_trade_no", out_trade_no);
        signMap.put("total_fee", "1");
        signMap.put("spbill_create_ip", getIpAddress(request));
        signMap.put("notify_url", "http://vip.xxx.com/xxx/xxx.action");
        signMap.put("trade_type", "JSAPI");
        signMap.put("openid", "换成要支付的openid");

        String sign = generateSignature(signMap, "你的商户key", "MD5");
        System.out.println("签名:" + sign);

        Map<String, String> map = new HashMap<>();
        map.put("appid", "你的APPID");
        map.put("mch_id", "你的商户id");
        map.put("nonce_str", "FB3930C5C94002262724CFEEAB6335EE");
        map.put("sign", sign);
        map.put("body", "xk-在线咨询费用");
        map.put("out_trade_no", out_trade_no);
        map.put("total_fee", "1");
        map.put("spbill_create_ip", getIpAddress(request));
        map.put("notify_url", "http://vip.xxx.com/xxx/xxx.action");
        map.put("trade_type", "JSAPI");
        map.put("openid", "换成要支付的openid");

        String str = new String(AnalysisXml.MapToXMLNoHead(map));
        System.out.println(str);

        String sendPost = VisitUrl.sendHttps("https://api.mch.weixin.qq.com/pay/unifiedorder",str);
        System.out.println("统一下单返回结果:" + sendPost);

        Map<String, String> xmlToMap = AnalysisXml.xmlToMap(sendPost);

        if (null != xmlToMap.get("prepay_id")) {
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            System.out.println("h5支付时间戳:" + timestamp);

            Map<String, String> signMap2 = new HashMap<>();
            signMap2.put("appId", "你的APPID");
            signMap2.put("nonceStr", "FB3930C5C94002262724CFEEAB6335EE");
            signMap2.put("package", "prepay_id=" + xmlToMap.get("prepay_id"));

            System.out.println("map中预支付id:" + xmlToMap.get("prepay_id"));

            signMap2.put("signType", "MD5");
            signMap2.put("timeStamp", timestamp);

            String signxx = generateSignature(signMap2, "你的商户key", "MD5");
            System.out.println("h5支付签名:" + signxx);

            Map<String, String> result = new HashMap<>();
            result.put("appId", "你的APPID");
            result.put("nonceStr", "FB3930C5C94002262724CFEEAB6335EE");
            result.put("pack", "prepay_id=" + xmlToMap.get("prepay_id"));
            result.put("paySign", signxx);
            result.put("signType", "MD5");
            result.put("timeStamp", timestamp);

            System.out.println("返回给前台的最终结果:" + result.toString());
            return result;

        }
        return null;

    }

    public static String generateSignature(final Map<String, String> data, String key, String signType)
            throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals("sign")) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if ("MD5".equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        } else if ("HMACSHA256".equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

    /**
     * 生成 MD5
     *
     * @param data
     *            待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 生成 HMACSHA256
     * 
     * @param data
     *            待处理数据
     * @param key
     *            密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 获取远程主机ip
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

这两个是上面用到的工具类

package cn.kdzy.wechat.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * 解析xml并转存至map 解析map并转存至xml
 * 
 * @author zl 2017年9月9日上午11:52:01
 */
public class AnalysisXml {

    public static void main(String[] args) {
        String xml = "<xml><ToUserName><![CDATA[toUser]]></ToUserName>\r\n"
                + "<FromUserName><![CDATA[FromUser]]></FromUserName>\r\n" + "<CreateTime>123456789</CreateTime>\r\n"
                + "<MsgType><![CDATA[event]]></MsgType>\r\n" + "<Event><![CDATA[subscribe]]></Event>\r\n"
                + "<EventKey><![CDATA[qrscene_123123]]></EventKey>\r\n" + "<Ticket><![CDATA[TICKET]]></Ticket>\r\n"
                + "</xml>";

        String temp = "<xml>    <ToUserName><![CDATA[gh_1643056df06d]]></ToUserName>    <Encrypt><![CDATA[1p0AdRxH3ohITPxDuUGniR3B9imeHJ/R4ASmA9+clxStNYYmIfLdy4aX1d/fYFduTjadMfXYmb0hoVra6YhSp3ssEPK1CWOGmecV65ETgwzAIFf1R+rtaPecTqQrbTvvFOAoKzgybM1RTSRqCr42wW/X12fQVquSomLnfrGlSyBit8wC/AetdZmOQ0QxgilsLgDGtAeEQgUveJA+9wrGFaXVZJxJpvjFk5TzXjGwjHKuRWxu4buetMweOFA/gvgnSex9Kioi2lQxuYZQo9k66Kc+6aF4EGIn4pxGLZcZKUbslbt0iZSQ77lLL7udzZ1PBMvT36sg+0ZrfcBA6egl5Wd3ulnEOYmVOZsCLLJpnDxx2UkIIksi3ggRk0EbvuiDQvRJQJGtRrsIAM4S1lWKxq6IRzP04pAinNN9zMrrWn0=]]></Encrypt></xml>";

        Map<String, String> map = xmlToMap(temp);
        for (Entry<String, String> string : map.entrySet()) {
            System.out.println("key:" + string.getKey() + "\t值:" + string.getValue());
        }
    }

    /**
     * xml 转 Map
     * 
     * @param xml
     * @return
     */
    public static Map<String, String> xmlToMap(String xml) {

        Map<String, String> map = new HashMap<String, String>();
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (doc == null)
            return map;
        Element root = doc.getRootElement();
        for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
            Element e = (Element) iterator.next();
            map.put(e.getName(), e.getText());
        }

        return map;
    }

    /**
     * Map 转 XML 无xml头
     * 
     * @param map
     * @return
     */
    public static byte[] MapToXMLNoHead(Map map) {

        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        mapToXMLTest2(map, sb);
        sb.append("</xml>");

        try {
            return sb.toString().getBytes("UTF-8");
        } catch (Exception e) {
        }

        return null;
    }
    
    /**
     * Map 转 XML 有xml头
     * 
     * @param map
     * @return
     */
    public static byte[] MapToXMLHaveHead(Map map) {

        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xml>");
        mapToXMLTest2(map, sb);
        sb.append("</xml>");

        try {
            return sb.toString().getBytes("UTF-8");
        } catch (Exception e) {
        }

        return null;
    }

    private static void mapToXMLTest2(Map map, StringBuffer sb) {

        Set set = map.keySet();
        for (Iterator it = set.iterator(); it.hasNext();) {
            String key = (String) it.next();
            Object value = map.get(key);
            if (null == value)
                value = "";
            if (value.getClass().getName().equals("java.util.ArrayList")) {
                ArrayList list = (ArrayList) map.get(key);
                sb.append("<" + key + "><![CDATA[");
                for (int i = 0; i < list.size(); i++) {
                    HashMap hm = (HashMap) list.get(i);
                    mapToXMLTest2(hm, sb);
                }
                sb.append("]]></" + key + ">");

            } else {
                if (value instanceof HashMap) {
                    sb.append("<" + key + "><![CDATA[");
                    mapToXMLTest2((HashMap) value, sb);
                    sb.append("]]></" + key + ">");
                } else {
                    sb.append("<" + key + "><![CDATA[" + value + "]]></" + key + ">");
                }

            }
        }
    }
}
package cn.kdzy.wechat.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * http访问url
 * 
 * @author zl 2017年9月1日上午9:27:33
 */
public class VisitUrl {
    public static void main(String[] args) {
        // 发送 GET 请求
        // String s=VisitUrl.sendGet("http://...com"+"p1=1&p2=2");
        // System.out.println(s);

        // 发送 POST 请求
        String sr = VisitUrl.sendPost(
                "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx126aa425932c5906&redirect_uri=https://www.baidu.com&response_type=code&scope=snsapi_base&state=1#wechat_redirect",
                "");
        System.out.println(sr);
    }

    /**
     * 简单访问url获取结果 http
     * 
     * @author zl 20172017年9月1日上午10:52:18
     * @param url
     * @return String
     */
    public static String visitUrl(String url) {
        // 访问url
        String jsonResulet = "";
        try {
            String str;
            URL u = new URL(url);
            InputStream is = u.openStream();
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            if (br.ready()) {
                while ((str = br.readLine()) != null) {
                    jsonResulet += str;
                }
            }
            br.close();
            isr.close();
            is.close();
        } catch (MalformedURLException e) {
            // url地址错误
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return jsonResulet;
    }

    /**
     * 向指定URL发送GET方法的请求 http
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        String urlNameString = null;
        BufferedReader in = null;
        try {
            if (null == param) {
                urlNameString = url;
            } else {
                urlNameString = url + "?" + param;
            }
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("Accept-Charset", "utf-8");
            connection.setRequestProperty("contentType", "utf-8");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            // Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            // for (String key : map.keySet()) {
            // System.out.println(key + "--->" + map.get(key));
            // }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            // System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求 http
     * 
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            // System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * https POST 访问
     */
    public static String sendHttps(String url, String param) throws IOException {

        SSLContext ctx = null;
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SSLSocketFactory ssf = ctx.getSocketFactory();

        URL u = new URL(url);
        HttpsURLConnection httpsConn = (HttpsURLConnection) u.openConnection();
        httpsConn.setSSLSocketFactory(ssf);
        httpsConn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
        // 设置通用的请求属性
        httpsConn.setRequestProperty("accept", "*/*");
        httpsConn.setRequestProperty("Accept-Charset", "utf-8");
        httpsConn.setRequestProperty("contentType", "utf-8");
        httpsConn.setRequestProperty("connection", "Keep-Alive");
        httpsConn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

        // 发送POST请求必须设置如下两行
        httpsConn.setDoInput(true);
        httpsConn.setDoOutput(true);
        // 获取URLConnection对象对应的输出流
        out = new PrintWriter(new OutputStreamWriter(httpsConn.getOutputStream(), "utf-8"));
        // 发送请求参数
        out.print(param);
        // flush输出流的缓冲
        out.flush();
        // 定义BufferedReader输入流来读取URL的响应
        in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream(), "UTF-8"));
        String line;
        while ((line = in.readLine()) != null) {
            result += line;
        }
        if (out != null) {
            out.close();
        }

        return result;
    }

    private static class DefaultTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    /**
     * 从url下载图片并返回其byte[]
     * 
     * @author zl 2018年1月16日 上午11:24:53
     * @param urlPath
     * @return byte[]
     */
    public static byte[] getImageFromURL(String urlPath) {
        byte[] data = null;
        InputStream is = null;
        HttpURLConnection conn = null;
        try {
            URL url = new URL(urlPath);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            // conn.setDoOutput(true);
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(6000);
            is = conn.getInputStream();
            // conn.getContentType();
            if (conn.getResponseCode() == 200) {
                data = readInputStream(is);
            } else {
                data = null;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            conn.disconnect();
        }
        return data;
    }

    /**
     * 读取InputStream数据,转为byte[]数据类型
     * 
     * @param is
     *            InputStream数据
     * @return 返回byte[]数据
     */
    public static byte[] readInputStream(InputStream is) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = -1;
        try {
            while ((length = is.read(buffer)) != -1) {
                baos.write(buffer, 0, length);
            }
            baos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] data = baos.toByteArray();
        try {
            is.close();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 根据url下载文件,参数(文件网址,存文件的本地地址)
     * 
     * @author zl 2018年1月16日 上午11:11:59
     * @param urlString
     * @param filePath
     * @return
     */
    public static Boolean downloadFile(String urlString, String filePath) {
        // 构造URL
        URL url;
        try {
            url = new URL(urlString);
            // 打开连接
            URLConnection con;
            try {
                con = url.openConnection();
                // 输入流
                InputStream is = con.getInputStream();
                // 1K的数据缓冲
                byte[] bs = new byte[1024];
                // 读取到的数据长度
                int len;
                // 输出的文件流
                OutputStream os = new FileOutputStream(filePath);
                // 开始读取
                while ((len = is.read(bs)) != -1) {
                    os.write(bs, 0, len);
                }
                // 完毕,关闭所有链接
                os.close();
                is.close();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将输入流转换为字符串
     * 
     * @param input
     *            输入流
     * @return 转换后的字符串
     */
    public static String inputToStr(InputStream input) {
        String result = "";
        if (input != null) {
            byte[] array = new byte[1024];
            StringBuffer buffer = new StringBuffer();
            try {
                for (int index; (index = (input.read(array))) > -1;) {
                    buffer.append(new String(array, 0, index, "UTF-8"));
                }
                result = buffer.toString();
            } catch (IOException e) {
                e.printStackTrace();
                result = "";
            }
        }
        return result;
    }

}

页面调起支付(不需要引入什么微信的js,在微信客户端浏览器打开方法已经内置了)

html

<div class="doctorList">
  <ul>
    <li>
      <div class="col-xs-12">
        <div class="smallAbout" style="text-align: center;" id="chushihua">
        访问后台初始化参数
        </div>
      </div>
    </li>
    <li><div>===========================</div></li>
    <li>
      <div class="col-xs-12">
        <div class="smallAbout" style="text-align: center;" id="annu">
        发起支付
        </div>
      </div>
    </li>
  </ul>
</div>

js

<script type="text/javascript">
         var appId=''
         var nonceStr=''
         var pack=''
         var paySign=''
         var signType=''
         var timeStamp=''
        /* 1获取参数 */
        $('#chushihua').click(function(){
            $.ajax({
                url:'${pageContext.request.contextPath }/pay/jsapi.action',
                type:'POST',
                dataType:'json',
                async:false,
                //data:{},
                success : function(jsonobj) {
                    alert('后台返回json数据:'+JSON.stringify(jsonobj))
                    if (null!=jsonobj) {
                        appId=jsonobj.appId
                        nonceStr=jsonobj.nonceStr
                        pack=jsonobj.pack    
                        paySign=jsonobj.paySign
                        signType=jsonobj.signType
                        timeStamp=jsonobj.timeStamp
                    }else{
                        alert('后台返回空数据')
                    }
                },
                error : function() {
                
                }
          })
        })
        
        /* 2支付 */
            $('#annu').click(function(){
                pay();
            })
            
            function pay(){
                if (typeof WeixinJSBridge == "undefined"){
                   if( document.addEventListener ){
                       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                   }else if (document.attachEvent){
                       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
                       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                   }
                }else{
                   onBridgeReady();
                }
            }
            
            function onBridgeReady(){
                   alert('支付前打印package:'+pack)
                   WeixinJSBridge.invoke(
                      'getBrandWCPayRequest', {
                               "appId":appId,
                               "timeStamp":timeStamp
                               "nonceStr":nonceStr,
                               "package":pack,
                               "signType":"MD5",
                               "paySign":paySign,
                      },
                       function(res){     
                            alert(JSON.stringify(res))
                            if(res.err_msg == "get_brand_wcpay_request:ok"){  
                                alert("微信支付成功!");
                            }else if(res.err_msg == "get_brand_wcpay_request:cancel"){  
                                alert("用户取消支付!");
                            }else if(res.err_msg == "get_brand_wcpay_request:fail"){  
                                alert("支付失败!");
                            }else{
                                alert("支付失败!");
                            }
                       }
                   ); 
                }
        </script>

猜你喜欢

转载自www.cnblogs.com/cnsdhzzl/p/8970641.html