国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

微信小程序 支付后臺java實現實例

2019-11-19 16:37:39
字體:
來源:轉載
供稿:網友

微信小程序 支付后臺java實現實例

前言:

前些天使用 LeanCloud 云引擎寫了個小程序的支付相關 以前只做過 APP 支付 這次在小程序支付爬了兩天的坑 把代碼也分享出來

支付流程:

1.小程序前端獲取微信 openId 以及訂單號 傳給后臺
2,后臺根據 openId 和訂單號進行簽名 post 微信統一下單接口
3.后臺獲取微信返回的xml字符串 解析 二次簽名以后返回給前端
4.前端調起支付微信支付 API

先看支付函數:

//獲取支付信息  @EngineFunction("getPayInformation")  public static Map<String, Object> getPayInformation(      @EngineFunctionParam("orderId") String orderId  ) throws AVException, UnsupportedEncodingException, DocumentException {    Map<String, Object> reqMap = new TreeMap<String, Object>(        new Comparator<String>() {          public int compare(String obj1, String obj2) {            // 升序排序            return obj1.compareTo(obj2);          }        });    if (AVUser.getCurrentUser() != null) {      String authDataJson = JSONArray.toJSONString(AVUser.getCurrentUser().get("authData"));      JSONObject jsonObject = JSON.parseObject(authDataJson);      jsonObject.get("lc_weapp");      JSONObject j2 = JSON.parseObject(jsonObject.get("lc_weapp").toString());      String openId = (String) j2.get("openid");      AVQuery<Order> query = AVObject.getQuery(Order.class);      Order order = query.get(orderId);      reqMap.put("appid", System.getenv("appid"));      reqMap.put("mch_id", System.getenv("mch_id"));      reqMap.put("nonce_str", WXPayUtil.getNonce_str());      reqMap.put("body", new String(order.getDishesList().toString().getBytes("UTF-8")));      reqMap.put("openid", openId);      reqMap.put("out_trade_no", order.getObjectId());      reqMap.put("total_fee", 1); //訂單總金額,單位為分      reqMap.put("spbill_create_ip", "192.168.0.1"); //用戶端ip      reqMap.put("notify_url", System.getenv("notify_url")); //通知地址      reqMap.put("trade_type", System.getenv("trade_type")); //trade_type=JSAPI時(即公眾號支付),此參數必傳,此參數為微信用戶在商戶對應appid下的唯一標識      String reqStr = WXPayUtil.map2Xml(reqMap);      String resultXml = HttpRequest.sendPost(reqStr);      System.out.println("微信請求返回:" + resultXml);      //解析微信返回串 如果狀態成功 則返回給前端      if (WXPayUtil.getReturnCode(resultXml) != null && WXPayUtil.getReturnCode(resultXml).equals("SUCCESS")) {        //成功        Map<String, Object> resultMap = new TreeMap<>(            new Comparator<String>() {              public int compare(String obj1, String obj2) {                // 升序排序                return obj1.compareTo(obj2);              }            });        resultMap.put("appId", System.getenv("appid"));        resultMap.put("nonceStr", WXPayUtil.getNonceStr(resultXml));//解析隨機字符串        resultMap.put("package", "prepay_id=" + WXPayUtil.getPrepayId(resultXml));        resultMap.put("signType", "MD5");        resultMap.put("timeStamp", String.valueOf((System.currentTimeMillis() / 1000)));//時間戳        String paySign = WXPayUtil.getSign(resultMap);        resultMap.put("paySign", paySign);        return resultMap;      } else {        throw new AVException(999, "微信請求支付失敗");      }    } else {      throw new AVException(98, "當前未登錄用戶");    }  }

其中appid和mch_id可以用系統常量

PS:這里注意一個坑

二次簽名的時候使用 appId nonceStr package signType timeStamp 這五個key生成簽名(這里無視微信官方文檔 以及注意 appId 的大小寫)

前端調起API支付時 按照官方文檔就可以

網絡請求類:

