微信常用接口

微信常用接口

一、公众号

1、准备工作

  1. 公众号的帐号及密码

  2. 公众号的AppID,AppSecret

    AppID:

    ​ 开发者ID是公众号开发识别码,配合开发者密码可调用公众号的接口能力。

    AppSecret:

    ​ 开发者密码是校验公众号开发者身份的密码,具有极高的安全性。切记勿把密码直接交给第三方开发者或直接存储在代码中。如需第三方代开发公众号,请使用授权方式接入

  3. 在公众号设置中选择功能设置,下载TXT文件放到web服务器的目录下,将域名填写至白名单等

    业务域名:

    ​ 设置业务域名后,在微信内访问该域名下页面时,不会被重新排版。用户在该域名上进行输入时,不出现安全提示。

    JS接口安全域名:

    ​ 因为微信的安全做得比较好,我们根据 微信的js sdk写的函数、方法,只有在指定的安全域名下才能被微信唤起。

    网页授权域名:

    ​ 用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。

    例如:微信公众号登录后的回调

  4. 微信官方文档:https://developers.weixin.qq.com/doc/ 有你想知道的一切信息

2、获取access_token

​ access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。access_token的有效期目前为2个小时,需定时刷新.

https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明

参数 是否必须 说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{
     "access_token":"ACCESS_TOKEN","expires_in":7200}

代码演示

(1) 获取Token,建议采用懒加载策略,用的时候再发请求,全局共享。

//拼接连接
String accessToken="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+"你的appId"+"&secret="+"你的appsecret";

String tokenResult = req.sendGet(accessToken);//进行网络的请求获取token
String tokenObj= JSON.parseObject(tokenResult);//在上面的基础上获取信息 
//返回:{"access_token":"ACCESS_TOKEN","expires_in":7200}

String accesstoken = tokenObj.getString("access_token");//获取access_token 
String expiresin = tokenObj.getString("expires_in");//获取expires_in
String errcode=tokenObj.getString("errcode");//获取错误代码
String errmsg=tokenObj.getString("errmsg");//获取错误信息
//判断是否为空
if(StringUtils.isNotBlank(accesstoken)){
     
    //写入redis缓存,设置2小时过期
	SecurityCommonUtils.putRedis("GLOBAL_ACCESS_TOKEN", accesstoken, 7200);
}else{
     
    logger.error("错误代码=========="+errcode);
    logger.error("错误信息=========="+errmsg);
    throw new NullPointerException("token获取异常!");
}

至此只要不出问题,SecurityCommonUtils.gutRedis(“GLOBAL_ACCESS_TOKEN”) 咱们就可以拿到的全局token了

3、用户管理

(1)OpenID 与 UnionID

OpenID :

​ 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的OpenID不同)

​ 简单的说就是,用户去逛各大商场,商场给你对应了商场的会员卡(OpenID),可以根据这个会员卡进行改商城的消费。

​ 那么问题来了,如果想在不同的维多利商城做到会员卡通用,就需要增加一个公用的会员卡(UnionID ),方便同一个集团在不同的产品中识别到同一个用户

UnionID :

​ 请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

(2)网页授权(用户登录)

具体而言,网页授权流程分为四步:

  1. 引导用户进入授权页面同意授权,获取code
  2. 通过code换取网页授权access_token(与基础支持中的access_token不同)
  3. 如果需要,开发者可以刷新网页授权access_token,避免过期
  4. 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

获取用户授权 请使用https协议。

/**
 * 微信登录请求这个方法获取code
 * @param response
 * @Date 2020年10月29日
 * @author zy
 */
@RequestMapping("/wxlogin")
public void wxloginvenue(HttpServletResponse response,String isLogin, String orderId){
     
    try {
     
        String appId = "你的appId";
        String url = "你的回调地址";
        String redirectUri = URLEncoder.encode(url,"utf-8");//回调的方法转成UTF-8
        String requestUrl = "";
        if (StringUtils.isNotBlank(isLogin)){
     // 登录操作
            requestUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +appId +
                "&redirect_uri=" + redirectUri + "&response_type=code&scope=snsapi_userinfo&state=-0#wechat_redirect";
        } else {
      // 授权,静默方式授权
            requestUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId +
                "&redirect_uri=" + redirectUri + "&response_type=code&scope=snsapi_base&state=-0#wechat_redirect";
        }
        response.sendRedirect(requestUrl);//进行网络的请求
    } catch (Exception e) {
     
        e.printStackTrace();
        logger.error("微信登录出现异常出现异常!",e);
    }
}

