微信小程序> 微信小程序对接主要涉及的接口(仅供参考)

微信小程序对接主要涉及的接口(仅供参考)

浏览量:1649 时间: 来源:慕言小鹏
1.授权登录需要获取到用户的唯一标识openid以及session_key会话密钥/*** @Description: 获取openid用户唯一标识以及session_key会话密钥*/@PostMapping("/getOpenId")public Map<String,Object> getOpenId(String code){    Map<String,Object>  map = new HashMap<>();    //登录凭证不能为空    if (null == code || code.length() == 0){        map.put("errMessage","code 不能为空!");        return map;    }    //1.向微信服务器 试用登录凭证 code 获取session_key 和openid    //请求参数    Map<String,String> params = new HashMap<>();    params.put("appid",StringInfo.APPID);    params.put("secret",StringInfo.APPSECRET);    params.put("js_code",code);    params.put("grant_type","authorization_code");    String result = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session?",params);    JSONObject json = JSON.parseObject(result);    System.out.println(json);    if (json != null) {        //当请求成功        if (json.getString("errcode")==null) {            map.put("openid",json.getString("openid"));//用户的唯一标识            map.put("sessionKey",json.getString("session_key"));//会话密钥            if (json.getString("unionid") != null) {                map.put("unionid", json.getString("unionid"));//用户在开放平台的唯一标识符            }        }else{            //当请求不成功的时候,将错误信息            map.put("errMessage",json.getString("errmsg"));        }    }    System.out.println(JSON.toJSON(map));    return map;}

2.获取AccessToken

/*** @Description:  获取AccessToken*/@PostMapping("/getAccessToken")public Map<String,Object> getAccessToken(){    Map<String,Object> map = new HashMap<>();    Map<String,String> params = new HashMap<>();    //请求参数    params.put("grant_type","client_credential");    params.put("appid", StringInfo.APPID);    params.put("secret",StringInfo.APPSECRET);    //向微信服务端发起请求    String result = HttpClientUtil.doGet("https://api.weixin.qq.com/cgi-bin/token?",params);    //将结果转为json对象    JSONObject json = JSON.parseObject(result);    if (json != null) {        if (json.getString("errcode") == null){            map.put("accessToken",json.getString("access_token"));            map.put("expiresIn",json.getString("expires_in"));        }else {            map.put("errMessage",json.getString("errmsg"));        }    }    return map;}

 

3.微信付款

/** * 支付接口 * @param openid 用户的唯一标识 * @param body1 商品描述信息 * @param total_fee1 金额 * @return */@RequestMapping("/WeiXinPay")public @ResponseBody Object WeiXinPay(String openid,String body1,int total_fee1      ) {   try {      String appid = userService.getUser().getAppid(); // 微信小程序--》“开发者ID”      String mch_id = userService.getUser().getMchId(); // 商户号,将该值赋值给partner      String key = userService.getUser().getMchKey(); // 微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位)      LOGGER.debug(appid);      LOGGER.debug(mch_id);      LOGGER.debug(key);      String body = body1; // 描述      int total_fee = total_fee1; // 支付金额       Date data = new Date();      String notify_url = "https://www.baidu.com/weixinpay/notify"; // 自己发布在公网回调链接,不然无法访问       String out_trade_no = IdUtils.genOrderName();//IdUtils-->见下面      LOGGER.debug(out_trade_no);      Map<Object, Object> map = WeiXinAtcion.me.weixinPlay(mch_id, appid,            key, openid, total_fee, out_trade_no, notify_url, body);      return map;   } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();   }   return TTResult.fail();}

 

6.微信退款

/** *  * @param request * @param database * @param out_trade_no * @param all_total_fee * @param refund_fee * @return */@RequestMapping("/WeiXinRefund")public @ResponseBody Object WeiXinRefund(HttpServletRequest request,      @RequestParam("out_trade_no") String out_trade_no,      @RequestParam("all_total_fee") int all_total_fee,      @RequestParam("refund_fee") int refund_fee) {   try {      LOGGER.debug("订单号是--->"+out_trade_no);      LOGGER.debug("总金额--->"+all_total_fee);      LOGGER.debug("剩余金额--->"+refund_fee);      // out_trade_no 退款订单号      // all_total_fee 订单金额      // refund_fee  输0  all_total_fee-refund_fee=退款的金额      String appid = userService.getUser().getAppid(); // 微信小程序--》“开发者ID”      String mch_id = userService.getUser().getMchId(); // 商户号,将该值赋值给partner      String key = userService.getUser().getMchKey(); // 微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位)      Map<String, String> refundmap = WeiXinAtcion.me.wechatRefund(            request, mch_id, appid, key, out_trade_no, all_total_fee,            refund_fee, userService.getUser().getCert());      if (refundmap.get("return_code").equals("SUCCESS")) {         if (refundmap.get("result_code").equals("FAIL")) {            LOGGER.debug("退款失败:原因" + refundmap.get("err_code_des"));         } else {            LOGGER.debug("退款成功");            return TTResult.ok();         }      } else {         LOGGER.debug("退款失败:原因" + refundmap.get("return_ms"));         return TTResult.fail();      }   } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();   }   return TTResult.fail();}

 

5.将调用微信付款、退款封装

import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.mj.mall.user.service.UserService;import com.mj.pay.util.WXUtil;@Controllerpublic class WeiXinAtcion {    public static final WeiXinAtcion me = new WeiXinAtcion();    private static final Logger LOGGER = LoggerFactory            .getLogger(WeiXinAtcion.class);    @Autowired    private UserService userService;    /**     * 退款     */    public static Map<String, String> wechatRefund(HttpServletRequest request, String mch_id, String appid, String key, String out_trade_no, int all_total_fee, int refund_fee, String apiclient_certLocationp12) throws Exception {        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();        LOGGER.debug("走到退款函数了");        packageParams.put("appid", appid);        packageParams.put("mch_id", mch_id);        packageParams.put("op_user_id", mch_id);        packageParams.put("nonce_str", WXUtil.generate());        packageParams.put("out_trade_no", out_trade_no);        packageParams.put("out_refund_no", WXUtil.generate());        packageParams.put("total_fee", String.valueOf(all_total_fee));        packageParams.put("refund_fee", String.valueOf(all_total_fee - refund_fee));        String sign = WXUtil.createSign_ChooseWXPay("UTF-8", packageParams, key);        packageParams.put("sign", sign);        String XML = WXUtil.getRequestXml(packageParams);        LOGGER.debug("退款函数结束,接下来执行退款操作");        return WXUtil.doRefund(request, "https://api.mch.weixin.qq.com/secapi/pay/refund", XML, mch_id, apiclient_certLocationp12);    }    /**     * 生成微信订单     */    public SortedMap<Object, Object> weixinPlay(String mch_id, String appid, String key, String openid, int total_fee, String out_trade_no, String notify_url, String body) throws UnsupportedEncodingException, DocumentException {        SortedMap<Object, Object> paymentPo = new TreeMap<Object, Object>();        paymentPo.put("appid", appid);        paymentPo.put("mch_id", mch_id);        paymentPo.put("nonce_str", WXUtil.generate());        paymentPo.put("body", body);        paymentPo.put("out_trade_no", out_trade_no);        paymentPo.put("total_fee", String.valueOf(total_fee));        paymentPo.put("spbill_create_ip", "120.77.171.156");//此处是公网ip        paymentPo.put("notify_url", notify_url);        paymentPo.put("trade_type", "JSAPI");        paymentPo.put("openid", openid);        String sign = WXUtil.createSign_ChooseWXPay("UTF-8", paymentPo, key);        paymentPo.put("sign", sign);        String param = WXUtil.getRequestXml(paymentPo);        ;        String request = WXUtil.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", param);        Map<String, String> map = new HashMap<String, String>();         // 将解析结果存储在HashMap中        InputStream in = new ByteArrayInputStream(request.getBytes());        SAXReader reader = new SAXReader();                              // 读取输入流        Document document = reader.read(in);        Element root = document.getRootElement();                        // 得到xml根元素        @SuppressWarnings("unchecked")                                   // 得到根元素的所有子节点                List<Element> elementList = root.elements();        for (Element element : elementList) {            map.put(element.getName(), element.getText());        }        SortedMap<Object, Object> result = new TreeMap<Object, Object>();        LOGGER.debug("第一次签名返回码" + map.get("return_code"));        LOGGER.debug("第一次签名返回结果" + map.get("return_msg"));        //第一次签名成功        if (map.get("return_code").equals("SUCCESS")) {                  // 业务结果            String nonceStr = WXUtil.generate();            Long timeStamp = System.currentTimeMillis() / 1000;            SortedMap<Object, Object> params = new TreeMap<Object, Object>();            params.put("appId", appid);            params.put("nonceStr", nonceStr);            params.put("package", "prepay_id=" + map.get("prepay_id"));            params.put("signType", "MD5");            params.put("timeStamp", timeStamp);            //第二次签名成功            LOGGER.debug("开始第二次签名");            String paySign = WXUtil.createSign_ChooseWXPay("UTF-8", params, key);            result.put("paySign", paySign);            result.put("timeStamp", timeStamp + "");            result.put("nonceStr", nonceStr);            result.put("out_trade_no", paymentPo.get("out_trade_no"));            result.put("package", "prepay_id=" + map.get("prepay_id"));            result.put("return_code", "SUCCESS");        } else {            result.put("return_code", "Fail");            result.put("return_msg", map.get("return_msg"));        }        return result;    }    /**     * 支付成功回调函数     */    @RequestMapping("/weixinpay/notify")    public void weixinpay_notify(HttpServletRequest request, HttpServletResponse response) throws Exception {        InputStream inputStream;        StringBuffer sb = new StringBuffer();        inputStream = request.getInputStream();        String s;        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));        while ((s = in.readLine()) != null) {            sb.append(s);        }        in.close();        inputStream.close();        Map<String, String> m = new HashMap<String, String>();        m = WXUtil.doXMLParse(sb.toString());        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();        Iterator it = m.keySet().iterator();        while (it.hasNext()) {            String parameter = (String) it.next();            String parameterValue = m.get(parameter);            String v = "";            if (null != parameterValue) {                v = parameterValue.trim();            }            packageParams.put(parameter, v);        }        //String key = ""; //秘钥        String key = userService.getUser().getMchKey(); //秘钥        if (WXUtil.isTenpaySign("UTF-8", packageParams, key)) {            String resXml = "";            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {                //得到返回的参数                String openid = (String) packageParams.get("openid");                String transaction_id = (String) packageParams.get("transaction_id");                String out_trade_no = (String) packageParams.get("out_trade_no");                String total_fee = (String) packageParams.get("total_fee");                Float fee = Float.parseFloat(total_fee) / 100;                //这里可以写你需要的业务                System.out.println("openid---->" + openid);                System.out.println("transaction_id---->" + transaction_id);                System.out.println("out_trade_no---->" + out_trade_no);                System.out.println("total_fee---->" + total_fee);                System.out.println("fee---->" + fee);                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());                out.write(resXml.getBytes());                out.flush();                out.close();            } else {                System.out.println("回调失败");            }        } else {            System.out.println("回调失败");        }    }}

8.WXUtil工具类

import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.net.HttpURLConnection;import java.net.URI;import java.net.URL;import java.security.KeyStore;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import java.util.SortedMap;import java.util.UUID;import javax.net.ssl.SSLContext;import javax.servlet.http.HttpServletRequest;import org.apache.http.HttpEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.SSLContexts;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.input.SAXBuilder;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class WXUtil {      private static final Logger LOGGER = LoggerFactory.getLogger(WXUtil.class);   /**    * 随机字符串    * @return    */   public static String generate() {      return UUID.randomUUID().toString().trim().replaceAll("-", "");   }      /**    * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。    */   public static Map doXMLParse(String strxml) throws JDOMException, IOException {      strxml = strxml.replaceFirst("encoding=".*"", "encoding="UTF-8"");      if(null == strxml || "".equals(strxml)) {         return null;      }      Map m = new HashMap();      InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));      SAXBuilder builder = new SAXBuilder();      Document doc = builder.build(in);      Element root = doc.getRootElement();      List list = root.getChildren();      Iterator it = list.iterator();      while(it.hasNext()) {         Element e = (Element) it.next();         String k = e.getName();         String v = "";         List children = e.getChildren();         if(children.isEmpty()) {            v = e.getTextNormalize();         } else {            v = WXUtil.getChildrenText(children);         }         m.put(k, v);      }            //关闭流      in.close();            return m;   }      /**    * 获取子结点的xml    * @param children    * @return String    */   public static String getChildrenText(List children) {      StringBuffer sb = new StringBuffer();      if(!children.isEmpty()) {         Iterator it = children.iterator();         while(it.hasNext()) {            Element e = (Element) it.next();            String name = e.getName();            String value = e.getTextNormalize();            List list = e.getChildren();            sb.append("<" + name + ">");            if(!list.isEmpty()) {               sb.append(WXUtil.getChildrenText(list));            }            sb.append(value);            sb.append("</" + name + ">");         }      }      return sb.toString();   }   /**    * 将请求参数转换为xml格式的string字符串,微信服务器接收的是xml格式的字符串    */   public static String getRequestXml(SortedMap<Object, Object> parameters) {      StringBuffer sb = new StringBuffer();      sb.append("<xml>");      Set<Entry<Object, Object>> es = parameters.entrySet();      Iterator<Entry<Object, Object>> it = es.iterator();      while (it.hasNext()) {         Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) it.next();         String k = (String) entry.getKey();         String v = (String) entry.getValue();                  if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {            sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");         } else {            sb.append("<" + k + ">" + v + "</" + k + ">");         }      }      sb.append("</xml>");      return sb.toString();   }      /**    * sign签名,必须使用MD5签名,且编码为UTF-8    */   public static String createSign_ChooseWXPay(String characterEncoding, SortedMap<Object, Object> parameters, String key) {      StringBuffer sb = new StringBuffer();      Set<Entry<Object, Object>> es = parameters.entrySet();      Iterator<Entry<Object, Object>> it = es.iterator();      while (it.hasNext()) {         Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) it.next();         String k = (String) entry.getKey();         Object v = entry.getValue();         if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {            sb.append(k + "=" + v + "&");         }      }      /** 支付密钥必须参与加密,放在字符串最后面 */      sb.append("key=" + key);      String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();      return sign;   }       /**     *      * @param requestUrl 请求地址     * @param requestMethod 请求方法     * @param outputStr 参数     */    public static String httpRequest(String requestUrl,String requestMethod,String outputStr){        // 创建SSLContext        StringBuffer buffer=null;        try{        URL url = new URL(requestUrl);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setRequestMethod(requestMethod);        conn.setDoOutput(true);        conn.setDoInput(true);        conn.connect();        //往服务器端写内容        if(null !=outputStr){            OutputStream os=conn.getOutputStream();            os.write(outputStr.getBytes("utf-8"));            os.close();        }        // 读取服务器端返回的内容        InputStream is = conn.getInputStream();        InputStreamReader isr = new InputStreamReader(is, "utf-8");        BufferedReader br = new BufferedReader(isr);        buffer = new StringBuffer();        String line = null;        while ((line = br.readLine()) != null) {             buffer.append(line);         }        }catch(Exception e){            e.printStackTrace();        }        return buffer.toString();        }       public static String urlEncodeUTF8(String source){        String result=source;        try {            result=java.net.URLEncoder.encode(source, "UTF-8");        } catch (UnsupportedEncodingException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return result;    }          /**    * 退款     */   public static Map<String, String> doRefund(HttpServletRequest request,String url,String data,String partner,String apiclient_certLocation) throws Exception {   // p12证书的位置         // 微信公众平台:“微信支付”--》“商户信息”--》“交易数据”--》“详情请登录微信支付商户平台查看”(登录)--》“API安全”--》“API证书”--》“下载证书”         // 下载证书后将apiclient_cert.p12放在src目录下面(出于安全考虑,请自行下载自己的证书)         KeyStore keyStore = KeyStore.getInstance("PKCS12");         String url2 = request.getSession().getServletContext().getRealPath("/")               + "images/cert/" + apiclient_certLocation;         LOGGER.debug("url2--->"+url2);         File file=new File(url2);         LOGGER.debug("new了一个file");         FileInputStream instream = new FileInputStream(file);// P12文件目录         LOGGER.debug("退款路径结束");        try {            keyStore.load(instream, partner.toCharArray());        } finally {            instream.close();        }        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, partner.toCharArray()).build();        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();        try {           HttpPost httpost = new HttpPost(url); // 设置响应头信息           httpost.addHeader("Connection", "keep-alive");           httpost.addHeader("Accept", "*/*");           httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");           httpost.addHeader("Host", "api.mch.weixin.qq.com");           httpost.addHeader("X-Requested-With", "XMLHttpRequest");           httpost.addHeader("Cache-Control", "max-age=0");           httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");          httpost.setEntity(new StringEntity(data, "UTF-8"));            CloseableHttpResponse response = httpclient.execute(httpost);            try {               HttpEntity entity = response.getEntity();                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");                EntityUtils.consume(entity);                return WXUtil.doXMLParse(jsonStr);            } finally {                response.close();            }        } finally {            httpclient.close();        }    }        /**      * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。      */      public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {          StringBuffer sb = new StringBuffer();          Set es = packageParams.entrySet();          Iterator it = es.iterator();          while(it.hasNext()) {              Map.Entry entry = (Map.Entry)it.next();              String k = (String)entry.getKey();              String v = (String)entry.getValue();              if(!"sign".equals(k) && null != v && !"".equals(v)) {                  sb.append(k + "=" + v + "&");              }          }          sb.append("key=" + API_KEY);          //算出摘要          String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();          String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();                    //System.out.println(tenpaySign + "    " + mysign);          return tenpaySign.equals(mysign);      }  }

 

9.IdUtils工具类

import java.util.Random;public class IdUtils {   /**    * 图片名生成    */   public static String genImageName() {      //取当前时间的长整形值包含毫秒      long millis = System.currentTimeMillis();      //long millis = System.nanoTime();      //加上三位随机数      Random random = new Random();      int end3 = random.nextInt(999);      //如果不足三位前面补0      String str = millis + String.format("%03d", end3);            return str;   }      /**    * 订单号生成    * @return    */   public static String genOrderName() {      //取当前时间的长整形值包含毫秒      long millis = System.currentTimeMillis();      //long millis = System.nanoTime();      //加上六位随机数      Random random = new Random();      long end6 = random.nextInt(999999);      //如果不足三位前面补0      String str = millis + String.format("%06d", end6);            return str;   }}

 

10.MD5Util工具类

import java.security.MessageDigest;public class MD5Util {   private static String byteArrayToHexString(byte b[]) {      StringBuffer resultSb = new StringBuffer();      for (int i = 0; i < b.length; i++)         resultSb.append(byteToHexString(b[i]));      return resultSb.toString();   }   private static String byteToHexString(byte b) {      int n = b;      if (n < 0)         n += 256;      int d1 = n / 16;      int d2 = n % 16;      return hexDigits[d1] + hexDigits[d2];   }    public static String MD5Encode(String origin, String charsetname) {             String resultString = null;             try {                 resultString = new String(origin);                 MessageDigest md = MessageDigest.getInstance("MD5");                 if (charsetname == null || "".equals(charsetname))                     resultString = byteArrayToHexString(md.digest(resultString                             .getBytes()));                 else                     resultString = byteArrayToHexString(md.digest(resultString                             .getBytes(charsetname)));             } catch (Exception exception) {             }             return resultString;         }        private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",      "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };}

 

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