HttpRequest

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.URL;import java.net.URLConnection;import java.util.List;import java.util.Map;public class HttpRequest {  /**   * 向指定URL發送GET方法的請求   *   * @param url  發送請求的URL   * @param param 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。   * @return URL 所代表遠程資源的響應結果   */  public static String sendGet(String url, String param) {    String result = "";    BufferedReader in = null;    try {      String urlNameString = url + "?" + param;      URL realUrl = new URL(urlNameString);      // 打開和URL之間的連接      URLConnection connection = realUrl.openConnection();      // 設置通用的請求屬性      connection.setRequestProperty("accept", "*/*");      connection.setRequestProperty("connection", "Keep-Alive");      connection.setRequestProperty("user-agent",          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");      // 建立實際的連接      connection.connect();      // 獲取所有響應頭字段      Map<String, List<String>> map = connection.getHeaderFields();      // 遍歷所有的響應頭字段      for (String key : map.keySet()) {        System.out.println(key + "--->" + map.get(key));      }      // 定義 BufferedReader輸入流來讀取URL的響應      in = new BufferedReader(new InputStreamReader(          connection.getInputStream()));      String line;      while ((line = in.readLine()) != null) {        result += line;      }    } catch (Exception e) {      System.out.println("發送GET請求出現異常!" + e);      e.printStackTrace();    }    // 使用finally塊來關閉輸入流    finally {      try {        if (in != null) {          in.close();        }      } catch (Exception e2) {        e2.printStackTrace();      }    }    return result;  }  /**   * 向指定 URL 發送POST方法的請求   *   * @param url  發送請求的 URL   * @param param 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。   * @return 所代表遠程資源的響應結果   */  public static String sendPost(String param) {    PrintWriter out = null;    BufferedReader in = null;    String result = "";    try {      URL realUrl = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");      // 打開和URL之間的連接      URLConnection conn = realUrl.openConnection();      // 設置通用的請求屬性      conn.setRequestProperty("accept", "*/*");      conn.setRequestProperty("connection", "Keep-Alive");      conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");//      conn.setRequestProperty("Pragma:", "no-cache");//      conn.setRequestProperty("Cache-Control", "no-cache");//      conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");      // 發送POST請求必須設置如下兩行      conn.setDoOutput(true);      conn.setDoInput(true);      // 獲取URLConnection對象對應的輸出流      out = new PrintWriter(conn.getOutputStream());      // 發送請求參數      out.print(param);      // flush輸出流的緩沖      out.flush();      // 定義BufferedReader輸入流來讀取URL的響應      in = new BufferedReader(          new InputStreamReader(conn.getInputStream()));      String line;      while ((line = in.readLine()) != null) {        result += line;      }    } catch (Exception e) {      System.out.println("發送 POST 請求出現異常!" + e);      e.printStackTrace();    }    //使用finally塊來關閉輸出流、輸入流    finally {      try {        if (out != null) {          out.close();        }        if (in != null) {          in.close();        }      } catch (IOException ex) {        ex.printStackTrace();      }    }    return result;  }}

XML解析工具類

WXPayUtil

import org.w3c.dom.NodeList;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.util.Map;import java.util.Random;public class WXPayUtil {  //生成隨機字符串  public static String getNonce_str() {    String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";    Random random = new Random();    StringBuilder sb = new StringBuilder();    for (int i = 0; i < 15; i++) {      int number = random.nextInt(base.length());      sb.append(base.charAt(number));    }    return sb.toString();  }  //map轉xml 加上簽名信息  public static String map2Xml(Map<String, Object> map) throws UnsupportedEncodingException {    StringBuffer sb = new StringBuffer();    StringBuilder sb2 = new StringBuilder();    sb2.append("<xml>");    for (String key : map.keySet()) {      sb.append(key);      sb.append('=');      sb.append(map.get(key));      sb.append('&');      // sb2是用來做請求的xml參數      sb2.append("<" + key + ">");//      sb2.append("<![CDATA[" + map.get(key) + "]]>");      sb2.append(map.get(key));      sb2.append("</" + key + ">");    }    sb.append(System.getenv("signKey"));    String sign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();    sb2.append("<sign>");    sb2.append(sign);    sb2.append("</sign>");    sb2.append("</xml>");    return sb2.toString();  }  //解析微信返回return_code SUCCESS或FILE  //根據微信返回resultXml再次生成簽名  public static String getSign(Map<String, Object> map) {    StringBuffer sb = new StringBuffer();    for (String key : map.keySet()) {      sb.append(key);      sb.append('=');      sb.append(map.get(key));      sb.append('&');    }    sb.append(System.getenv("signKey"));    System.out.println("第二次簽名內容:" + sb);    System.out.println("第二次簽名SING:" + MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase());    return MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();  }  //解析微信返回return_code SUCCESS或FILE  public static String getReturnCode(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("return_code");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  //解析微信返回return_msg  public static String getReturn_msg(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("return_msg");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  //解析微信返回appid  public static String getAppId(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("appid");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  //解析微信返回mch_id  public static String getMchId(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("mch_id");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  //解析微信返回nonce_str  public static String getNonceStr(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("nonce_str");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  //解析微信返回prepay_id  public static String getPrepayId(String resultXml) {    String nonceStr;    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    DocumentBuilder builder;    try {      builder = dbf.newDocumentBuilder();      InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());      org.w3c.dom.Document doc = builder.parse(inputStream); //      // 下面開始讀取      org.w3c.dom.Element root = doc.getDocumentElement(); // 獲取根元素      NodeList nl = root.getElementsByTagName("prepay_id");      org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);      org.w3c.dom.Node nd = el.getFirstChild();      nonceStr = nd.getNodeValue();      return nonceStr;    } catch (Exception e) {      e.printStackTrace();      return null;    }  }}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 封丘县| 天津市| 论坛| 赤城县| 静安区| 紫云| 靖边县| 奎屯市| 无极县| 阿尔山市| 新宾| 湘潭县| 长汀县| 惠水县| 安仁县| 抚宁县| 大田县| 息烽县| 金川县| 巫山县| 东乌珠穆沁旗| 镇雄县| 通山县| 城步| 祁连县| 凉城县| 清徐县| 且末县| 冀州市| 沿河| 合水县| 阿克苏市| 江达县| 钟山县| 温州市| 秦皇岛市| 蕉岭县| 柏乡县| 安仁县| 寿光市| 密云县|