以上代码有几个比较重要的参数:

  1. snsapi_userinfo :非静默授权。这种授权方式需要用户手动同意,授权后获取该用户的基本信息
  2. snsapi_base :静默授权。这种授权方式可以让用户无感知,授权后获取该用户的OpenID
  3. redirect_uri : 回调地址,微信登录成功后需要通知的地址,返回数据
  4. state:重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节

回调地址

获取code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

@RequestMapping("/logingetaccesstoken")
    public String loginGetAccessToken(HttpRequest req, HttpServletRequest request) {
     
        String tokenResult = null;
        String redirecturl = null;
        try {
     
            String code = request.getParameter("code");
            String state = request.getParameter("state");
            String appId = "你的appId";;
            String secret = "你的appsecret";
            //通过code获取access_token的url
            String wxAccessUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
            String accessTokenUrl = wxAccessUrl + "?appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";//Url的拼接
            tokenResult = req.sendGet(accessTokenUrl);//进行网络的请求获取token
            JSONObject tokenObj = JSON.parseObject(tokenResult);//在上面的基础上获取信息

            //获取用户信息url
            //获取access_token网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
            String accessToken = tokenObj.getString("access_token");
            String openId = tokenObj.getString("openid");//获取openid
            String unionid = tokenObj.getString("unionid");
            String wxUserinfoUrl = "https://api.weixin.qq.com/sns/userinfo";
            String userUrl = wxUserinfoUrl + "?access_token=" + accessToken + "&openid=" + openId;//url的拼接
            String wxUserInfo = req.sendGet(userUrl);//进行网络请求获取用户的信息

            request.getSession().setAttribute("openId", openId);
            //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
            request.getSession().setAttribute("unionid", unionid);
            request.getSession().setAttribute("wxUserInfo", wxUserInfo);

            if ("-0".equals(state)) {
     // 登录操作需要更新数据库中信息,授权操作只记录openId
                SecurityCommonUtils.putRedis("THIRD_PARTY_LOGIN_" + user.getLogin_name(), "true", 7200);
                SecurityCommonUtils.putRedis(user.getUser_id().toString() + REDIS_USER_OPENID_SUFFIX, openId);
                SecurityCommonUtils.login(user, false);
                SavedRequest savedRequest = WebUtils.getSavedRequest(request);
                String url = "";
                if (null != savedRequest) {
     
                    url = savedRequest.getRequestUrl();
                    redirecturl = "redirect:" + url;//上一次访问的页面
                }else {
     
                    redirecturl = "redirect:" + HOME_URL;
            	}
            } else{
     
                redirecturl = "redirect:/pay/orders.shtml?orderId"+ state+"&code="+code;// 微付支付页面;*/
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            logger.error("微信登录绑定出现异常出现异常!", e);
        }
        return redirecturl;
    }

获取到的用户信息为JSON数据,进行处理

{
         
  "openid":" OPENID",
  "nickname": "用户昵称",
  "sex":"用户的性别",//,值为1时是男性,值为2时是女性,值为0时是未知
  "province":"省市",
  "city":"城市信息",
  "country":"国家地区",
  "headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",//用户头像地址
  "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],//用户特权信息
  "unionid": "unionid"
}

4、 模板消息

(1)准备工作

进入公众号,找到功能-模板消息-我的末班-从模板库中添加,进行新增模板库(需要审核)

进入模板详情查看对应参数,

微信常用接口_第1张图片

{ {first.DATA}}
{ {keyword1.DATA}}
{ {keyword2.DATA}}
{keyword3.DATA}}

{ {keyword.DATA}}
{ {remark.DATA}}

记录上方的的字段,传输模板消息时会用

(2)代码实现

发送请求

public boolean sendMessage(WxMsg wxMsg,String openid){
     
    HttpRequest req=new HttpRequest();
    if(StringUtils.isBlank(SecurityCommonUtils.getRedis("GLOBAL_ACCESS_TOKEN"))){
     //判断access token是否失效
        GetAccessToken.getasstoken(req);//获取accesstoken
    }
    
    //拼接连接 传入TOKEN
    String sendurl="https://api.weixin.qq.com/cgi-bin/message/template/send?						access_token="+SecurityCommonUtils.getRedis("GLOBAL_ACCESS_TOKEN");
    
    JSONObject map=spellMsg(wxMsg, openid);//拼接消息
    
    String results=req.sendPost(sendurl, map.toString());
    JSONObject tokenObj=JSON.parseObject(results);
    String errcode = tokenObj.getString("errcode");//获取返回值
    if(StringUtils.isNotBlank(errcode)&&errcode.equals("0")){
     
        logger.info("发送消息成功,返回代码————————"+errcode);
        return true;
    }else{
     
        logger.error("发送失败,返回错误代码————————"+errcode);
        return false;
    }
}

