• 1.我们要接入js安全接口(公众号设置=》功能设置=》js安全域名) 2.引入js是必要的(http://res.wx.qq.com/open/js/jweixin-1.2.0.js) 3配置wx.config wx.config({ debug: true, // 开启调试模式,调用的所有api的...

    1.我们要接入js安全接口(公众号设置=》功能设置=》js安全域名)
    2.引入js是必要的(http://res.wx.qq.com/open/js/jweixin-1.2.0.js)
    3配置wx.config

    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名
        jsApiList: [] // 必填,需要使用的JS接口列表
    });

    公众号中有appID和appsecret然后进入(https://mp.weixin.qq.com/debug/cgi-bin/apiinfo)
    公众号中的appID和appsecret
    生成Token/access_token注意有效时间是7200秒
    Token/access_token
    采用https get方式获取jsapi_ticket
    (https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi)
    成功返回json

    {"errcode":0,
    "errmsg":"ok",
    "ticket":"LIKLcA",
    "expires_in":7200}

    获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了也就是 timestamp,nonceStr,signature这三个参数,jsApiList这个参数可以到公众号平台中附录2去找需要用哪个js就调用那个
    https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
    4.通过ready接口处理成功验证/通过error接口处理失败验证。
    成功也就可以正常调用,失败那就自己找找哪里有错误吧。

    展开全文
  • 微信支付接口调用

    2018-04-13 10:53:16
    在上周的博客中我讲了调用支付宝的接口实现支付,这周我们继续来讲一讲如何调用微信的支付接口。 在讲之前依然先给出微信的官方接口说明。官方的场景介绍图如下: 其实pc端的支付场景都差不多,用户点击按钮,...

    在上周的博客中我讲了调用支付宝的接口实现支付,这周我们继续来讲一讲如何调用微信的支付接口。
    在讲之前依然先给出微信的官方接口说明。官方的场景介绍图如下:

    这里写图片描述

    其实pc端的支付场景都差不多,用户点击按钮,生成一个二维码,微信扫码之后支付成功。要调用微信的接口,首先你需要引入微信支付的jar包,如下:

            <dependency>
                <groupId>com.github.wxpay</groupId>
                <artifactId>wxpay-sdk</artifactId>
                <version>0.0.3</version>
            </dependency>

    我把微信官方的调用示例拿来改了一下,成为了下面这个工具类:

    package com.example.ffmpeg;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import java.util.SortedMap;
    import java.util.TreeMap;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.github.wxpay.sdk.WXPay;
    
    public class WXService {
    
        private static Logger logger = LoggerFactory.getLogger(WXService.class);
        private WXPay wxpay;
        private WXPayConfigImpl config;
        private static WXService INSTANCE;  
    
        private WXService() throws Exception {
            config = WXPayConfigImpl.getInstance();
            wxpay = new WXPay(config);
        }
    
        public static WXService getInstance() throws Exception {
            if (INSTANCE == null) {
                synchronized (WXPayConfigImpl.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new WXService();
                    }
                }
            }
            return INSTANCE;
        }
    
        /**
         * 微信下單接口
         * 
         * @param out_trade_no
         * @param body
         * @param money
         * @param applyNo
         * @return
         */
        public String doUnifiedOrder(String out_trade_no, String body, Double money, String applyNo) {
            String amt = String.valueOf(money * 100);
            HashMap<String, String> data = new HashMap<String, String>();
            data.put("body", body);
            data.put("out_trade_no", out_trade_no);
            data.put("device_info", "web");
            data.put("fee_type", "CNY");
            data.put("total_fee", amt.substring(0, amt.lastIndexOf(".")));
            data.put("spbill_create_ip", config.getSpbillCreateIp());
            data.put("notify_url", config.getNotifUrl());
            data.put("trade_type", config.getTradeType());
            data.put("product_id", applyNo);
            System.out.println(String.valueOf(money * 100));
            // data.put("time_expire", "20170112104120");
    
            try {
                Map<String, String> r = wxpay.unifiedOrder(data);
                logger.info("返回的参数是" + r);
                return r.get("code_url");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info(e.getMessage());
                return null;
            }
        }
    
        /**
         * 退款 已测试
         */
        public void doRefund(String out_trade_no, String total_fee) {
            logger.info("退款时的订单号为:" + out_trade_no + "退款时的金额为:" + total_fee);
            String amt = String.valueOf(Double.parseDouble(total_fee) * 100);
            logger.info("修正后的金额为:" + amt);
            logger.info("最终的金额为:" + amt.substring(0, amt.lastIndexOf(".")));
            HashMap<String, String> data = new HashMap<String, String>();
            data.put("out_trade_no", out_trade_no);
            data.put("out_refund_no", out_trade_no);
            data.put("total_fee", amt.substring(0, amt.lastIndexOf(".")));
            data.put("refund_fee", amt.substring(0, amt.lastIndexOf(".")));
            data.put("refund_fee_type", "CNY");
            data.put("op_user_id", config.getMchID());
    
            try {
                Map<String, String> r = wxpay.refund(data);
                logger.info("退款操作返回的参数为" + r);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    
        /**
         * 微信验签接口
         * 
         * @param out_trade_no
         * @param body
         * @param money
         * @param applyNo
         * @return
         * @throws DocumentException 
         */
        public boolean checkSign(String  strXML) throws DocumentException {
             SortedMap<String, String> smap = new TreeMap<String, String>();
             Document doc = DocumentHelper.parseText(strXML);
             Element root = doc.getRootElement();
             for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
                 Element e = (Element) iterator.next();
                 smap.put(e.getName(), e.getText());
             }
             return isWechatSign(smap,config.getKey());
        }
    
    
        private boolean isWechatSign(SortedMap<String, String> smap,String apiKey) {
             StringBuffer sb = new StringBuffer();
             Set<Entry<String, String>> es = smap.entrySet();
             Iterator<Entry<String, String>> it = es.iterator();
             while (it.hasNext()) {
                 Entry<String, String> entry =  it.next();
                 String k = (String) entry.getKey();
                 String v = (String) entry.getValue();
                 if (!"sign".equals(k) && null != v && !"".equals(v) && !"key".equals(k)) {
                     sb.append(k + "=" + v + "&");
                 }
             }
             sb.append("key=" + apiKey);
             /** 验证的签名 */
             String sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
             /** 微信端返回的合法签名 */
             String validSign = ((String) smap.get("sign")).toUpperCase();
             return validSign.equals(sign);
         }
    }
    

    我把微信的下单,退款,验签操作封装到了WXService 这个工具类里面。这个类需要两个成员变量wxpay和config,分别是WXPay和WXPayConfigImpl的实例化对象。WXPay是引自微信的工具包。WXPayConfigImpl则是自己写的一个类,代码如下:

    package com.example.ffmpeg;
    
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    import com.github.wxpay.sdk.WXPayConfig;
    
    public class WXPayConfigImpl implements WXPayConfig{
    
         private byte[] certData;
            private static WXPayConfigImpl INSTANCE;
    
            private WXPayConfigImpl() throws Exception{
                String certPath = "F:\\weixin\\apiclient_cert.p12";
                File file = new File(certPath);
                InputStream certStream = new FileInputStream(file);
                this.certData = new byte[(int) file.length()];
                certStream.read(this.certData);
                certStream.close();
            }
    
            public static WXPayConfigImpl getInstance() throws Exception{
                if (INSTANCE == null) {
                    synchronized (WXPayConfigImpl.class) {
                        if (INSTANCE == null) {
                            INSTANCE = new WXPayConfigImpl();
                        }
                    }
                }
                return INSTANCE;
            }
    
            public String getAppID() {
                return "你的appid";
            }
    
            public String getMchID() {
                return "你的商户id";
            }
    
            public String getKey() {
                return "你设置的key值";
            }
    
            public String getNotifUrl() {
                return "微信通知回调的url接口";
            }
    
            public String getTradeType() {
                return "NATIVE";
            }
    
            public InputStream getCertStream() {
                ByteArrayInputStream certBis;
                certBis = new ByteArrayInputStream(this.certData);
                return certBis;
            }
    
    
            public int getHttpConnectTimeoutMs() {
                return 2000;
            }
    
            public int getHttpReadTimeoutMs() {
                return 10000;
            }
    
    //      IWXPayDomain getWXPayDomain() {
    //          return WXPayDomainSimpleImpl.instance();
    //      }
    
            public String getPrimaryDomain() {
                return "api.mch.weixin.qq.com";
            }
    
            public String getAlternateDomain() {
                return "api2.mch.weixin.qq.com";
            }
    
            public int getReportWorkerNum() {
                return 1;
            }
    
            public int getReportBatchSize() {
                return 2;
            }
    
            public String getSpbillCreateIp() {
                // TODO Auto-generated method stub
                return "192.168.1.1";
            }
    }

    可以看到,这个类实现了微信提供的WXPayConfig这个接口,里面封装了一些方法,主要是返回微信接口所需要的一些参数。值得注意的是,这里需要去读取一个文件名叫apiclient_cert.p12的证书文件。这个证书文件你可以登录微信的商户平台。在这里去下载你所需要的证书。WXPayConfigImpl 在构造方法里面去读取这个文件,所以构造方法抛了异常。因为构造器抛出异常,所以这里没有采用静态内部类而是采用双检锁的方式去实现单例。

    回到WXService这个类中,代码往下走,在WXService的构造器中对config和wxpay进行了实例化。接下来同样是用双检锁的方式实现的单例。往下走,微信的下单接口,分别传入out_trade_no(外部订单号),body(商品描述), money(付款金额), applyNo(对应微信的product_id:商品id,由商户自定义)四个参数。进入方法后第一句话String amt = String.valueOf(money * 100);是把传入的钱数乘以100,并转换成字符串。这里之所以乘以100是因为微信那边会把我们传过去的钱数除以100得到应付金额,且不能传小数,所以下面的那一句amt.substring(0, amt.lastIndexOf(“.”))就是为了把金额中的小数点去掉。往下走,new出了一个hashmap,将参数传入hashmap中,然后调用wxpay.unifiedOrder(data);下单接口下单。得到返回的map集合,从map中获得的code_url这个参数就是微信返回给我们生成二维码的字符串。这样,下单的整个流程就跑通了,现在写个测试类来测试一下。

    package com.example.ffmpeg;
    
    public class Test {
    
        public static void main(String[] args) throws Exception {
            WXService wx = WXService.getInstance();
            String QRcode = wx.doUnifiedOrder("test001", "测试下单接口", 0.01, "a123456");
            System.out.println("得到的二维码是:"+QRcode);
        }
    }

    运行结果如下图:

    这里写图片描述

    如何检验该二维码是否是正确的喃?很简单,打开百度,搜索二维码生成器,如下图所示:

    这里写图片描述

    点击进入第二个百度应用里面的进入应用,出现如下图所示:

    这里写图片描述

    选择通用文本,在中间的文本框中粘贴刚才拿到的二维码字符串,点击生成按钮,右边就会生成一个二维码了。如下:

    这里写图片描述

    当然,这只是我们后台人员测试时使用的方法,实际生产环境中前端可以用一些javascript的插件去生成二维码。

    下单接口完了之后,紧接着就是退款的方法,该方法比较简单且和下单方法大同小异,同学们自己看看注释应该可以理解了。再往后走是微信验签的方法。在讲这个方法之前,先来看看微信的回调方法:

    /**
         * 微信回调的接口
         * 
         * @param uuid
         * @return
         * @throws Exception
         */
        @RequestMapping(value = "/wxReturnPay")
        public void wxReturnPay(HttpServletResponse response, HttpServletRequest request)
                throws Exception {
    
            logger.info("****************************************wxReturnPay微信的回调函数被调用******************************");
            String inputLine;
            String notityXml = "";
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            // 微信给返回的东西
            try {
                while ((inputLine = request.getReader().readLine()) != null) {
                    notityXml += inputLine;
                }
                request.getReader().close();
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("xml获取失败");
                response.getWriter().write(setXml("fail", "xml获取失败"));
                return;
            }
            if (StringUtils.isEmpty(notityXml)) {
                logger.info("xml为空");
                response.getWriter().write(setXml("fail", "xml为空"));
                return;
            }
    
            WXService wxService = WXService.getInstance();
            if(!wxService.checkSign(notityXml)) {
                response.getWriter().write(setXml("fail", "验签失败"));
            }
            logger.info("xml的值为:" + notityXml);
            XMLSerializer xmlSerializer = new XMLSerializer(); 
            JSON json = xmlSerializer.read(notityXml);
            logger.info(json.toString());
             JSONObject jsonObject=JSONObject.fromObject(json.toString());
             UnifiedOrderRespose returnPay = (UnifiedOrderRespose) JSONObject.toBean(jsonObject, UnifiedOrderRespose.class);
             logger.info(("转换后的实体bean为:"+returnPay.toString()));
             logger.info(("订单号:"+returnPay.getOut_trade_no()+"价格:"+returnPay.getTotal_fee()));
            if (returnPay.getReturn_code().equals("SUCCESS") && returnPay.getOut_trade_no() != null
                    && !returnPay.getOut_trade_no().isEmpty()) {
                double fee = Double.parseDouble(returnPay.getTotal_fee());
                returnPay.setTotal_fee(String.valueOf(fee/100));
                logger.info("微信的支付状态为SUCCESS");
                tbPaymentRecordsService.wxPaySuccess(returnPay);
            }
        }

    在支付成功后,微信会回调该方法(回调的url是我们在调用下单接口时传过去的)。进入方法,首先会获得HttpServletRequest 实例对象的流,将他读取出来,这里面notityXml 是微信读取出来的结果,是一串xml格式的字符串,里面有各种回调的参数信息,示例返回结果如下:

    <xml>
      <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
      <attach><![CDATA[支付测试]]></attach>
      <bank_type><![CDATA[CFT]]></bank_type>
      <fee_type><![CDATA[CNY]]></fee_type>
      <is_subscribe><![CDATA[Y]]></is_subscribe>
      <mch_id><![CDATA[10000100]]></mch_id>
      <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
      <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
      <out_trade_no><![CDATA[1409811653]]></out_trade_no>
      <result_code><![CDATA[SUCCESS]]></result_code>
      <return_code><![CDATA[SUCCESS]]></return_code>
      <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
      <sub_mch_id><![CDATA[10000100]]></sub_mch_id>
      <time_end><![CDATA[20140903131540]]></time_end>
      <total_fee>1</total_fee>
    <coupon_fee><![CDATA[10]]></coupon_fee>
    <coupon_count><![CDATA[1]]></coupon_count>
    <coupon_type><![CDATA[CASH]]></coupon_type>
    <coupon_id><![CDATA[10000]]></coupon_id>
    <coupon_fee><![CDATA[100]]></coupon_fee>
      <trade_type><![CDATA[JSAPI]]></trade_type>
      <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
    </xml> 

    返回参数是这个样子的那后面自然涉及到对xml参数的解析。进入验签的方法:

    /**
         * 微信验签接口
         * 
         * @param out_trade_no
         * @param body
         * @param money
         * @param applyNo
         * @return
         * @throws DocumentException 
         */
        public boolean checkSign(String  strXML) throws DocumentException {
             SortedMap<String, String> smap = new TreeMap<String, String>();
             Document doc = DocumentHelper.parseText(strXML);
             Element root = doc.getRootElement();
             for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
                 Element e = (Element) iterator.next();
                 smap.put(e.getName(), e.getText());
             }
             return isWechatSign(smap,config.getKey());
        }
    
    
        private boolean isWechatSign(SortedMap<String, String> smap,String apiKey) {
             StringBuffer sb = new StringBuffer();
             Set<Entry<String, String>> es = smap.entrySet();
             Iterator<Entry<String, String>> it = es.iterator();
             while (it.hasNext()) {
                 Entry<String, String> entry =  it.next();
                 String k = (String) entry.getKey();
                 String v = (String) entry.getValue();
                 if (!"sign".equals(k) && null != v && !"".equals(v) && !"key".equals(k)) {
                     sb.append(k + "=" + v + "&");
                 }
             }
             sb.append("key=" + apiKey);
             /** 验证的签名 */
             String sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
             /** 微信端返回的合法签名 */
             String validSign = ((String) smap.get("sign")).toUpperCase();
             return validSign.equals(sign);
         }

    首先用dom4j的DocumentHelper解析字符串得到Document 对象,然后得到跟元素对象,遍历,将key和value值存入SortedMap中,然后将SortedMap与微信的key一同传入isWechatSign方法,在方法中讲该SortedMap用迭代器遍历,把key和value拼接成key1=value1&key2=value2这样的形式,拼接时且注意以下几点:

    ◆ 参数名ASCII码从小到大排序(字典序);
    ◆ 如果参数的值为空不参与签名;
    ◆ 参数名区分大小写;
    ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
    ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

    字符串拼接完成后,使用MD5加密,然后把得到的字符串全部转换成大写。将转换后的字符串与微信传给我们的sign参数作对比,若相同,则验签成功,若不相同,则验签失败。

    验证签名之后的方法就属于业务逻辑范畴了,每个人业务逻辑都不相同,我这里也就不再赘述了。那么到此,调用微信的最基本操作我就已经讲完了,想看如何调用支付宝的同学可以去看我的支付宝支付接口的调用这篇文章。那么这次博客就到这里,拜拜。

    展开全文
  • 文章结构 ...1、怎么调用微信高级接口微信高级接口微信普通接口的区别后台服务器可以调用微信接口微信用户进行讯息的通信,这样的行为就是在调用微信接口,这些接口是基础接口,你不需要任

    文章结构
    1、怎么调用微信高级接口
    2、调用微信高级几大实例
    2.1、调用自定义菜单接口
    2.2、客服接口
    2.3、生成二维码
    3、获取非微信功能接口,如天气网的天气接口、股票网站的信息接口。

    怎么调用微信高级接口

    微信高级接口和微信普通接口的区别

    后台服务器可以调用微信的接口与微信用户进行讯息的通信,这样的行为就是在调用微信的接口,这些接口是基础接口,你不需要任何付费行为或者身份认证行为就可以调用。但是有一些高级接口,你的微信公众号必须达到一定的权限如通过微信认证才能调用自定义菜单、微信支付等高级功能。
    不过微信公众帐号的测试号系统可以应用这些高级接口(微信支付等涉及交易的接口除外)。

    微信高级接口的调用

    微信高级接口的调用需要先调用一个token_access接口,只有先调用这个接口才能调用其它高级接口。
    如下:连通高级接口示意图
    这里写图片描述
    调用token_access需要用到appID和appsecreset(在微信公众好平台开发(一)中已经讲述这两者的由来)


    调用代码如下

    <?php
    $appid = "wxbad0b4x543aa0b5e";
    $appsecret = "ed222a84da15cd24c4bdfa5d9adbabf2";
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
    //下面是一个cURL会话过程,通过这个会话可以返回一段字符串{"access_token":"NU7Kr6v9L9TQaqm5NE3OTPctTZx797Wxw4Snd2WL2HHBqLCiXlDVOw2l-Se0I-WmOLLniAYLAwzhbYhXNjb"}
    这就是我们要获得的Access Token了。在调用高级功能接口的时候就靠它。这个过程用的时候直接引用就好,不需要深究,这个cURL系统相关函数有点多而且复杂。
    
    $ch = curl_init();//初始化
    curl_setopt($ch, CURLOPT_URL, $url);//与url建立对话
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //进行配置
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //进行配置
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//进行配置
    $output = curl_exec($ch);//执行对话,获取接口数据Access Token
    curl_close($ch);//关闭会话
    $jsoninfo = json_decode($output, true);//解码接口数据,将json格式字符串转换成php变量或数组。默认是变量,加true后是数组。
    $access_token = $jsoninfo["access_token"];
    
    ?>
    
    

    2、调用微信高级接口

    调用自定义菜单功能

      //创建一个自定义菜单的json字符串
      $jsonmenu = '{
          "button":[
          {
                "name":"关于我们",
               "sub_button":[
                {
                   "type":"click",
                   "name":"公司简介",
                   "key":"公司简介"
                },
                {
                   "type":"click",
                   "name":"社会责任",
                   "key":"社会责任"
                },
                {
                   "type":"click",
                   "name":"联系我们",
                   "key":"联系我们"
                }]
           },
           {
               "name":"产品服务",
               "sub_button":[
                {
                   "type":"click",
                   "name":"微信平台",
                   "key":"微信平台"
                },
                {
                   "type":"click",
                   "name":"微博应用",
                   "key":"微博应用"
                },
                {
                    "type":"click",
                    "name":"手机网站",
                    "key":"手机网站"
                }]
           },
           {
               "name":"技术支持",
               "sub_button":[
                {
                   "type":"click",
                   "name":"文档下载",
                   "key":"文档下载"
                },
                {
                   "type":"click",
                   "name":"技术社区",
                   "key":"技术社区"
                },
                {
                    "type":"click",
                    "name":"服务热线",
                    "key":"服务热线"
                }]
           }]
     }';
    
      $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token;//接口地址
    $result = https_request($url, $jsonmenu);//与接口建立会话
    var_dump($result);
    
    function https_request($url,$data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    //把这段代码加入到上面的调用Access Token接口的代码中就可以实现在微信公众号界面添加菜单的功能。
    
    

    当我们为微信公众号添加菜单后怎么样设置点击菜单时会出现相应的效果呢?
    这里涉及到另一种xml类型的数据传递:

    <xml>
    <ToUserName><![CDATA[gh_82479813ed64]]></ToUserName>
    <FromUserName><![CDATA[ojpX_jig-gyi3_Q9fHXQ4rdHniQs]]></FromUserName>
    <CreateTime>1392297442</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[CLICK]]></Event>
    <EventKey><![CDATA[公司简介]]></EventKey>
    </xml>
    //上面是点击click菜单的数据传递类型,数据会发送给后台服务器,然后服务器做出响应。

    菜单类型有多种,xml类型差别,详细情况可以在微信公众号平台上查看相应文档。
    *这里要说明的是只要你有微信公众号的appID和appsecret,在任何服务器空间运行这段php代码都可以进入微信服务器调用相应功能,不一定非要在进行了token验证的服务器下运行。token验证是为了后台服务器进行判断数据来源是否是来自微信服务器,与调用微信服务器的高级接口并没有多大的关联。
    php文件一定要在服务器运行才会产生效果。
    其它高级接口的调用都同调用自定义菜单一样。

    调用客服接口

    当微信用户主动发消息 给微信公众帐号的时候(包括发送信息、单击自定义菜单click事件、订阅事件、扫描二维码、支付成功事件)微信会把消息数据推送给开发者。开发者在一段时间内可以调用客服接口消息,通过post一个JSON数据包来发送消息给用户。

    $access_token = "nFX6GFsspSLBKJLgMQ3kj1YM8_FchRE7vE2ZOIlmfiCOQntZKnBwuOen2GCBpFHBYS4QLGX9fGoVfA36tftME2sRiYsKPzgGQKU-ygU7x8cgy_1tlQ4n1mhSumwQEGy6PK6rdTdo8O8GROuGE3Hiag";
    $openid = "o7Lp5t6n59DeX3U0C7Kric9qEx-Q";//微信用户都有一个openID
    

    下图所示即为openID的获取方式。
    这里写图片描述

    $data = '{
        "touser":"'.$openid.'",
        "msgtype":"text",
        "text":
        {
             "content":"Hello World"
        }
    }';//通过基础消息接口发送的数据是XML格式的,但是调用客服接口发送的数据是json数据格式,更易传输。 
    $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
    $result = https_request($url,$data);
    var_dump($result);
    
    function https_request($url,$data)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url); 
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);
        if (curl_errno($curl)) {
           return 'Errno'.curl_error($curl);
        }
        curl_close($curl);
        return $result;
    }

    客服接口发送图文消息、音乐消息、视频消息具体格式请参看微信公众平台上的开发帮助文档。
    客服接口可以和消息接口混合使用。
    这里大家可能不明白既然可以直接通过被动响应消息的接口发送xml数据给用户,为什么还需要这样一个客服接口?可以这样理解,被动响应消息是一次性的只能回复一次相同的消息。如你向一个音乐平台输入一个歌星名称,通过被动响应方式发送的消息永远只会回复你一首相同的歌。但是通过客服接口方式可以每次回复不同的 歌曲,这涉及到mysql数据库。
    再简单一点,一个查看快递包括地址的微信公众平台。你每次输入同一个订单编号,后台却能够回复订单每次所在的位置(针对同样的文本却可以做出不同的回应)就像是人工回复一样,这就是客服接口 。

    生成二维码接口

    二维码类型分两种,分别是临时二维码eh 和永久二维码,前者与过期时间,最长是1800s。
    生成二维码你需要调用3个接口,
    第一个是access_token
    第二个是生成ticket接口
    第三个是通过第二个接口生成的ticket来换取二维码图片。

    $access_token = " xDx0pD_ZvXkHM3oeu5oGjDt1_9HxlA-9g0vtR6MZ-v4r7MpvZYC4ee4OxN97Lr4irkPKE94tzBUhpZG_OvqAC3D3XaWJIGIn0eeIZnfaofO1C3LNzGphd_rEv3pIimsW9lO-4FOw6D44T3sNsQ5yXQ";//假定获取的ACCESS TOKEN为这段代码。
    
    //临时二维码
    $qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 10000}}}';
    //永久二维码
    $qrcode = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 1000}}}';
    
    $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";//创建ticket接口
    $result = https_request($url,$qrcode);
    $jsoninfo = json_decode($result, true);
    $ticket = $jsoninfo["ticket"];
    
    function https_request($url, $data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    
    
    $ticket = "gQHi8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0UweTNxNi1sdlA3RklyRnNKbUFvAAIELdnUUgMEAAAAAA==";//获取ticket的字符串
    
    $url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($ticket);//ticket对面二维码图片代码。
    $imageInfo = downloadWeixinFile($url);
    
    $filename = "qrcode.jpg";
    $local_file = fopen($filename, 'w');
    if (false !== $local_file){
        if (false !== fwrite($local_file, $imageInfo["body"])) {
            fclose($local_file);
        }
    }
    
    function downloadWeixinFile($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);    
        curl_setopt($ch, CURLOPT_NOBODY, 0);    //只取body头
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $package = curl_exec($ch);
        $httpinfo = curl_getinfo($ch);
        curl_close($ch);
        return array_merge(array('body' => $package), array('header' => $httpinfo)); 
    }
    

    在服务器空间运行这段代码,浏览器会生成一张二维码图片。

    获取非微信功能接口,比如获取交通信息、天气预报。

    这里我们以调去百度天气的api接口为例:参看以下连接文章即可
    http://www.jianshu.com/writer#/notebooks/6632557/notes/6780992/preview

    展开全文
  • 功能描述:用户下单支付时可以选择微信支付,并调用微信接口实现支付完成 微信支付的种类 微信扫描二维码支付 微信端吊起H5进行支付 微信公众号吊起支付 app吊起微信支付 本篇讲的是针对微信公众号和app...

    功能描述:用户下单支付时可以选择微信支付,并调用微信端接口实现支付完成

    微信支付的种类

    • 微信扫描二维码支付
    • 微信端吊起H5进行支付
    • 微信公众号吊起支付
    • app吊起微信支付

    本篇讲的是针对微信公众号和app吊起支付的流程

    首先是图文流程

    微信支付流程

    模块代码

    一、申请微信商户平台

    这里是详细的微信开发的开发文档链接

    二、进入到商户平台,设置一些需要的参数

    三、前台执行ajax请求,提交到后台吊起微信支付接口。用户在前台选择想要购买的商品,点击支付按钮时,前台ajax获取商品的具体信息(id,num,name),然后请求后台的支付方法,后台执行完成后给前台返回需要的参数并跳转到微信支付页面执行输入密码操作

    function wechatDoPay({
    //获取商品名称,价格,商品数量
    $.ajax({
              type:"post",
              url:"http://www.xyz.cn/wechatTest/wechat/unifiedorder",
              success:function(data){
              if(data.status=="success"){
              wx.chooseWXPay(data);
    }
    }
    })
    });
    
    wx.chooseWXPay({
    timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: '', // 支付签名随机串,不长于 32 位
    package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
    signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
    paySign: '', // 支付签名
    success: function (res) {
    // 支付成功后的回调函数
    }
    });
    
    

    备注:prepay_id 通过微信支付统一下单接口拿到,paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。

    四、后台controller层代码,校验用户的登陆状态,拿着openid和前台传来的参数去service层执行微信支付的具体方法

    @RequestMapping("unifiedorder")
    @ResponseBody
    public String unifiedorder(HttpServletRequest request, String goodsId, int countNum){
    
        //在这里做一下校验,直接校验用户有没有登录,如果没有登录,就不允许吊起下单操作
    
        //接受前台的token防止用户重复提交
    
        String openid = "";//openid是微信用户在公众号appid下的唯一用户标识
        JSONObject jsonObject = service.unifiedorder(openid, goodsId,countNum);
    
        jsonObject.put("status", "success");
        return jsonObject.toString();
    }
    

    五、后台service层

    处理主要的支付业务,根据前台传来的商品id获取详细商品信息,以及购买总价格,然后吊起微信统一下单的地址,在吊起之前,需要对传递的数据进行一些操作,首先需要appid和openid,商户ID,随即生成的字符串等等,还要设置一下支付完成后,微信如何通知后台管理用户已经完成了支付的路径,这些参数设置号以后,将它们转化成xml格式,并且调用支付接口,随后微信端返回对应的xml结果回来,我们在根据前台需要将传递回来的参数,进行json格式的转换以及paysign签名的重新生成,随后把拼接好的json字符串返回给前台

    public JSONObject unifiedorder(String openid, String goodsId, int countNum) {
    
            GoodsOrder goodsOrder = new GoodsOrder();
    
            //根据用户id查询用户权限,看看用户是否是VIP
    
            //根据商品id查询出商品信息
    
            //根据商品数量和商品价格,计算出要付的价格
    
    
            //4、调用微信下单操作,开始执行微信下单功能
            //获取预支付号
            String out_trade_no = UUID.randomUUID().toString();//需要插入订单表的订单ID
            String prepayId = "";//第一次生成的预支付订单
            SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();//使用sortedmap给下面插入的数据进行排序
            parameters.put("appid", WechatUtils.appid);//微信支付分配的公众账号ID
            parameters.put("mch_id", WechatUtils.mch_id);//微信支付分配的商户号,注册完公众号后开通微信支付接口时给的id
            parameters.put("nonce_str", WechatUtils.CreateNoncestr());//随即生成的16位的字符串
            parameters.put("body", "我是从商品表中拿出来的商品名字");
    //        parameters.put("body", goodsOrder.getId());
            parameters.put("out_trade_no", out_trade_no);
            //110 等于一块一毛钱
            //10000 等于一百
            //如果数据库存的是double类型的,价格是10.5怎么传入微信里,10.5*100=1050
    //        parameters.put("total_fee", String.valueOf(goods.getPrice())+"00");
            parameters.put("total_fee", String.valueOf(10)+"00");//我是十块
            parameters.put("spbill_create_ip", WechatUtils.spbill_create_ip);//调用微信支付API的机器IP
            parameters.put("notify_url", WechatUtils.WECHAT_NOTIFY_URL);//支付完成后回返回后台系统的调用的请求路径
            parameters.put("trade_type", "JSAPI");//交易类型
    
            //生成签名的地方需要一个openid,所以把这个openid加上
            //openid是微信用户在公众号appid下的唯一用户标识(appid不同,则获取到的openid就不同),
            // 可用于永久标记一个用户,同时也是微信JSAPI支付的必传参数
            parameters.put("openid", openid);
    
            parameters.put("timeStamp", WechatUtils.create_timestamp());//生成时间戳
    
            //我的作用是为了生成一个签名
            String sign = WechatUtils.createSign(parameters);
            parameters.put("sign", sign);
            //把map类型的参数转换成xml格式的
            String requestXML = WechatUtils.getRequestXml(parameters);
    
            //开始请求支付接口,返回微信的订单结果
            String preparyIdXml = CommonUtil.httpRequestJson(WechatUtils.unifiedorder, "POST", requestXML);
    
    
            //把返回的订单结果转换为map类型的
            Map<String, String> prepayIdMap =new HashMap<String, String>();
            try {
                prepayIdMap = XMLUtil.doXMLParse(preparyIdXml);
            } catch (JDOMException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null != prepayIdMap) {
                prepayId =prepayIdMap.get("prepay_id");
            }
    
    
        }
    

    这是微信端需要的参数格式,都是以xml的形式传递

    <xml>
    
             <appid>wx2421b1c4370ec43b</appid>
    
             <attach>支付测试</attach>
    
             <body>JSAPI支付测试</body>
    
             <mch_id>10000100</mch_id>
    
    				     <detail><![CDATA[{
    "goods_detail":[
    {
    "goods_id":"iphone6s_16G",
    "wxpay_goods_id":"1001",
    "goods_name":"iPhone6s 16G",
    "quantity":1,
    "price":528800,
    "goods_category":"123456",
    "body":"苹果手机"
    },
    {
    "goods_id":"iphone6s_32G",
    "wxpay_goods_id":"1002",
    "goods_name":"iPhone6s 32G",
    "quantity":1,
    "price":608800,
    "goods_category":"123789",
    "body":"苹果手机"
    }
    ]
    }]]></detail>
    
             <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
    
             <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
    
             <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
    
             <out_trade_no>1415659990</out_trade_no>
    
             <spbill_create_ip>14.23.150.211</spbill_create_ip>
    
             <total_fee>1</total_fee>
    
             <trade_type>JSAPI</trade_type>
    
             <sign>0CB01533B8C1EF103065174F50BCA001</sign>
    
          </xml> 
    

    这是第二次返回的xml结果,需要我们后台进行转换以及拼接成json字符串返回给前台

    <xml>
    
             <return_code><![CDATA[SUCCESS]]></return_code>
    
             <return_msg><![CDATA[OK]]></return_msg>
    
             <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
    
             <mch_id><![CDATA[10000100]]></mch_id>
    
             <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
    
    	     <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
    
             <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
    
             <result_code><![CDATA[SUCCESS]]></result_code>
    
             <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
    
             <trade_type><![CDATA[JSAPI]]></trade_type>
    
          </xml> 
    

    这是前台需要的参数类型,后台需要拼接成这种类似的格式,前台才能引用

    wx.chooseWXPay({
    timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: ‘’, // 支付签名随机串,不长于 32 位
    package: ‘’, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
    signType: ‘’, // 签名方式,默认为’SHA1’,使用新版支付需传入’MD5’
    paySign: ‘’, // 支付签名
    success: function (res) {
    // 支付成功后的回调函数
    }
    });

    后台controller层,负责接收微信端的回调数据,主要是解析用户有没有完成支付,并进行更进一步的业务判断和处理

    @RequestMapping("wechatNotifyUrl")
    @ResponseBody
    public String wechatNotifyUrl(HttpServletRequest request){
    
        try {
            //用户发送了一条消息或关注了我的公众号,都会发一条消息,消息是流形式
            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);
            }
            outSteam.close();
            String result = new String(outSteam.toByteArray(), "UTF-8");
    
            System.out.println("result==="+result);
    
            //SAX解析xml
            Map<String, String> map = null;
            //通过sax解析xml技术,把xml文本解析成map对象
            try {
                map = XMLUtil.doXMLParse(result);
            } catch (JDOMException e) {
                e.printStackTrace();
            }
       
         //必须要给微信一个回复,否则微信端会一直请求你的接口
         return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    
    
        }catch (Exception e){
    
        }
        
        return null;
    }
    

    这里需要注意的是,一定要给微信端返回

    “<return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg>”;

    这种形式的数据,不然微信端会一直调用你的后台接口确认你有没有接受到数据

    总结

    前台调用后台接口→后台调用微信统一下单接口,后台返回调用微信统一下单后返回的内容给前台→前台根据后台返回的内容调用微信浏览器内置JS弹出支付→支付后有两种处理 ①前台支付成功后的页面 ②微信回调url(一般处理业务逻辑)

    支付的幂等性

    什么是支付的幂等性?
    (1)用户多次请求造成出现多个订单
    (2)支付完成后,被拦截或网络不好,造成收不到回调通知或是收到了回调通知,但是这个回调通知的金额和支付信息不匹配,说明数据有问题

    可以参考以下博客来进行问题的解决
    https://blog.csdn.net/github_36032947/article/details/78386551
    https://www.cnblogs.com/leechenxiang/p/6626629.html
    https://blog.csdn.net/aly1989/article/details/52352726

    展开全文
  • WX开放平台申请网站应用,获得APPID和SECRET,第三方应用接入WX登录 ...第一步:调用微信登录接口,用户扫码登录,生成code https://open.weixin.qq.com/connect/qrconnect?appid=xxxxxxxxxxxxxx&redirect_uri=https%...

    WX开放平台申请网站应用,获得APPID和SECRET,第三方应用接入WX登录

    APPID:xxxxxxxxxxxxxx
    SECRET:yyyyyyyyyyyyyyy

    第一步:调用微信登录接口,用户扫码登录,生成code
    https://open.weixin.qq.com/connect/qrconnect?appid=xxxxxxxxxxxxxx&redirect_uri=https%3A%2F%2Fp7yrpa.natappfree.cc&response_type=code&scope=snsapi_login&state=200

    结果:
    http://79n8s3.natappfree.cc/?code=0610Xey313BXSQ15G6v31H6wy310Xeyv&state=200
    

    第二步:请求以下路径通过code获取access_token 参数:appid=APPID,secret=SECRET,code=填写上一步生成的code,grant_type=“authorization_code”,生成access_token
    https://api.weixin.qq.com/sns/oauth2/access_token
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxxxxxxx&secret=yyyyyyyyyyyyyyy&code=061OWZMX1Rl7LZ0qICMX1I9CMX1OWZMK&grant_type=authorization_code
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxxxxxxx&secret=SECRETyyyyyyyyyyyyyyy&code=0610Xey313BXSQ15G6v31H6wy310Xeyv&grant_type=authorization_code

    结果:
    { 
    "access_token":"ACCESS_TOKEN",                       	接口调用凭证
    "expires_in":7200, 			          	access_token接口调用凭证超时时间,单位(秒)
    "refresh_token":"REFRESH_TOKEN",		用户刷新access_token
    "openid":"OPENID", 				授权用户唯一标识
    "scope":"SCOPE",				用户授权的作用域,使用逗号(,)分隔
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"	当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
    }
    

    第三步:请求以下链接进行refresh_token 参数:appid=APPID,grant_type=‘refresh_token’,refresh_token=填写上一步获取到的refresh_token参数
    https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=23_ivXL7QsljTjYUJaifpGajw6DaWu3N-2A5-GewcFpSEK_xZ_CSBGBJ35HpXS-qa4GwbsvrEHbibwJWma3OKpYr73m3ZnAi25_V3pezwRSO10
    https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

    结果:
    { 
    "access_token":"ACCESS_TOKEN", 		接口调用凭证
    "expires_in":7200, 				access_token接口调用凭证超时时间,单位(秒)
    "refresh_token":"REFRESH_TOKEN", 		用户刷新access_token
    "openid":"OPENID", 				授权用户唯一标识
    "scope":"SCOPE" 				用户授权的作用域,使用逗号(,)分隔
    }
    

    第四步:请求以下连接查询用户基本信息 参数:access_token=填写上一步获取的access_token,openid=填写上一步获取的openid
    https://api.weixin.qq.com/sns/userinfo

    结果:
    {"openid":"ooooooooooooo",
    "nickname":"朝",
    "sex":1,
    "language":"zh_CN",
    "city":"Hangzhou",
    "province":"Zhejiang",
    "country":"CN",
    "headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTIlicQP4zdmtiaDkLEus7e8GMHZXnnD2YqLWpgEPl5QGPAKe02x4nMwZricqBOzo8gF0mm3gLyL0zh2Q\/132",
    "privilege":[],
    "unionid":"oniwU5vxax7qU27Xdy3Cb-MYvYeE"}
    
    展开全文
  • 调用微信图片接口

    2018-09-09 14:41:22
    首先连入微信端,用户同意授权,获取code,通过code换取网页授权access_token,根据开发文档可以获取到微信接口调用方式。 微信选择照片后在页面做一个展示效果,此处有坑,不同操作系统,Android和Ios不一样...
  • 在php微信开发文档中,我们使用php来做微信的开发; 首先: 在微信开发者文档中,开始开发->接入指南->目录中有三步骤写的很已经很明确了。 好了。进入正题; 下载demo,php示例; 把Demo放到线上的域名中。 ...
  • 前言:应项目要求,需要使用微信小程序做支付,写完后告知手续费太高方案不予通过(宝宝心里苦,但宝宝不说)。此次开发在因站在巨人的肩膀上顺利完成。 微信支付文档传送门:...
  • 微信调用“获取access_token”接口增加IP白名单校验:只有将IP地址设置为公众号的IP白名单,才能成功调用接口。 开启IP白名单的步骤如下: 1、登录公众平台,进入开发->基本配置页面 2、点击配置...
  • 我前段时间做微信支付,遇到了很多坑,网上也...在微信提供的接口文档中提供了一个微信支付接口,应该是直接调用这个接口就可以发起微信支付 文档路径:https://developers.weixin.qq.com/miniprogram/dev/api/ap...
  • 微信API接口文档

    2019-05-24 01:03:22
    微信API接口文档 微信API接口文档,微信API接口,个人微信聊天接口api 微信手机客户端上传的通知类消息 1、手机客户端微信上线通知 WeChatOnlineNotice = 1020; 2、手机客户端微信下线通知 ...
  • 微信公众平台开发调用微信支付的接口发起支付;JSAPI方式 JS-SDK ASP.NET版本 测试运行通过的 如果你想测试 需要发布到IIS到公网上。 因为在运行该代码时,微信公众平台的微信支付中有开发配置 需要设置支付授权目录...
  • 今天我们自己调用自己商城中的接口 以下是简单的示例 这是自己的目录结构,我选择的是index1来开发 首先在 index.js中想写逻辑代码 其中page里面的data里面是前台展示时的一些数据,而onload里面是调用...
  • 为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制时,调用对应接口会收到如下错误返回码: {"errcode":45009,"errmsg":"api freq out of limit"} ...
  • 微信音频接口调用demo

    2018-02-10 17:52:54
    前几天做一个录音送祝福的项目,事先做了一个demo,记录一下,方便日后需要时套上直接使用&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset=".../&
  • 微信开发调用微信上传图片接口,并保存到自己的服务器 整体思路是这样的: 1.先把手机上的图片上传到微信服务器,然后返回一个图片ID 2.在通过后台根据ID从微信后台拿到流,保存到服务器 前几个步骤在之前的博客上有...
  • 微信开发之JSSDK调用

    2016-11-22 17:03:13
    由于项目需要,需要接触微信开发,并要调用微信的JS-SDK里面的接口。 因为经验缺乏,我百度一下关于微信开发的资料,但收集的资料都不尽人意。网上的主流的微信开发是采用PHP开发的,而本人学的Java。所以对PHP微信...
  • 1.1 前言  我们在使用别人的接口的时候,需要参考它的官方开发文档,例如微信的网址是...统一下单接口调用: 请求URL 请求参数(XML格式、加签名) 发送请求https请求 响应数据(xml) 获取code_url...
  • java调用微信支付接口

    2020-07-10 16:42:06
    调用的页面是oauth.jsp,调用的代码类是WeiXinPayController,我用的是springmybatis,你可以放到自己的项目中运行
1 2 3 4 5 ... 20
收藏数 65,061
精华内容 26,024