天天看點

小程式微信支付請求,java服務端接口編寫

請求過程:  小程式端,先送出微信支付請求,服務端擷取請求。然後再向微信發生支付請求,微信擷取服務端送出的支付請求。根據api文檔裡的notify_url(設定接收回報結果的路徑)傳回給服務端。伺服器接收到微信端的結果之後,再把相應參數傳回給小程式,小程式端再請調取微信支付接口,生成訂單,最後客戶完成支付。然後通知微信支付成功,整個過程就是這樣,下面貼出詳細的代碼;

小程式微信支付api文檔 :https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1

//首先服務端得有個接口,來接收 小程式端來 送出支付請求

    @RequestMapping(value = "addWaybillTest", produces ="application/json;charset=UTF-8")    

    @ResponseBod

public Map addWaybillTest(HttpServletRequest request,HttpServletResponse response,@RequestBody   MlApiEntity mlApiEntity) {

            Map<String, Object> resultMap=new HashMap();

        try {            //得到一個時間戳

                        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

                        String str = sdf.format(new Date());

                        String  body="MLSystem"+"礦泉水2瓶測試";

                        String total_fee="1";

                    String notify_url="擷取微信支付通知接口URL,自定義" ;

                        String openId=WxCommon.getOpenId(mlApiEntity.getCode());

                        //先微信支付

                        resultMap    =WxCommon.wexinPlace( body, "220", total_fee, request, notify_url, openId);

        } catch (Exception e) {

            e.printStackTrace();

            loger.info("checkLogin=============error====" + e);

            resultMap.put("result", "系統伺服器繁忙,請稍候!");

            e.printStackTrace();

        }

        return resultMap;    

    }

//微信支付工具類

public class WxCommon {

        private static String appid="";

        private static String secret="";

        private static String mch_id="";

        private static String key="";

    //擷取oppenid

    public  static String getOpenId(String code){

        Map<String, String>params=new HashMap();

        params.put("appid", appid);

        params.put("secret",secret );

        params.put("js_code", code);

        params.put("grant_type", "authorization_code");

        String result=HttpXmlClient.post("https://api.weixin.qq.com/sns/jscode2session", params);

        JSONObject jsonObj = JSONObject.fromObject(result);

        if(jsonObj.has("openid")){

                String openid=jsonObj.getString("openid");

                if("".equals(openid)){

                    return "invalidCode";

                }else{

                    return openid;

                }

        }else{

            return "invalidCode";

        }

    }

        //統一下單

  public  static Map wexinPlace(  String body,String waybillNo,String total_fee,HttpServletRequest request,String notify_url,String account){

            Map<String, String> paramMap=new HashMap();

            paramMap.put("appid", appid);

            paramMap.put("mch_id", mch_id);

            paramMap.put("device_info", "WEB");

            paramMap.put("nonce_str", GeneratePwd.genRandomNum(32));

            paramMap.put("sign_type","MD5");

            paramMap.put("body",body);

            paramMap.put("out_trade_no",waybillNo);

            paramMap.put("total_fee",total_fee);

            paramMap.put("spbill_create_ip",getIpAddr(request));

            paramMap.put("notify_url",notify_url);

            paramMap.put("trade_type","JSAPI");

            paramMap.put("openid",account);

            paramMap.put("sign",  createSign(paramMap));

              // 把參數轉換成XML資料格式

            String xmlWeChat = assembParamToXml(paramMap);

     String resXml = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlWeChat);

            Map<String, String> resMap = null;

            if (!StrUtil.isBlank(resXml)) {

                try {

                    resMap = parseXMLToMap(resXml);

                } catch (IOException e) {

                    e.printStackTrace();

                } catch (JDOMException e) {

                    e.printStackTrace();

                }

            }

            Map<String, String> map = new HashMap();

            if (resMap == null) {

                map.put("status", "false");

                return map;

            }

            String return_code = resMap.get("return_code");

            if (return_code.equalsIgnoreCase("FAIL")) {

                map.put("message", resMap.get("return_msg"));

                map.put("status", "false");

                return map;

            } else if (return_code.equalsIgnoreCase("SUCCESS")) {

                String err_code = resMap.get("err_code");

                if (!StrUtil.isBlank(err_code)) {

                    map.put("status", "false");

                    map.put("message", resMap.get("err_code_des"));

                } else if (resMap.get("result_code").equalsIgnoreCase("SUCCESS")) {

                    map.put("appId",appid);

                    // 時間戳 目前的時間 需要轉換成秒

                    map.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));

                    // 随機字元串 不長于32位

                    map.put("nonceStr", GeneratePwd.genRandomNum(32));

                    // 訂單詳情擴充字元串 統一下單接口傳回的prepay_id參數值,送出格式如:prepay_id=***

                    map.put("package", "prepay_id=" + resMap.get("prepay_id"));

                    // 簽名方式 簽名算法,暫支援MD5

                    map.put("signType", "MD5");

                    // 簽名

                    map.put("paySign", createSign(map));

                    map.remove("appId");