**消息拼接 **

public JSONObject spellMsg(WxEasyMsg wxEasyMsg,String openid){
     
	JSONObject result=new JSONObject(); 
	JSONObject data=new JSONObject(); 

    //{
     {first.DATA}}
	JSONObject first=new JSONObject(); 
    first.put("value","恭喜你购买成功");
    first.put("color","#173177");
    data.put("first",first);

  
    //{
     {keyword1.DATA}}
    JSONObject keyword1=new JSONObject();
    keyword1.put("value","巧克力");
    data.put("keyword1",keyword1);
    
	//{
     {keyword2.DATA}}
    JSONObject keyword2=new JSONObject();
    keyword2.put("value","39.8元");
    data.put("keyword2",keyword2);

    //{
     {keyword3.DATA}}
    JSONObject keyword3=new JSONObject();
    keyword3.put("value","2014年9月22日");
    data.put("keyword3",keyword3);

    //{
     {remark.DATA}}
    JSONObject remark=new JSONObject();
    remark.put("value","欢迎再次购买!");
    remark.put("color","#0000FF");
    data.put("remark",remark);
			
    result.put("touser","用户的OpenID");
    result.put("template_id","对应的模板ID");
    
    //详情页的回调地址
    result.put("url","你的详情地址");
    result.put("topcolor","#FF0000");
    result.put("data",data);
    return result;
}

拼接结果

{
     
    "touser":"OPENID",
    "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
    "url":"http://weixin.qq.com/download",  
    "miniprogram":{
     
        "appid":"xiaochengxuappid12345",
        "pagepath":"index?foo=bar"
    },          
    "data":{
     
        "first": {
     
            "value":"恭喜你购买成功!",
            "color":"#173177"
        },
        "keyword1":{
     
            "value":"巧克力",
            "color":"#173177"
        },
        "keyword2": {
     
            "value":"39.8元",
            "color":"#173177"
        },
        "keyword3": {
     
            "value":"2014年9月22日",
            "color":"#173177"
        },
        "remark":{
     
            "value":"欢迎再次购买!",
            "color":"#173177"
        }
    }
}

**发送完毕 **

微信常用接口_第2张图片

二、 微信支付

1、准备工作

傻瓜式准备文档 : https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/ico-guide/chapter1_2.shtml

  1. 微信支付的帐号密码

  2. 商户号(mch_id):

微信常用接口_第3张图片

  1. 证书(cert):

    微信常用接口_第4张图片

  2. 密码(password)

  3. API秘钥(key):API密钥属于敏感信息,请妥善保管不要泄露,如果怀疑信息泄露,请重设密钥。

  4. 选择并且开通对应的支付渠道

    微信常用接口_第5张图片

场景介绍文档 : https://pay.weixin.qq.com/static/product/product_intro.shtml?name=jsapi

2、代码实现

​ 下订单前,需要获取用户的OPENID(使用静默授权即可,除非业务需要)

接口文档 : https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1

JSAPI : https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

业务流程

微信常用接口_第6张图片

代码演示

sdk 工具,以及demo:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

订单生成

function submit(){
     
    var name=$("#name").val();
    var phone=$("#phone").val();
    var sex=$("input[name='sex']:checked") .val();
    var contributionTypeId=$("#contributionTypeId").val();
    var price=$("#price").val();

    if(name==null || name==''){
     
        layer.msg("请填写姓名!");
        return false;
    }
    if(phone==null || phone==''){
     
        layer.msg("请填写手机号!");
        return false;
    }
    if(!(/^[1][0-9]{10}$/.test(phone))){
     
        layer.msg("请填写正确手机号!");
        return false;
    }
    if(sex==null || sex==''){
     
        layer.msg("请选择性别!");
        return false;
    }
    if(contributionTypeId==null || contributionTypeId==''){
     
        layer.msg("请选择捐款用途!");
        return false;
    }
    if(price==null || price=='' || price<=0){
     
        layer.msg("请填写正确的金额!");
        return false;
    }
    var data={
     
        name:name,
        phone:phone,
        sex:sex,
        contributionTypeId:contributionTypeId,
        price:price
    };

    $.post(ctx+"/wechat/savecontribution.shtml",data,function(data){
     //创建订单
        if(data.flag){
     
           $("#orderCode").val(data.orderCode);
            goPay();
        }else if(data.isNotLogin){
     
            window.location.href = ctx + "/wechat/wxlogin.shtml?isLogin=true";
        }else{
     
            layer.msg(data.msg);
        }
    });
}

