1. 程式人生 > >微信刷卡支付(被掃支付)

微信刷卡支付(被掃支付)

步驟:
1、掃碼 獲取被掃物件微信支付二維碼 獲得支付授權碼 即微信錢包→付款 裡面那個條形碼上面的那一串數字
2、把授權碼及所需要的引數傳給提交訂單api
3、用查詢訂單api查詢訂單付款情況
4、用while迴圈重複查詢10次 如果都是交易失敗就呼叫撤銷訂單api

用到的jar包:
jar包
(注意專案裡面儘量讓這三個包httpclient和httpcore還有httpmime版本如圖匹配好 而且這三個包在專案裡面都只能出現一個版本 如:httpclient-4.2.4和httpclient-4.3.4都有的情況下 只能保留一個)

wechatscan.java

import java.
net.ConnectException; import java.util.Map; import java.util.TreeMap; import com.demo.dao.PayDao; import com.demo.dao.QueryDao; import com.demo.utils.HttpUtil; import com.demo.utils.XMLUtil; public class wechatscan { public static String appid = ""; //public static String sub_appid = ""; public
static String mch_id = ""; public static String device_info = ""; public static String nonce_str = ""; public static String sign = "";//簽名 //public static String sign_type = ""; //預設MD5 public static String body = ""; public static String detail = ""; public static String attach =
""; public static String out_trade_no = "";//日期+4位隨機數 public static String total_fee = ""; public static String fee_type = ""; public static String spbill_create_ip = ""; public static String goods_tag = ""; public static String auth_code = ""; //public static String sub_mch_id = ""; public static String key = "645yh45y45y45y45y45y45y45y45y5445y"; public static void scanpay(PayDao pd) throws Exception { appid = pd.getAppid()==null?"":pd.getAppid(); //sub_appid = pd.getSub_appid()==null?"":pd.getSub_appid(); mch_id = pd.getMch_id()==null?"":pd.getMch_id(); device_info = pd.getDevice_info()==null?"":pd.getDevice_info(); String currTime = Method.getCurrTime(); String time_start = currTime.substring(8, currTime.length()); String strRandom = Method.buildRandom(4) + ""; nonce_str = time_start + strRandom; //隨機數生成演算法 sign = "";//簽名 body = pd.getBody()==null?"":pd.getBody(); detail = pd.getDetail()==null?"":pd.getDetail(); attach = pd.getAttach()==null?"":pd.getAttach(); String time = currTime.substring(0, currTime.length()); out_trade_no = time+strRandom;//日期+4位隨機數 total_fee = pd.getTotal_fee()==null?"0":pd.getTotal_fee(); fee_type = pd.getFee_type()==null?"":pd.getFee_type(); spbill_create_ip = Method.localIp(); goods_tag = pd.getGoods_tag()==null?"":pd.getGoods_tag(); auth_code = pd.getAuth_code()==null?"":pd.getAuth_code(); //sub_mch_id = pd.getSub_mch_id()==null?"":pd.getSub_mch_id(); String MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay"; Map<Object, String> map = new TreeMap<Object, String>(); map.put("appid", appid); //map.put("sub_appid", sub_appid); map.put("mch_id", mch_id); map.put("device_info", device_info); map.put("nonce_str", nonce_str); map.put("body", body); //map.put("detail", detail); map.put("attach", attach); map.put("out_trade_no", out_trade_no); map.put("fee_type", fee_type); map.put("total_fee", total_fee); map.put("spbill_create_ip", spbill_create_ip); map.put("auth_code", auth_code); //map.put("goods_tag", goods_tag); //map.put("sub_mch_id", sub_mch_id); sign = Method.createSign("UTF-8", map,key); map.put("sign", sign); String requestXML = Method.getRequestXml(map); Map map1 = null; try{ String resXml = HttpUtil.postData(MICROPAY_URL, requestXML); map1 = XMLUtil.doXMLParse(resXml); }catch (ConnectException ce){ System.out.println("連線超時:"+ce.getMessage()); }catch (Exception e){ System.out.println("https請求異常:"+e.getMessage()); } System.out.println("SCAN requestXML::::"+requestXML); System.out.println("SCAN resXml::::"+HttpUtil.postData(MICROPAY_URL, requestXML)); QueryDao qd = new QueryDao(); qd.setAppid(appid); qd.setMch_id(mch_id); qd.setOut_trade_no(out_trade_no); qd.setSub_mch_id(sub_mch_id); int querycount = 10; boolean booleanquery = false; while(querycount>0){ if(wechatquery.orderquery(qd)!=true && querycount>0){ querycount = querycount - 1; booleanquery = false; }else{ querycount = 0; booleanquery = true; } Thread.sleep(500); } if(booleanquery==false&&querycount==0){ wechatcancel.ordercancel(qd); } } }

如果是服務商的話 wechatscan裡面的sub_mch_id一定需要有 sub_appid就可能用到

wechatquery.java

import java.net.ConnectException;
import java.util.Map;
import java.util.TreeMap;

import com.demo.dao.QueryDao;
import com.demo.utils.HttpUtil;
import com.demo.utils.XMLUtil;

public class wechatquery {

public static boolean orderquery(QueryDao qd) throws Exception {

        int successcode = 0;  //0 success   1 fail
        String appid = qd.getAppid()==null?"":qd.getAppid();
        String sub_appid = qd.getSub_appid()==null?"":qd.getSub_appid();
        String mch_id = qd.getMch_id()==null?"":qd.getMch_id();

        String currTime = Method.getCurrTime(); 
        String time_start = currTime.substring(8, currTime.length());
        String strRandom = Method.buildRandom(4) + "";
        String nonce_str = time_start + strRandom; //隨機數生成演算法

        String sign = "";//簽名
        //String sign_type = ""; //預設MD5

        String out_trade_no = qd.getOut_trade_no()==null?"":qd.getOut_trade_no();//商戶系統內部的訂單號,微信訂單號、商戶訂單號二選一必傳

        String sub_mch_id = qd.getSub_mch_id()==null?"":qd.getSub_mch_id();

        String transaction_id = qd.getTransaction_id()==null?"":qd.getTransaction_id();

        String QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

        String key = "645yh45y45y45y45y45y45y45y45y5445y";

        Map<Object, String> map = new TreeMap<Object, String>();
        map.put("appid", appid);
        map.put("sub_appid", sub_appid);
        map.put("mch_id", mch_id);
        map.put("nonce_str", nonce_str);
        //map.put("sign_type", sign_type);
        map.put("out_trade_no", out_trade_no);
        map.put("sub_mch_id", sub_mch_id);
        map.put("transaction_id", transaction_id);
        sign = Method.createSign("UTF-8", map,key);
        map.put("sign", sign);

        String requestXML = Method.getRequestXml(map);
        Map map1 = null;

        try{
            String resXml = HttpUtil.postData(QUERY_URL, requestXML);
            map1 = XMLUtil.doXMLParse(resXml);
            System.out.println(map1.get("result_code"));
        }catch (ConnectException ce){
            System.out.println("連線超時:"+ce.getMessage());
        }catch (Exception e){
            System.out.println("https請求異常:"+e.getMessage());
        }

        System.out.println("QUERY requestXML::::"+requestXML);
        System.out.println("QUERY resXml::::"+HttpUtil.postData(QUERY_URL, requestXML));

        if(map1.get("return_code").equals("SUCCESS")&& map1.get("result_code").equals("SUCCESS")){
            if(map1.get("trade_state").equals("SUCCESS")){
                successcode = 0;
            }else if(map1.get("trade_state").equals("USERPAYING")){
                successcode = 1;
            }
        }else{
            successcode = 1;
        }

        if(successcode == 0){
            return true;
        }else{
            return false;
        }

    }
}

這個是查詢訂單的 wechatscan把獲取的資料發到微信伺服器之後 就要用這個類來對訂單狀態查詢 然後決定後面應該是交易成功好似撤銷訂單

wechatcancel.java

import java.net.ConnectException;
import java.util.Map;
import java.util.TreeMap;

import com.demo.dao.QueryDao;
import com.demo.utils.ClientCustomSSL;
import com.demo.utils.HttpUtil;
import com.demo.utils.XMLUtil;

public class wechatcancel {

public static void ordercancel(QueryDao qd) throws Exception {

        String appid = qd.getAppid()==null?"":qd.getAppid();
        String mch_id = qd.getMch_id()==null?"":qd.getMch_id();
        String out_trade_no = qd.getOut_trade_no()==null?"":qd.getOut_trade_no();//商戶系統內部的訂單號,微信訂單號、商戶訂單號二選一必傳
        String sub_mch_id = qd.getSub_mch_id()==null?"":qd.getSub_mch_id();

        String currTime = Method.getCurrTime(); 
        String time_start = currTime.substring(8, currTime.length());
        String strRandom = Method.buildRandom(4) + "";
        String nonce_str = time_start + strRandom; //隨機數生成演算法

        String sign = "";//簽名

        //String QUERY_URL = "https://api.mch.weixin.qq.com/secapi/pay/reverse";

        String key = "645yh45y45y45y45y45y45y45y45y5445y";

        Map<Object, String> map = new TreeMap<Object, String>();
        map.put("appid", appid);
        map.put("mch_id", mch_id);
        map.put("out_trade_no", out_trade_no);
        map.put("sub_mch_id", sub_mch_id);
        map.put("nonce_str", nonce_str);
        sign = Method.createSign("UTF-8", map,key);
        map.put("sign", sign);

        String requestXML = Method.getRequestXml(map);

        ClientCustomSSL clientCustomSSL = new ClientCustomSSL();
        clientCustomSSL.clientcustomSSL(requestXML);

        System.out.println("Cancel resXml::::");


    }
}

最後這個是撤銷訂單的類 這裡要注意的是 需要微信支付平臺上申請退款許可權 獲得一個證書 java的話只用到apiclient_cert.p12 其他語言就需要用到所有證書了 具體怎麼用證書就是寫在ClientCustomSSL裡面 這個東西微信支付官方例子裡面有 直接下載官方demo 就能找到一個ClientCustomSSL.java的檔案 這個基本上直接搬專案就好了

注意事項:
1、金額是以分為單位的 而且不能有小數點
2、注意開發文件裡面寫的 哪一個是必傳引數 就算沒什麼用的 也不能傳空白
3、注意key 這個key是微信支付平臺賬號還是微信公眾號平臺上能找到的 是用來生成簽名用的
4、查詢和掃碼這些不需要證書的 基本上寫法都一樣 不過遇到退款的 寫法就會有改變 不只要生成xml傳給微信伺服器 還要對證書解釋 一起傳微信伺服器才行
5、對應證書 java只用到.p12那個 不過寫php或者asp的時候 就要把所有的都用上
6、clientcustomSSL裡面要配置一下mchid