zoukankan      html  css  js  c++  java
  • 微信支付(公众号支付接入方式)

    首先准备几个工具类:HttpRequest请求工具类,MD5加密工具类,随机数生成工具类,签名生成工具类,xml格式转换类

    package net.tiantianup.wap.utils.weixinpay;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.ssl.SSLContexts;
    import org.apache.http.util.EntityUtils;
    
    import javax.net.ssl.SSLContext;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.*;
    import java.security.cert.CertificateException;
    
    /**
     * Created by LV on 2016/4/11 0011.
     * Email:LvLoveYuForever@gmail.com
     */
    public class HttpRequest {
        /**
         * 请求工具类(使用httpclient)
         * @param requestUrl 请求的API的URL
         * @param postData  需要发送的内容
         * @param certLocalPath PKCS12证书地址
         * @param certPassword  证书密码
         * @return
         * @throws CertificateException
         * @throws NoSuchAlgorithmException
         * @throws KeyStoreException
         * @throws IOException
         * @throws KeyManagementException
         * @throws UnrecoverableKeyException
         */
        public static String httpRequest(String requestUrl, String postData, String certLocalPath, String certPassword) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException, UnrecoverableKeyException {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(certLocalPath));//加载本地的证书进行https加密传输
            try {
                keyStore.load(instream, certPassword.toCharArray());//设置证书密码
            } catch (CertificateException e) {
                e.printStackTrace();
            } finally {
                instream.close();
            }
    
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, certPassword.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
    
            HttpPost httpPost=new HttpPost(requestUrl);
    
            //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
            StringEntity postEntity = new StringEntity(postData, "UTF-8");
            httpPost.addHeader("Content-Type", "text/xml");
            httpPost.setEntity(postEntity);
    
            //设置请求器的配置
            httpPost.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(3000).build());
    
            HttpResponse response=httpclient.execute(httpPost);
            HttpEntity entity=response.getEntity();
            String result= EntityUtils.toString(entity);
    
            return result;
        }
    }
    package net.tiantianup.wap.utils.weixinpay;
    
    import java.security.MessageDigest;
    
    /**
     * MD5加密工具
     */
    public class MD5 {
        private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
                "8", "9", "a", "b", "c", "d", "e", "f"};
    
        /**
         * 转换字节数组为16进制字串
         * @param b 字节数组
         * @return 16进制字串
         */
        public static String byteArrayToHexString(byte[] b) {
            StringBuilder resultSb = new StringBuilder();
            for (byte aB : b) {
                resultSb.append(byteToHexString(aB));
            }
            return resultSb.toString();
        }
    
        /**
         * 转换byte到16进制
         * @param b 要转换的byte
         * @return 16进制格式
         */
        private static String byteToHexString(byte b) {
            int n = b;
            if (n < 0) {
                n = 256 + n;
            }
            int d1 = n / 16;
            int d2 = n % 16;
            return hexDigits[d1] + hexDigits[d2];
        }
    
        /**
         * MD5编码
         * @param origin 原始字符串
         * @return 经过MD5加密之后的结果
         */
        public static String MD5Encode(String origin) {
            String resultString = null;
            try {
                resultString = origin;
                MessageDigest md = MessageDigest.getInstance("MD5");
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultString;
        }
    
    }
    package net.tiantianup.wap.utils.weixinpay;
    
    import java.util.Random;
    
    /**
     * 随机数自动生成器
     */
    public class RandomStringGenerator {
    
        /**
         * 获取一定长度的随机字符串
         * @param length 指定字符串长度
         * @return 一定长度的字符串
         */
        public static String getRandomStringByLength(int length) {
            String base = "abcdefghijklmnopqrstuvwxyz0123456789";
            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();
        }
    
    }
    package net.tiantianup.wap.utils.weixinpay;
    
    import org.apache.log4j.Logger;
    import org.xml.sax.SAXException;
    
    import javax.xml.parsers.ParserConfigurationException;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Map;
    
    /**
     * Created by LV on 2016/4/7 0007.
     * Email:LvLoveYuForever@gmail.com
     */
    public class SignUtil {
        /**
         * 签名算法
         * @param o 要参与签名的数据对象
         * @return 签名
         * @throws IllegalAccessException
         */
        public static Logger log=Logger.getLogger(SignUtil.class);
    
        public static String getSign(Object o,String key) throws IllegalAccessException {
            ArrayList<String> list = new ArrayList<String>();
            Class cls = o.getClass();
            Field[] fields = cls.getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                if (f.get(o) != null && f.get(o) != "") {
                    list.add(f.getName() + "=" + f.get(o) + "&");
                }
            }
            int size = list.size();
            String [] arrayToSort = list.toArray(new String[size]);
            Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < size; i ++) {
                sb.append(arrayToSort[i]);
            }
            String result = sb.toString();
            result += "key=" + key;
            log.info("Sign Before MD5:" + result);
            result = MD5.MD5Encode(result).toUpperCase();
            log.info("Sign Result:" + result);
            return result;
        }
    
        /**
         * 将map对象进行签名
         * @param map
         * @return
         */
        public static String getSign(Map<String,Object> map,String key){
            ArrayList<String> list = new ArrayList<String>();
            for(Map.Entry<String,Object> entry:map.entrySet()){
                if(entry.getValue()!=""){
                    list.add(entry.getKey() + "=" + entry.getValue() + "&");
                }
            }
            int size = list.size();
            String [] arrayToSort = list.toArray(new String[size]);
            Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < size; i ++) {
                sb.append(arrayToSort[i]);
            }
            String result = sb.toString();
            result += "key=" + key;
            log.info("Sign Before MD5:" + result);
            result = MD5.MD5Encode(result).toUpperCase();
            log.info("Sign Result:" + result);
            return result;
        }
    
        /**
         * 从API返回的XML数据里面重新计算一次签名
         * @param responseString API返回的XML数据
         * @return
         */
        public static String getSignFromResponseString(String responseString,String key) throws IOException, SAXException, ParserConfigurationException {
            Map<String,Object> map = XMLParser.getMapFromXML(responseString);
            //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
            map.put("sign","");
            //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
            return SignUtil.getSign(map,key);
        }
    
        /**
         * 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
         * @param responseString API返回的XML数据字符串
         * @return API签名是否合法
         * @throws ParserConfigurationException
         * @throws IOException
         * @throws SAXException
         */
        public static boolean checkIsSignValidFromResponseString(String responseString,String key) throws ParserConfigurationException, IOException, SAXException {
    
            Map<String,Object> map = XMLParser.getMapFromXML(responseString);
            log.info(map.toString());
    
            String signFromAPIResponse = map.get("sign").toString();
            if(signFromAPIResponse=="" || signFromAPIResponse == null){
                log.info("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
                return false;
            }
            log.info("服务器回包里面的签名是:" + signFromAPIResponse);
            //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
            map.put("sign","");
            //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
            String signForAPIResponse = SignUtil.getSign(map,key);
    
            if(!signForAPIResponse.equals(signFromAPIResponse)){
                //签名验不过,表示这个API返回的数据有可能已经被篡改了
                log.info("API返回的数据签名验证不通过,有可能被第三方篡改!!!");
                return false;
            }
           log.info("恭喜,API返回的数据签名验证通过!!!");
            return true;
        }
    }
    package net.tiantianup.wap.utils.weixinpay;
    import org.apache.log4j.Logger;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.SAXException;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    /**
     * Created by LV on 2016/4/7 0007.
     * Email:LvLoveYuForever@gmail.com
     */
    public class XMLParser {
    
        private static Logger log=Logger.getLogger(XMLParser.class);
        /**
         * 将返回的xml的数据转换成map
         * @param xmlString
         * @return
         * @throws ParserConfigurationException
         * @throws IOException
         * @throws SAXException
         */
        public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
    
            //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream is =  Util.getStringStream(xmlString);
            Document document = builder.parse(is);
    
            //获取到document里面的全部结点
            NodeList allNodes = document.getFirstChild().getChildNodes();
            Node node;
            Map<String, Object> map = new HashMap<String, Object>();
            int i=0;
            while (i < allNodes.getLength()) {
                node = allNodes.item(i);
                if(node instanceof Element){
                    map.put(node.getNodeName(),node.getTextContent());
                }
                i++;
            }
            return map;
    
        }
    
        /**
         * 商户处理后同步返回给微信参数,转换成xml类型
         * @param return_code
         * @param return_msg
         * @return
         */
        public static String setXML(String return_code,String return_msg) {
            return "<xml><return_code><![CDATA[" + return_code +
                    "]]></return_code><return_msg><![CDATA[" +
                    return_msg + "]]></return_msg></xml>";
    
    
        }
    
        public static String mapToXML(Map<String,Object> map){
            //将map类型的请求参数装换成XML格式
            StringBuilder sb=new StringBuilder();
            sb.append("<xml>");
            Iterator it=map.entrySet().iterator();
            while (it.hasNext()){
                Map.Entry entry= (Map.Entry) it.next();
                String k= (String) entry.getKey();
                String v= (String) entry.getValue();
                sb.append("<"+k+">"+v+"</"+k+">");
            }
            sb.append("</xml>");
            log.info("转换xml格式:"+sb.toString());
            return sb.toString();
        }
    
    }

    然后支付具体业务需按照需求来定制,下面的业务是本人开发的项目需求里的例子:

    /**
         * 异步发起提交订单
         * @param courseApplyId
         * @param request
         * @return
         */
        @ResponseBody
        @RequestMapping(value = "/course/courseWxPayAjax/{courseApplyId}" ,method = RequestMethod.GET)
        public String courseWxPayAjax(@PathVariable("courseApplyId") String courseApplyId,HttpServletRequest request) throws IOException, SAXException, ParserConfigurationException, IllegalAccessException {
            //判断是否是微信客户端
            String userAgent = request.getHeader("User-Agent");
            if (userAgent.indexOf("MicroMessenger") > 0){
                //获取当前用户信息
                Subject currentUser = SecurityUtils.getSubject();//获取当前用户
                Session session = currentUser.getSession();
                CurrentUserModel currentUserModel = JSONObject.parseObject(session.getAttribute("user").toString(),CurrentUserModel.class);
                //获取申请的课程信息
                CourseApply courseApply=courseApplyService.getCourseApplyByCourseAppId(courseApplyId);
                //获取课程信息
                Course course=courseService.getCourseByCourseId(courseApply.getCourseId());
    
                /**微信支付请求参数*/
                Map<String,Object> requestParm=new TreeMap<>();
                requestParm.put("appid","wx0071d459ab95ac0f");//公众账号ID
                requestParm.put("attach",courseApplyId);//附加数据我们带上支付的课程申请ID,方便我们在微信支付回调后对数据库进行操作
                requestParm.put("body",course.getCourseName());//商品描述:课程名
                requestParm.put("mch_id","商户号》填上申请的商户号");//商户号
                requestParm.put("nonce_str",RandomStringGenerator.getRandomStringByLength(32));//随机字符串
                requestParm.put("notify_url","http://wap.zhaorenxue.com/course/paySuccess");//接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
                requestParm.put("openid",currentUserModel.getOpenId());//trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
                requestParm.put("out_trade_no",RandomStringGenerator.getRandomStringByLength(32));//out_trade_no商户订单号
                requestParm.put("spbill_create_ip", IPTools.getIpAddr(request));//APP和网页支付提交用户端ip
                requestParm.put("total_fee",String.valueOf((int)(course.getCoursePrice()*100)));//订单总金额,微信支付是1分钱为单位的
                requestParm.put("trade_type","JSAPI");//JSAPI--公众号支付
                String sign= SignUtil.getSign(requestParm,key);//生成签名
                requestParm.put("sign",sign);
    
                /**微信支付请求参数*/
                log.info("微信支付请求参数:"+requestParm.toString());
    
                //将需要发送给API的参数转换成规定的xml类型
                String requestXml= XMLParser.mapToXML(requestParm);
                /**请求参数转换成xml格式*/
                log.info("请求参数转换成xml格式:"+requestXml);
    
                /**调用微信请求的API*/
                //证书在服务器上面的路径
                String certLocalPath="/var/www/wap/WEB-INF/classes/apiclient_cert.p12";//证书在服务器上的地址,此应用部署的服务器上证书的具体地址------------------
    
                String responseXml=null;
                            try {
                        responseXml= HttpRequest.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder",requestXml,certLocalPath,"证书密码,自己根据具体的密码填写");
                        //返回的xml格式数据
                        log.info("返回的xml格式数据:"+responseXml);
    
                } catch (Exception e) {
                    return null;//如果请求失败,说明请求过程发生了错误,我们在返回的页面做处理
                }
    
               /* //模拟返回的xml数据
                String responseXml="<xml>" +
                        "   <return_code><![CDATA[SUCCESS]]></return_code>" +
                        "   <return_msg><![CDATA[OK]]></return_msg>" +
                        "   <appid><![CDATA[wx00]]></appid>" +
                        "   <mch_id><![CDATA[131]]></mch_id>" +
                        "   <nonce_str><![CDATA["+requestParm.get("nonce_str")+"]]></nonce_str>" +
                        "   <sign><![CDATA["+sign+"]]></sign>" +
                        "   <result_code><![CDATA[SUCCESS]]></result_code>" +
                        "   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>" +
                        "   <trade_type><![CDATA[JSAPI]]></trade_type>" +
                        "</xml>";*/
    
                /**将返回的xml转换map格式*/
                Map<String,Object> responseMap=XMLParser.getMapFromXML(responseXml);
                /**返回数据转换成map格式*/
                log.info("返回数据转换成map格式:"+responseMap.toString());
    
                /**查看签名是否被修改*/
                if(SignUtil.checkIsSignValidFromResponseString(responseXml,key)){
                    /**没有修改就做下一步判断*/
                    //result_code成功时才会返回prepay_id
                    if(responseMap.get("result_code").toString().equalsIgnoreCase("SUCCESS")){
                        //添加发起时间
                        CourseApply courseApplyTime=new CourseApply();
                        courseApplyTime.setApplyId(courseApplyId);
                        courseApplyTime.setPrePayTime(new Date());
                        courseApplyService.updateCourseApply(courseApplyTime);
    
                        //给微信JSAPI准备发送数据
                        Map<String,Object> parameters=new TreeMap<>();
                        parameters.put("appId","此处按申请的账号填写");
                        parameters.put("timeStamp",Long.toString(new Date().getTime()));
                        parameters.put("nonceStr", RandomStringGenerator.getRandomStringByLength(32));
                        parameters.put("package","prepay_id="+responseMap.get("prepay_id").toString());
                        parameters.put("signType","MD5");
                        String paySign=SignUtil.getSign(parameters,key);
                        parameters.put("paySign",paySign);//用签名算法算出来的
                        //当前微信浏览器的版本,5.0以上才支持微信支付
                        char agent=userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);
                        parameters.put("agent",new String(new char[]{agent}));
                       // parameters.put("agent","5.5");//测试时写死
                        parameters.put("sendUrl","course/checkPaySuccess");//支付成功的回调地址----我们回调时可以查询一下数据库,是否支付成功,如果没有支付成功,返回到支付页面再支付---TODO
    
                        /**为支付JSAPI准备的数据*/
                        log.info("为支付JSAPI准备的数据:"+parameters.toString());
    
                        return JSONObject.toJSONString(parameters);
                    }
                }
            }
    
            return null;
        }

    代码里的商户号,appid,证书的路径,证书密码都按申请的账号填写其中的签名key需要在微信商户号里自行设置

    回调函数方法:

    /**
         * 微信支付完成后,通知的支付结果notify_url,由微信服务器请求的异步地址(LV)
         */
        @ResponseBody
        @RequestMapping(value = "/course/paySuccess")
        public void paySuccess(HttpServletRequest request, HttpServletResponse response) throws IOException, ParserConfigurationException, SAXException {
    
            InputStream inputStream=request.getInputStream();
    
            ByteArrayOutputStream outStream=new ByteArrayOutputStream();
            byte[] buffer=new byte[1024];
            int len;
            while((len=inputStream.read(buffer))!=-1){
                outStream.write(buffer,0,len);
            }
            outStream.close();
            inputStream.close();
    
            String result=new String(outStream.toByteArray(),"utf-8");
    
            /**通知的支付结果notify_url返回的数据*/
            log.info("notify_url返回的数据:"+result);
    
            Map<String,Object> map= XMLParser.getMapFromXML(result);//返回数据转换成map
    
            log.info("notify_url返回的数据转换map格式:"+map.toString());
    
    
            if(map.get("result_code").toString().equalsIgnoreCase("SUCCESS")){
                //TODO 对数据库进行操作
                //获取放入attach的课程申请ID
                String courseApplyId=map.get("attach").toString();
    
                CourseApply courseApply=new CourseApply();
                courseApply.setApplyId(courseApplyId);
                courseApply.setApplyStatus(1);
                courseApply.setPayType(0);
                courseApply.setPayStatus(1);
                courseApply.setPayTime(new Date());
                courseApply.setPayment("WXOPENPAY");//微信公众平台支付
                courseApply.setOutTradeNo(map.get("out_trade_no").toString());
                courseApply.setTransactionId(map.get("transaction_id").toString());
                courseApply.setAppid(map.get("appid").toString());
                courseApply.setMchId(map.get("mch_id").toString());
                //将课程的支付的几个参数设置成已支付的状态
                courseApplyService.updateCourseApply(courseApply);
    
                //告诉微信服务器,支付完成
                response.getWriter().write(XMLParser.setXML("SUCCESS","OK"));
    
            }
        }

    jsAPI中支付成功后的检查数据库的动作

     /**
         * sendUrl 在jsAPI中如果支付成功,我们再次验证一下,是否支付成功
         * @param model
         * @param courseApplyId
         * @return
         */
        @RequestMapping(value = "/course/checkPaySuccess/{courseApplyId}",method = RequestMethod.GET)
        public String checkPaySuccess(Model model,@PathVariable("courseApplyId") String courseApplyId){
            log.info("支付成功,检验数据库是否插入数据成功,已支付就跳转到支付成功页面");
            CourseApply courseApply=courseApplyService.getCourseApplyByCourseAppId(courseApplyId);
            int payStatus=courseApply.getPayStatus();
            model.addAttribute("courseApply",courseApply);
            if (payStatus==1){
    
                //使用返现码,生成返现记录(add by zzy)
                //获取当前用户信息
                Subject currentUser = SecurityUtils.getSubject();//获取当前用户
                Session session = currentUser.getSession();
    
                if(session.getAttribute("user")!=null) {
                    CurrentUserModel currentUserModel = JSONObject.parseObject(session.getAttribute("user").toString(), CurrentUserModel.class);
    
                    List<UserCoupon> list = userCouponService.getCouponByUserId(currentUserModel.getUserId());
                    if (list != null && list.size() > 0) {
                        UserCoupon coupon = list.get(0);
    
                        User user = userService.getUserByUserId(currentUserModel.getUserId());
                        Course course = courseService.getCourseByCourseId(courseApply.getCourseId());
    
                        CashBackRecord cashBackRecord = new CashBackRecord();
                        cashBackRecord.setRecordId(UUID.randomUUID().toString());
                        cashBackRecord.setCouponNum(coupon.getCouponCode());
                        cashBackRecord.setMoney(course.getCoursePrice() / 10);//返现10%
                        cashBackRecord.setCreateTime(new Date());
                        cashBackRecord.setUserName(user.getNickname());
                        cashBackRecord.setUserId(user.getUserId());
                        cashBackRecord.setCourseId(course.getCourseId());
    
                        coupon.setIsUsed(1);
                        user.setMoney(user.getMoney() + course.getCoursePrice() / 10);
    
                        //生成返现记录
                        cashBackRecordService.saveCashBackRecord(cashBackRecord);
                        //更新余额
                        userService.updateUser(user);
                        //更改优惠码使用状态
                        userCouponService.updateCoupon(coupon);
                    }
                }
    
                //数据库有支付记录,返回到成功页面
                return "pay_result";
            }
            //数据库没有支付记录,返回错误页面
            return "pay_error";
        }

    在jsp中用ajax发起支付,页面中要引入jsapi自己的js文件

     <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
        <script>
            $(function($) {
                $("a[name='wxpay']").click(
                        function () {
                            //alert("${ctx}/course/courseWxPayAjax/${courseApplyId}");
                            $.ajax({
                                type: "GET",
                                url: "${ctx}/course/courseWxPayAjax/${courseApplyId}",
                                dataType: "JSON",
                                success: function(data){
                                    //alert(data);
                                    //alert("${ctx}/"+data.sendUrl+"/${courseApplyId}");
                                    if(parseInt(data.agent)<5){
                                        alert("你的微信版本低于5.0,不能使用微信支付");
                                        return;
                                    }
                                    //调用微信支付控件完成支付
                                    function onBridgeReady(){
                                        WeixinJSBridge.invoke(
                                                'getBrandWCPayRequest',{
                                                    "appId":data.appId,     //公众号名称,由商户传入
                                                    "timeStamp":data.timeStamp,         //时间戳,自1970年以来的秒数
                                                    "nonceStr":data.nonceStr, //随机串
                                                    "package":data.package,
                                                    "signType":data.signType,         //微信签名方式:
                                                    "paySign":data.paySign //微信签名
                                                },
                                                function(res){// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                                                    //alert("支付成功"+res.err_msg);
                                                    if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                                                        //alert("判断成功");
                                                        //跳转到设置的支付成功页面url
                                                        window.location.href="${ctx}/"+data.sendUrl+"/${courseApplyId}";
                                                    }else {
                                                        //alert("fail");
                                                        // window.location.href="";//跳转到支付页面继续支付
                                                    }
                                                }
                                        );
                                    }
                                    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();
                                    }
    
                                }
                            });
                        }
                )
            })
    
        </script>

    注意:在微信支付平台中设置支付目录,其中有测试目录和正式目录,如果是测试目录,只有添加进白名单的微信号才能完成支付,使用正式目录,只要是微信用户都可以完成支付。

    ${ctx}/course/courseWxPayAjax/${courseApplyId}

    那么设置的支付目录是:
    域名/${ctx}/course
  • 相关阅读:
    【软件测试部署基础】maven的认识
    测试管理那些事[组建测试团队的思考]
    Django 框架基本操作(二)
    测试人员的工作开展方式
    产品管理基础知识
    项目经理与职能经理的区别
    python 面向对象(二)
    Python 常用方法和模块的使用(time & datetime & os &random &sys &shutil)-(六)
    python基本案例实现
    JAVA基础——集合浅析
  • 原文地址:https://www.cnblogs.com/LvLoveYuForever/p/5465051.html
Copyright © 2011-2022 走看看