支付js

function goPay(){
     
    var load = parent.layer.load(1, {
     
        shade : [ 0.3, '#393D49' ]
    });

    $.ajax({
     
        url : ctx + "/pay/orders.shtml",
        type : 'post',
        async:false,
        data : {
     
            orderCode : $("#orderCode").val()
        },
        success : function(data) {
     
            parent.layer.close(load);
            if (data.flag) {
     
                //固定写法开始 
                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(data.json);
                }
                //固定写法结束 
            }else if(data.status){
     
                parent.layer.msg(data.msg);
            }else if(data.wxlogin){
     
                parent.layer.msg(data.wxlogin);
                setTimeout(function(){
     
                    window.location.href = ctx + "/wechat/wxlogin.shtml?isLogin=true&orderId="+orderId;
                },3000);
            }
        }
    });
}

onBridgeReady

function onBridgeReady(data){
     
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest', {
     
            "appId":data.appId,//公众号名称,由商户传入
            "timeStamp":data.timeStamp,//时间戳,自1970年以来的秒数
            "nonceStr":data.nonceStr, //随机串
            "package":data['package'],
            "signType":data.signType,//微信签名方式:
            "paySign":data.paySign //微信签名
        },
        function(res){
     
            if (res.err_msg == "get_brand_wcpay_request:ok" ) {
     
                setCodeTimer();
            } else {
     
                layer.msg("支付失败");
            }
        }
    );
}

轮询查询支付结果

function setCodeTimer() {
     
    var time=120;
    var codeTimer = window.setInterval(function() {
     
        time=time--;
        $.ajax({
     
            url : ctx+"/pay/getnotify.shtml",
            type : 'post',
            data:{
     
                orderCode:$("#orderCode").val()
            },
            success : function(data) {
     
                if(data.flag){
     
                    window.clearInterval(codeTimer);
                    layer.msg("捐赠成功,感谢您的捐赠!");
                    setTimeout(function(){
     
                        location.href = ctx + "/wechat/home.shtml";
                    },2000);

                }
            }
        });
        if (time == 0) {
     
            window.clearInterval(codeTimer);
            layer.msg("订单已过期");
            setTimeout(function(){
     
                location.href =location.href = ctx + "/wechat/home.shtml";
            },2000);
        }
    },1500);
}

微信预下单操作

/**
    * @Description 微信浏览器内微信支付/公众号支付(JSAPI)
    * @param request
    * @param code
    * @return Map
    */