                    map.put("status", "true");

                }else {

                    map.put("status", "false");

                }

            }

            return map;

        }

        public static String createSign(Map<String, String> param) {

            //簽名步驟一:按字典排序參數

            List list = new ArrayList(param.keySet());

            Object[] ary = list.toArray();

            Arrays.sort(ary);

            list = Arrays.asList(ary);

            String str = "";

            for (int i = 0; i < list.size(); i++) {

                str += list.get(i) + "=" + param.get(list.get(i) + "") + "&";

            }

            //簽名步驟二:加上key

            str += "key=" + key;

            System.err.println(str);

            //步驟三:加密并大寫

            str = MD5Util.md5(str).toUpperCase();

            return str;

        }

        public static String getIpAddr(HttpServletRequest request) {

            String ip = request.getHeader("X-Real-IP");

            if (!StrUtil.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {

                if (ip.contains("../") || ip.contains("..\\")) {

                    return "";

                }

                return ip;

            }

            ip = request.getHeader("X-Forwarded-For");

            if (!StrUtil.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {

                // 多次反向代理後會有多個IP值,第一個為真實IP。

                int index = ip.indexOf(',');

                if (index != -1) {

                    ip = ip.substring(0, index);

                }

                if (ip.contains("../") || ip.contains("..\\")) {

                    return "";

                }

                return ip;

            } else {

                ip = request.getRemoteAddr();

                if (ip.contains("../") || ip.contains("..\\")) {

                    return "";

                }

                if (ip.equals("0:0:0:0:0:0:0:1")) {

                    ip = "127.0.0.1";

                }

                return ip;

            }

        }

     // 通知微信正确接收

        public static void noticeWeChatSuccess(String weiXinPayUrl) {

            Map<String, String> parames = new HashMap<String, String>();

            parames.put("return_code", "SUCCESS");

            parames.put("return_msg", "OK");

            // 将參數轉成xml格式

            String xmlWeChat = assembParamToXml(parames);

            try {

                if (!StrUtil.isBlank(weiXinPayUrl)) {

                    String s = HttpUtil.post(weiXinPayUrl, xmlWeChat);

                }

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        // 通知微信錯誤

        public static void noticeWeChatFAIL(String weiXinPayUrl) {

            Map<String, String> parames = new HashMap<String, String>();

            parames.put("return_code", "FAIL");

            parames.put("return_msg", "校驗錯誤");

            // 将參數轉成xml格式

            String xmlWeChat = assembParamToXml(parames);

            try {

                if (!StrUtil.isBlank(weiXinPayUrl)) {

                    String s = HttpUtil.post(weiXinPayUrl, xmlWeChat);

                }

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        public static Map parseXMLToMap(String strxml) throws IOException, JDOMException {

            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 = getChildrenText(children);

                }

                m.put(k, v);

            }

            //關閉流

            in.close();

            return m;

        }

        private 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(getChildrenText(list));

                    }

                    sb.append(value);

                    sb.append("</" + name + ">");

                }

            }

            return sb.toString();

        }

        private static String assembParamToXml(Map<String, String> parameters) {

            StringBuffer sb = new StringBuffer();

            sb.append("<xml>");

            Set<String> es = parameters.keySet();

            List<Object> list = new ArrayList<Object>(es);

            Object[] ary = list.toArray();

            Arrays.sort(ary);

            list = Arrays.asList(ary);

            Iterator<Object> it = list.iterator();

            while (it.hasNext()) {

                String key = (String) it.next();

                String val = (String) parameters.get(key);

 if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) {

                    sb.append("<" + key + ">" + "<![CDATA[" + val + "]]></" + key + ">");

                } else {

                    sb.append("<" + key + ">" + val + "</" + key + ">");

                }

            }

            sb.append("</xml>");

            return sb.toString();

        }

        public static String getWeiXinResponse(HttpServletRequest request) {

            BufferedReader bis = null;

            String result = "";

            try {

                bis = new BufferedReader(new InputStreamReader(request.getInputStream()));

                String line = null;

                while ((line = bis.readLine()) != null) {

                    result += line;

                }

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

                if (bis != null) {

                    try {

                        bis.close();

                    } catch (IOException e) {

                        e.printStackTrace();

                    }

                }

            }

            return result;

        }

}

    @RequestMapping(value = "wxPayResult", produces ="application/json;charset=UTF-8")    

    @ResponseBody

    public void wxPayResult(HttpServletRequest request,HttpServletResponse response)throws Exception {

            String resXml=WxCommon.getWeiXinResponse(request);//位元組流 轉換成 字元流

              Map<String, String> resMap = null;

         if (!StrUtil.isBlank(resXml)) {

                try {

                    resMap = WxCommon.parseXMLToMap(resXml);

                } catch (IOException e) {

                    e.printStackTrace();

                } catch (JDOMException e) {

                    e.printStackTrace();

                }

            }

          Map<String, String> map = new HashMap();

            if (resMap != null) {

                  String return_code = resMap.get("return_code");

                  if(return_code.equals("FAIL")){

                      String return_msg="";

                      return_msg=resMap.get("return_msg");

                      loger.info("===========================微信支付接口調用失敗,傳回結果=====================" +return_msg);

                   }else if(return_code.equals("SUCCESS")){

                       String result_code=resMap.get("result_code");

                       if(result_code.equals("SUCCESS")){

                           String sign=resMap.get("sign");

                           resMap.remove("sign");

                           String result=WxCommon.createSign(resMap);

                           if(sign.equals(result)){

                              String out_trade_no=resMap.get("out_trade_no");

                               WxCommon.noticeWeChatSuccess("https://api.mch.weixin.qq.com/pay/unifiedorder");//支付成功後我們要通知微信

loger.info("===========================微信支付成=====================");

             }

                 }else{

loger.info("===========================微信支付失=====================" );

                           }

                         }else if(result_code.equals("FAIL")){

                              String err_code=resMap.get("err_code");

                                 if(!StrUtil.isBlank(err_code)){

             loger.info("===========================微信支付失敗:錯誤傳回的資訊描述:====================="+err_code );

                                     String err_code_des=resMap.get("err_code_des");

                                     if(!StrUtil.isBlank(err_code_des)){

                                        loger.info("===========================微信支付失敗:錯誤傳回的資訊描述:====================="+err_code_des );

                                     }

                                 }else{

                                 }

                         }

                  }

            }

     }

繼續閱讀