微信掃碼支付(模式一)

項目開源地址:http://git.oschina.net/javen205/weixin_guidephp

微信掃碼支付(模式一)你有測試成功嗎?若是你看到了這篇文章,我想你是在測試中遇到問題了。OK 那如今咱們來看看微信掃碼支付中的坑。

git

 

解決問題算法

  • 原生支付URL參數錯誤

    這個錯誤通常會出如今獲取到二維碼URL以後生成二維碼微信掃碼的時候。若是你出現此類型的問題請檢查

    一、生成二維碼所需參數列表中參數是否有錯誤(區分大小寫)
    二、參數中籤名
    sign時候正確 簽名算法  簽名校驗工具

    如下是生成二維碼URL的代碼
    /**
         * 
         * @author Javen
         * 2016年5月14日
         * 掃碼支付獲取二維碼URL(模式一)
         */
        public String getCodeUrl(){
            String url="weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
            String product_id="001";
            String timeStamp=Long.toString(System.currentTimeMillis() / 1000);
            String nonceStr=Long.toString(System.currentTimeMillis());
            Map<String, String> packageParams = new HashMap<String, String>();
            packageParams.put("appid", appid);
            packageParams.put("mch_id", partner);
            packageParams.put("product_id",product_id);
            packageParams.put("time_stamp", timeStamp);
            packageParams.put("nonce_str", nonceStr);
            String packageSign = PaymentKit.createSign(packageParams, paternerKey);
            
            return StringUtils.replace(url, "XXXXX", packageSign,appid,partner,product_id,timeStamp,nonceStr);
        }

     



  • 回調接口URL有回調,可是接收不到參數
    Enumeration<String>  en=getParaNames();
            while (en.hasMoreElements()) {
                Object o= en.nextElement();
                System.out.println(o.toString()+"="+getPara(o.toString()));
            }

    以上代碼中輸出的參數都爲NULLapi


    因爲官方的文檔描述不是很清楚,你們都覺得回調請求將帶productid和用戶的openid等參數是以普通的參數同樣,其實這個回調返回的參數是一個XML輸入流
    HttpServletRequest request = getRequest();
                 /**
                 * 獲取用戶掃描二維碼後,微信返回的信息
                 */
                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();
                inStream.close();
                String result  = new String(outSteam.toByteArray(),"utf-8");

    result結果爲服務器

    <xml>
    <appid><![CDATA[wx5e9360a3f46f64cd]]></appid>
    <openid><![CDATA[o_pncsidC-pRRfCP4zj98h6slREw]]></openid>
    <mch_id><![CDATA[1322117501]]></mch_id>
    <is_subscribe><![CDATA[Y]]></is_subscribe>
    <nonce_str><![CDATA[y4dGR6JxuybgUWUo]]></nonce_str>
    <product_id><![CDATA[001]]></product_id>
    <sign><![CDATA[89951BAE8796DE7D32E9741E42C35FB4]]></sign>
    </xml>



    若是以上都沒有出現問題,下面就要根據product_id來生成(統計下單接口)預付訂單了
    如下是正確返回的XML數據微信

    <xml>
    <
    return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx5e9360a3f46f64cd]]></appid> <mch_id><![CDATA[1322117501]]></mch_id> <nonce_str><![CDATA[lr3cCuO2KxMEBHIW]]></nonce_str> <sign><![CDATA[842C1857EDD009D67519527BCF3AFA4C]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <prepay_id><![CDATA[wx201605151311568e801d50fb0555050106]]></prepay_id> <trade_type><![CDATA[NATIVE]]></trade_type> <code_url><![CDATA[weixin://wxpay/bizpayurl?pr=Gj3ZF2b]]></code_url> </xml>

    若是返回的 return_code  result_code 不爲SUCCESS 而回調的接口沒有返回任何數據或者返回的數據不合法就會出現如下錯誤app

    • 商戶後臺返回的數據字段結構不合法(返回的數據包格式不正確)
    • 獲取商戶訂單信息超時或者商戶返回的httpcode非200(沒有返回的數據包)


      若是以上都沒有問題,就剩下最後一個步驟了  商戶後臺系統將prepay_id返回給微信支付系統  如下是詳細的代碼
      /**
           * @author Javen
           * 2016年5月14日
           * 掃碼支付回調(模式一)
           */          
      public void wxpay(){
              try {
                  HttpServletRequest request = getRequest();
                   /**
                   * 獲取用戶掃描二維碼後,微信返回的信息
                   */
                  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();
                  inStream.close();
                  String result  = new String(outSteam.toByteArray(),"utf-8");
                  
                  System.out.println("callback>>>>"+result);
                  /**
                   * 獲取返回的信息內容中各個參數的值
                   */
                  Map<String, String> map = PaymentKit.xmlToMap(result);
                  for (String key : map.keySet()) {
                         System.out.println("key= "+ key + " and value= " + map.get(key));
                  }
                  
                  String appid=map.get("appid");
                  String openid = map.get("openid");
                  String mch_id = map.get("mch_id");
                  String is_subscribe = map.get("is_subscribe");
                  String nonce_str = map.get("nonce_str");
                  String product_id = map.get("product_id");
                  String sign = map.get("sign");
                  Map<String, String> packageParams = new HashMap<String, String>();
                  packageParams.put("appid", appid);
                  packageParams.put("openid", openid);
                  packageParams.put("mch_id",mch_id);
                  packageParams.put("is_subscribe",is_subscribe);
                  packageParams.put("nonce_str",nonce_str);
                  packageParams.put("product_id", product_id);
                  
                  String packageSign = PaymentKit.createSign(packageParams, paternerKey);
                  // 統一下單文檔地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
                  
                  Map<String, String> params = new HashMap<String, String>();
                  params.put("appid", appid);
                  params.put("mch_id", mch_id);
                  params.put("body", "測試掃碼支付");
                  String out_trade_no=Long.toString(System.currentTimeMillis());
                  params.put("out_trade_no", out_trade_no);
                  int price=((int)(Float.valueOf(10)*100));
                  params.put("total_fee", price+"");
                  params.put("attach", out_trade_no);
                  
                  String ip = IpKit.getRealIp(getRequest());
                  if (StrKit.isBlank(ip)) {
                      ip = "127.0.0.1";
                  }
                  
                  params.put("spbill_create_ip", ip);
                  params.put("trade_type", TradeType.NATIVE.name());
                  params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
                  params.put("notify_url", notify_url);
                  params.put("openid", openid);
      
                  String paysign = PaymentKit.createSign(params, paternerKey);
                  params.put("sign", paysign);
                  
                  String xmlResult = PaymentApi.pushOrder(params);
                  
                  System.out.println("prepay_xml>>>"+xmlResult);
                  
                  /**
                   * 發送信息給微信服務器
                   */
                  Map<String, String> payResult = PaymentKit.xmlToMap(xmlResult);
                  
                  String return_code = payResult.get("return_code");
                  String result_code = payResult.get("result_code");
                  
                  if (StrKit.notBlank(return_code) && StrKit.notBlank(result_code) && return_code.equalsIgnoreCase("SUCCESS")&&result_code.equalsIgnoreCase("SUCCESS")) {
                      // 如下字段在return_code 和result_code都爲SUCCESS的時候有返回
                      String prepay_id = payResult.get("prepay_id");
                      
                      Map<String, String> prepayParams = new HashMap<String, String>();
                      prepayParams.put("return_code", "SUCCESS");
                      prepayParams.put("appId", appid);
                      prepayParams.put("mch_id", mch_id);
                      prepayParams.put("nonceStr", System.currentTimeMillis() + "");
                      prepayParams.put("prepay_id", prepay_id);
                      String prepaySign = null;
                      if (sign.equals(packageSign)) {
                          prepayParams.put("result_code", "SUCCESS");
                      }else {
                          prepayParams.put("result_code", "FAIL");
                          prepayParams.put("err_code_des", "訂單失效");   //result_code爲FAIL時,添加該鍵值對,value值是微信告訴客戶的信息
                      }
                      prepaySign = PaymentKit.createSign(prepayParams, paternerKey);
                      prepayParams.put("sign", prepaySign);
                      String xml = PaymentKit.toXml(prepayParams);
                      log.error(xml);
                      renderText(xml);
                  }
              } catch (UnsupportedEncodingException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              
          }    

       


      以上項目開源地址:http://git.oschina.net/javen205/weixin_guide
相關文章
相關標籤/搜索