@RequestMapping(value="orders", method = RequestMethod.POST)
@ResponseBody
public Map orders(HttpServletRequest request,String orderCode) {
     
   Map<String, Object> payMap = new HashMap<String, Object>();
   boolean resultBool = false;
   payMap.put("flag",false);
   if(StringUtils.isBlank(orderCode)){
     
       payMap.put("msg","订单号为空!");
       return payMap;
   }
   Map<String, String> map = new HashMap<String, String>();
   try {
     
       ContributionOrder contributionOrder=contributionOrderService.getContributionOrderByOrderCode(orderCode);
       if(contributionOrder!=null){
     
           if(contributionOrder.getStatus()!=0){
     
               payMap.put("status",true);
               payMap.put("msg","捐赠订单状态异常,请重新下单!");
               return payMap;
           }
           if(request.getSession().getAttribute("openId")==null){
     
               payMap.put("wxlogin",true);
               payMap.put("msg","暂未登录,请登录后重新捐赠!");
               return payMap;
           }

           //页面获取openId接口
           String nonceStr = getRandomStringByLength(32);
           String appid = SysConfigManager.getInstance().getText("/config/wx/appid");
           String key = SysConfigManager.getInstance().getText("/config/wxpay/key");
           String mchId =SysConfigManager.getInstance().getText("/config/wx/wxpay");
           String notifyUrl = SysConfigManager.getInstance().getText("/config/wxpay/notify_url");
           String unifiedorderUrl = SysConfigManager.getInstance().getText("/config/pay/unifiedorder");
           String openId=request.getSession().getAttribute("openId").toString();
           String sign = Signature.getSign(map, key);
           String ip = CommonUtils.getIpAddr(request);
           if(ip.contains(",")){
     
               ip = ip.split(",")[0];
           }

           map.put("appid", appid);//公众账号ID
           map.put("mch_id", mchId);//商户号ID
           map.put("nonce_str", nonceStr);//随机字符串
           map.put("sign", sign);//签名
           map.put("body", "爱心捐赠:[" + contributionOrder.getPrice() + "] 费用");//商品描述
           map.put("out_trade_no", contributionOrder.getOrderCode());//订单号

           //交易金额默认为人民币交易,接口中参数支付金额单位为【分】,参数值不能带小数。对账单中的交易金额单位为【元】
           map.put("total_fee",""+(new Double(contributionOrder.getPrice() * 100)).intValue());//标价金额
           map.put("spbill_create_ip", ip);//IP地址
           map.put("notify_url",notifyUrl);// 此路径是微信服务器调用支付结果
           map.put("trade_type", "JSAPI");
           map.put("openid",openId);
           String xml = WXPayUtil.mapToXml(map);//将所有参数(map)转xml格式
           String result = PayUtils.invokeHttpsMethod(unifiedorderUrl, xml);
           Map resultMap = PayUtils.getMapFromXML(result);

           String returnCode = resultMap.get("return_code").toString();//返回状态码
           String resultCode = resultMap.get("result_code").toString();//业务结果
           String timeStamp = String.valueOf(System.currentTimeMillis());
           String nonceStr2 = getRandomStringByLength(32);

           payMap.put("appId", appid);
           payMap.put("timeStamp", timeStamp);
           payMap.put("nonceStr", nonceStr2);
           payMap.put("orderCode", contributionOrder.getOrderCode());
           payMap.put("price", contributionOrder.getPrice());
           String prepayId = "";
           if ("SUCCESS".equals(returnCode.toUpperCase()) && "SUCCESS".equals(resultCode.toUpperCase())) {
     //SUCCESS/FAIL
               prepayId = resultMap.get("prepay_id").toString();
               resultBool = true;
           }
           if (!resultBool) {
     
               logger.error("微信下单失败,订单号:" + contributionOrder.getOrderCode() + " 返回信息:" + result);
           }
           String returnSign = createSign(appid, timeStamp, nonceStr, prepayId, key);

           payMap.put("prepay_id", prepayId);
           payMap.put("paySign", returnSign);
           payMap.put("flag",true);
       }

   } catch (Exception e) {
     
       e.printStackTrace();
   }
   return payMap;
}

随机字符串

/**
     * 获取一定长度的随机字符串
     *
     * @param length
     *            指定字符串长度
     * @return 一定长度的字符串
     */
private 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();
}

**发送请求 **

public static String invokeHttpsMethod(String url,Object xmlObj) {
    CloseableHttpClient httpClient = null;
    HttpPost httpPost = null;
    String result = null;
    try {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        // 证书路径
        String certPath = SysConfigManager.getInstance().getText("/config/wxpay/cert");
        String certPassword = SysConfigManager.getInstance().getText("/config/wxpay/password");
        FileInputStream instream = new FileInputStream(new File(certPath));
        //FileInputStream instream = new FileInputStream(new File(SysConfigManager.getInstance().getText("/config/wechatpay/cert")));
        //String certPassword = SysConfigManager.getInstance().getText("/config/wechatpay/password");
        keyStore.load(instream, certPassword.toCharArray());
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,certPassword.toCharArray()).build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(30000).build();
        httpPost = new HttpPost(url);
        //设置请求器的配置
        httpPost.setConfig(requestConfig);
        //解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        xStreamForRequestPostData.alias("xml", OrderXml.class);
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
        System.out.println("支付xml>>>>>>>>>>>>>>>>>>"+postDataXML);
        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        result = EntityUtils.toString(entity, "UTF-8");
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        e.printStackTrace();
    }finally{
        if(httpPost!=null){
            httpPost.abort();
        }
        if(httpClient!=null){
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return result;
}

回调后台

/**
     * 微信支付回调
     *
     * @param result
     * @return
     */
@RequestMapping(value = "/notify", produces = "application/xml;charset=UTF-8")
@ResponseBody
public String wxNotify(@RequestBody String result) {
     
    String notifyResult = null;
    if (StringUtils.isNotBlank(result)) {
     
        logger.info("微信回调报文:" + result);
        try {
     
            Map<String, Object> resultMap = PayUtils.getMapFromXML(result);
            String returnCode = (String) resultMap.get("return_code");
            if (StringUtils.isNotBlank(returnCode) && "SUCCESS".toUpperCase().equals(returnCode)) {
     
                String orderCode = (String) resultMap.get("out_trade_no");
                ContributionOrder contributionOrder=contributionOrderService.getContributionOrderByOrderCode(orderCode);

                String key = SysConfigManager.getInstance().getText("/config/wxpay/key");
                if (Signature.checkIsSignValidFromResponseString(result,key)) {
     
                    Integer totalfFee = Integer.parseInt(resultMap.get("total_fee").toString());
                    Integer orderPrice = new Double(contributionOrder.getPrice() * 100).intValue();

                    if (contributionOrder.getStatus() == 0 && orderPrice.equals(totalfFee)) {
     
                        contributionOrder.setStatus(1);//已支付
                        contributionOrderService.updateOrderPayStatus(contributionOrder);
                        notifyResult = "";
                        SecurityCommonUtils.putRedis(VENUE_ORDER_NOTIFY_WX + contributionOrder.getOrderCode(), "OK", 300);
                    }
                }
            }
        } catch (Exception e) {
     
            e.printStackTrace();
        }

    }
    return notifyResult;
}

三、微信开放平台

1、简介

简单的说,微信公众平台是给编辑的,微信开放平台是给技术的。

接口文档 : https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html?action=dir_list&t=resource%2Fres_list&verify=1&lang=zh_CN&token=a4d21a0a5d1d4c40242e1af442d2e78e76378432

微信公众平台能干什么?

  • 写文章发文章

  • 和粉丝聊天

  • 配置菜单

  • 开通各种公众号的权限(仅限自己的公众号)

  • 启用开发者模式,开发自己的公众号

  • 投放广告

  • 查看数据

微信开放平台能干什么?

  • APP想用微信登录/分享到朋友圈等
  • PC网站想用微信登录等
  • 注册公众号第三方平台(服务所有公众号)
  • 注册小程序第三方平台(提供小程序模板)
  • 绑定公众号或小程序,以形成UnionID

2、绑定操作

微信常用接口_第7张图片

3、接口说明

(1)app接口信息

接口名称 接口介绍 接口状态 操作
分享到朋友圈 将内容分享到微信朋友圈 已获得
发送给朋友 将内容发送给朋友或者群聊 已获得
微信支付 获得微信支付能力 [详情](javascript:void(0) 未获得 [申请开通](javascript:void(0)
微信登录 使用微信帐号登录App或者网站 [详情](javascript:void(0) 已获得
微信卡券 移动应用内领取卡券收入微信卡包 [详情](javascript:void(0) 未获得 [申请开通](javascript:void(0)
智能接口 获得语音识别、图像识别、语义理解等模式识别能力 已获得
一次性订阅消息 用户授权后,开发者将获得发送一条订阅消息的权限 已获得 [查看模板id](javascript:
APP跳转小程序 获得 APP 中跳转至微信小程序,且回到原 APP 的权限 详情 已获得

(2)网站接口信息

接口名称 接口介绍 接口状态 操作
微信登录 使用微信帐号登录App或者网站 [详情](javascript:void(0) 已获得
微信支付 获得微信支付能力 [详情](javascript:void(0) 未获得 [申请开通](javascript:void(0)

(3)公众号接口信息

接口名称 接口介绍 接口状态 操作
网页跳转移动应用 微信内打开服务号的JS接口安全域名,可以跳转至已关联的移动应用。使用前需关联移动应用和域名 详情 未获得

(4)小程序接口信息

接口名称 接口介绍 接口状态 操作
网页跳转移动应用 微信内打开服务号的JS接口安全域名,可以跳转至已关联的移动应用。使用前需关联移动应用和域名 详情 未获得

微信登录 | 使用微信帐号登录App或者网站 [详情](javascript:void(0) | 已获得 | – |
| 微信支付 | 获得微信支付能力 [详情](javascript:void(0) | 未获得 | [申请开通](javascript:void(0) |

(3)公众号接口信息

接口名称 接口介绍 接口状态 操作
网页跳转移动应用 微信内打开服务号的JS接口安全域名,可以跳转至已关联的移动应用。使用前需关联移动应用和域名 详情 未获得

(4)小程序接口信息

接口名称 接口介绍 接口状态 操作
网页跳转移动应用 微信内打开服务号的JS接口安全域名,可以跳转至已关联的移动应用。使用前需关联移动应用和域名 详情 未获得

你可能感兴趣的:(微信,java)