JAVA實現微信支付V3

喜歡的朋友能夠關注下,粉絲也缺。

相信不少的碼友在項目中都須要接入微信支付,雖然說微信支付已成爲一個廣泛的現象,可是接入的過程當中不免會遇到各類各樣的坑,這一點支付寶的SDK就作的很好,已經完成的都知道了。javascript

下面就開始咱們的代碼之旅,這裏我將給你們提供兩種支付一個是微信公衆號支付,一個是APP微信支付。php

一 微信公衆號支付css

流程:html

1.獲取用戶openid前端

2.獲取token,注意獲取的token是有時效的並且接口是有獲取上線,具體看微信API文檔java

3.拿商品信息(金額,名字等)去請求統一下單接口android

4.統一下單接口獲取預支付ID,後進行二次簽名把參數返回給前端ios

5.前端JS中接收到參數調起支付ajax

6.支付成功頁面跳轉以及回調處理算法

下面咱們就來具體說說功能

GetOpenId:獲取用戶openid

public class GetOpenid extends HttpServlet {
 
	private static final Logger logger = Logger.getLogger(GetOpenid.class);
	
	@SuppressWarnings("unused")
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		HttpSession session = request.getSession();
		PreparedStatement pst=null;
		String username="";
		//獲取code
		String appid=WeiXinUitls.appid;
		
		String code = request.getParameter("code");
		String rturl = request.getParameter("rturl");
 
		String appsecret = WeiXinUitls.appsecret;
		String grant_type = "authorization_code";
		String returnJSON = HttpTool.getToken(appid, appsecret, grant_type,code);
		JSONObject obj = JSONObject.fromObject(returnJSON);
		if(!(obj==null)){
			String openid = obj.get("openid").toString();
			String token = obj.get("access_token").toString();
			String retoken = obj.get("refresh_token").toString();
			//獲取微信用戶
			String getuserinfo = HttpTool.getuserinfo(token, openid);
			JSONObject fromObject = JSONObject.fromObject(getuserinfo);
			String stropenid = fromObject.get("openid").toString();
			session.setAttribute("openid", stropenid);
			String strnickname = fromObject.get("nickname").toString();
			String strcity = fromObject.get("city").toString();
			String strcountry = fromObject.get("country").toString();
			String strprovince = fromObject.get("province").toString();
			String strsex = fromObject.get("sex").toString();
		
		}
		
	}
 
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
	public static String RmFilter(String message){
 
		if ((message == null) || (message.equals(""))) {
	      message = "";
	    }
		message = message.replace("<",""); 
		message = message.replace(">",""); 
		message = message.replace("'","");
		message = message.replace("\"","");
		//message = message.replace("/","/");
		message = message.replace("%",""); 
		message = message.replace(";",""); 
		message = message.replace("(",""); 
		message = message.replace(")",""); 
		message = message.replace("&",""); 
		message = message.replace("+","_"); 
		return message;
	}
 
}

RefTicket:獲取ticket

public class RefTicket extends TimerTask{
 
    private static ServletContext application = null;
    public RefTicket(ServletContext application){
        this.application = application;
    }
    
    public void run() {
        String jsapi_ticket = getTicket();
        if(!"".equalsIgnoreCase(jsapi_ticket)){
            this.application.setAttribute("jsapi_ticket", jsapi_ticket);
            System.out.println("jsapi_ticket:"+jsapi_ticket);
            System.out.println("jsapi_ticket--application:"+this.application.getAttribute("jsapi_ticket"));
        }
        
    }
    
    private static DefaultHttpClient httpclient;
    static {
        httpclient = new DefaultHttpClient();
        httpclient = (DefaultHttpClient) HttpClientConnectionManager
                .getSSLInstance(httpclient);
    }
    
    private String getTicket(){
        String token = (String) this.application.getAttribute("token");
        if("".equalsIgnoreCase(token) || null ==  token ){
            return "";
        }
        HttpGet get = HttpClientConnectionManager
                .getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
                        
        HttpResponse response;
        try {
            response = httpclient.execute(get);
            String jsonStr = EntityUtils
                    .toString(response.getEntity(), "utf-8");
            JSONObject demoJson = JSONObject.fromObject(jsonStr);
            return demoJson.getString("ticket");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
        
    }
 
}

RefToken:獲取token

public class RefToken extends TimerTask{
 
    private  final static String appId = "wx842b838875cd9bd3";
    private final static String appSecret = "ce7948b66d04b5ae714c9d0e4bc6eba9";
    private static ServletContext application = null;
    public RefToken(ServletContext application){
        this.application = application;
    }
    
    public void run() {
        String token = getAccessToken(appId,appSecret);
        if(!"".equalsIgnoreCase(token)){
            this.application.setAttribute("token", token);
            System.out.println("token---init:"+token);
             String ticket = getTicket();
            this.application.setAttribute("jsapi_ticket", ticket);
            System.out.println("ticket--init:"+ticket);
        }
    }
    
    private static DefaultHttpClient httpclient;
    static {
        httpclient = new DefaultHttpClient();
        httpclient = (DefaultHttpClient) HttpClientConnectionManager
                .getSSLInstance(httpclient);
    }
    
    private static String getAccessToken(String appid, String secret) {
        HttpGet get = HttpClientConnectionManager
                .getGetMethod("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                        + appid + "&secret=" + secret);
        HttpResponse response;
        try {
            response = httpclient.execute(get);
            String jsonStr = EntityUtils
                    .toString(response.getEntity(), "utf-8");
            JSONObject demoJson = JSONObject.fromObject(jsonStr);
            return demoJson.getString("access_token");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
    }
    
    private String getTicket(){
        String token = (String) this.application.getAttribute("token");
        if("".equalsIgnoreCase(token) || null ==  token ){
            return "";
        }
        HttpGet get = HttpClientConnectionManager
                .getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
                        
        HttpResponse response;
        try {
            response = httpclient.execute(get);
            String jsonStr = EntityUtils
                    .toString(response.getEntity(), "utf-8");
            JSONObject demoJson = JSONObject.fromObject(jsonStr);
            return demoJson.getString("ticket");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
        
    }
 
}

GetSignature :

public class GetSignature extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = Logger.getLogger(GetSignature.class);
    public GetSignature() {
        super();
    }
 
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    }
 
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try{
            response.setCharacterEncoding("UTF-8");
            request.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            //你的支付目錄的Url,不須要轉義,不包含#及其後面部分
            String url = request.getParameter("url");
            ServletContext application = this.getServletContext();
            String jsapi_ticket=String.valueOf(application.getAttribute("jsapi_ticket"));
            JSONObject obj = WeixinPay.getSignature(url, jsapi_ticket);
//            Map<String, String> sign = Sign.sign(jsapi_ticket,url);
            out.print(obj.toString());
            out.flush();
            out.close();
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
        
    }
 
}

JS中初始化:

//支付初始化
        function initPay(openId){
            //獲取當前頁面URL
            var geturl=window.location.href.split('#')[0];
            var getencodeurl=encodeURIComponent(geturl);
            $.ajax({
                type : 'POST',
                url : "/GetSignature?url="+getencodeurl,
                contentType:"application/x-www-form-urlencoded", 
                success : function(response) {
                    var params = eval("(" + response + ")");
                    wx.config({
                         debug: false,
                        appId : params.appid, // 必填,公衆號的惟一標識
                        timestamp : params.timestamp, // 必填,生成簽名的時間戳
                        nonceStr : params.nonceStr,  // 必填,生成簽名的隨機串
                        signature : params.signature,// 必填,簽名,見附錄1
                        jsApiList : [ 'chooseWXPay']
                    });
                    wx.ready(function() {
                        // config信息驗證後會執行ready方法,全部接口調用都必須在config接口得到結果以後,config是一個客戶端的異步操做,因此若是須要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則能夠直接調用,不須要放在ready函數中。
                        $("#weixinpay").on('click', function(t) {
//                             var c_sname =getQueryString("c_sname");
                            var paymoney=document.getElementById("money").value;//實際付款
                            var phone=document.getElementById("phone").value;//手機號
                            
                            if(phone==null||phone==""){
                                Dialog.alert("請填寫手機號碼!");
                            }else{
                                $("#weixinpay").unbind('click');
                                $("#mcover").css("display","block"); 
//                                 alert($("#payment").serialize());
                                $.ajax({
                                    type : 'POST',
//                                     url:"/topayServlet",
                                    url : "/topayServlet?openId="+openId+"&money="+paymoney+"&phone="+phone,
//                                     data:$("#payment").serialize(),// 提交formid
//                                     async: false,
                                    success : function(response) {
                                            var params = eval("(" + response + ")");
                                            $("#mcover").css("display","none");
                                            wx.chooseWXPay({
                                                appId : params.appId,
                                                timestamp :params.timeStamp, // 支付簽名時間戳,注意微信jssdk中的全部使用timestamp字段均爲小寫。但最新版的支付後臺生成簽名使用的timeStamp字段名需大寫其中的S字符
                                                nonceStr  : params.nonceStr, // 支付簽名隨機串,不長於 32 位
                                                package : params.package, // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=***)
                                                signType :params.signType, 
                                                paySign : params.paySign, 
                                                success : function(res) {
                                                     if(res.errMsg == "chooseWXPay:ok" ) {
                                                         window.location.href="/3g/shareBusiness.jsp?sid="+sp+"&c_sname="+skf+"&phone="+phone;
                                                        //支付成功
                                                        $("#weixinpay").bind('click');
                                                    }
                                                },
                                                 cancel: function (res) { 
                                                     window.location.href="/3g/shop_list.jsp";
                                                     $("#weixinpay").bind('click');
                                                },
                                                fail:function(res){
                                                       window.location.href="/3g/shop_list.jsp";
                                                       $("#weixinpay").bind('click');
                                                }
                                            });
                                    },
                                    error : function() {
//                                         window.location.reload();
//                                         alert("服務器異常,統一下單接口出錯!");
                                    }
                                })
                            }
                            
                        });
                    });
                    // config信息驗證失敗會執行error函數,如簽名過時致使驗證失敗,具體錯誤信息能夠打開config的debug模式查看,也能夠在返回的res參數中查看,對於SPA能夠在這裏更新簽名。
//                     wx.error(function(res){
//                         alert('wx.error: '+JSON.stringify(res));
//                     });
                },
                error : function() {
//                     window.location.reload();
//                     Dialog.alert("服務器異常,支付初始化失敗!");
                }
            })
    }

TopayServlet:統一下單接口

/**
 * 支付請求處理
 * @author dsn
 *
 */
public class TopayServlet extends HttpServlet {
 
 
    /**
     * 
     */
    private static final long serialVersionUID = 1359159929707330023L;
    private static final Logger logger = Logger.getLogger(TopayServlet.class);
    private String finalmoney=null;
    private String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    //商戶相關資料 
    private    String appid = WeiXinUitls.appid;
    private    String appsecret = WeiXinUitls.appsecret;
    private    String partner = WeiXinUitls.partner;
    private    String partnerkey = WeiXinUitls.partnerkey;
    @SuppressWarnings("static-access")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        request.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        //網頁受權後獲取傳遞的參數
        String openId = request.getParameter("openId");     
        String sid = request.getParameter("sssp"); //商戶ID
        String money = request.getParameter("money");//實際付款
        String phone = request.getParameter("phone");//手機號
        
        String c_sname = new String(skf.getBytes("ISO-8859-1"), "utf-8");
        //拼接字符串
        String zong=sid+"*"+money+"*"+phone+"*"+jfdy;
        //金額轉化爲分爲單位
        String money2 = TenpayUtil.getMoney(money);
        //獲取openId後調用統一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
                String currTime = TenpayUtil.getCurrTime();
                //8位日期
                String strTime = currTime.substring(8, currTime.length());
                //四位隨機數
                String strRandom = TenpayUtil.buildRandom(4) + "";
                //10位序列號,能夠自行調整。
                String strReq = strTime + strRandom;
                //商戶號
                String mch_id = partner;
                //子商戶號  非必輸
                //String sub_mch_id="";
                //設備號   非必輸
                String device_info="WEB";
                //隨機數 
                String nonce_str = strReq;
                //商品描述
                //String body = describe;
                //商品描述根據狀況修改
                String body = c_sname;
                //附加數據
                String attach = zong;
                //商戶訂單號
                String out_trade_no = NonceString.generate();
                //int intMoney = Integer.parseInt(finalmoney);
                //總金額以分爲單位,不帶小數點
                //int total_fee = intMoney;
                //訂單生成的機器 IP
                String spbill_create_ip = request.getRemoteAddr();
                //訂 單 生 成 時 間   非必輸
                String time_start =TenpayUtil.getStartTime();
                //訂單失效時間      非必輸
                String time_expire =TenpayUtil.getEndTime();;
                //商品標記   非必輸
                String goods_tag = "WXG";
                //這裏notify_url是 支付完成後微信發給該連接信息,能夠判斷會員是否支付成功,改變訂單狀態等。
                String notify_url ="http://www.yiquanmian.com/notifyServlet";
                String trade_type = "JSAPI";
                String openid = openId;
                //非必輸
//                String product_id = "";
                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                packageParams.put("appid", appid);  
                packageParams.put("mch_id", mch_id);  
                packageParams.put("nonce_str", nonce_str);  
                packageParams.put("body", body);  
                packageParams.put("attach", attach);  
                packageParams.put("out_trade_no", out_trade_no);  
                packageParams.put("total_fee", money2);  
                packageParams.put("spbill_create_ip", spbill_create_ip);
                packageParams.put("time_start", time_start); 
                packageParams.put("time_expire", time_expire); 
                packageParams.put("notify_url", notify_url);  
                packageParams.put("trade_type", trade_type);  
                packageParams.put("openid", openid);  
                RequestHandler reqHandler = new RequestHandler(request, response);
                reqHandler.init(appid, appsecret, partnerkey);
                String sign = reqHandler.createSign(packageParams);
                String xml="<xml>"+
                        "<appid>"+appid+"</appid>"+
                        "<mch_id>"+mch_id+"</mch_id>"+
                        "<nonce_str>"+nonce_str+"</nonce_str>"+
                        "<sign>"+sign+"</sign>"+
                        "<body><![CDATA["+body+"]]></body>"+
                        "<attach>"+attach+"</attach>"+
                        "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                        "<total_fee>"+money2+"</total_fee>"+
                        "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
                        "<time_start>"+time_start+"</time_start>"+
                        "<time_expire>"+time_expire+"</time_expire>"+
                        "<notify_url>"+notify_url+"</notify_url>"+
                        "<trade_type>"+trade_type+"</trade_type>"+
                        "<openid>"+openid+"</openid>"+
                        "</xml>";
                String allParameters = "";
                try {
                    allParameters =  reqHandler.genPackage(packageParams);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    e.printStackTrace();
                }
                String prepay_id="";
                try {
                    prepay_id= new GetWxOrderno().getPayNo(createOrderURL, xml);
//                    JSONObject xmls = p.getJSONObject("xml");
                    if(prepay_id.equals("")){
                        request.setAttribute("ErrorMsg", "統一支付接口獲取預支付訂單出錯");
                        response.sendRedirect("error.jsp");
                    }
                } catch (Exception e1) {
                    logger.error(e1.getMessage(), e1);
                    e1.printStackTrace();
                }
                SortedMap<String, String> finalpackage = new TreeMap<String, String>();
                String appid2 = appid;
                String timestamp = Sha1Util.getTimeStamp();
                String nonceStr2 = nonce_str;
                String prepay_id2 = "prepay_id="+prepay_id;
                String packages = prepay_id2;
                finalpackage.put("appId", appid2);  
                finalpackage.put("timeStamp", timestamp);  
                finalpackage.put("nonceStr", nonceStr2);  
                finalpackage.put("package", packages);  
                finalpackage.put("signType", "MD5");
                String finalsign = reqHandler.createSign(finalpackage);
                finalpackage.put("paySign",finalsign);
                JSONObject jsonObject1 = JSONObject.fromObject(finalpackage);   
                out.print(jsonObject1);
                out.flush();
                out.close();
                 
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
 
}

NotifyServlet:回調處理類

public class NotifyServlet extends HttpServlet {
 
    /**
     * 
     */
    private static final long serialVersionUID = 6743167121907086323L;
    private static final Logger logger = Logger.getLogger(NotifyServlet.class);
    private String resultXML;
 
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
//        response.setContentType("text/html;charset=utf-8");
        HttpSession session = request.getSession();
        int i = 0;
        //
        String inputLine;
        String notityXml = "";
        String resXml = "";
        try {
            while ((inputLine = request.getReader().readLine()) != null) {
                notityXml += inputLine;
            }
            request.getReader().close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            Map m = GetWxOrderno.parseXmlToList2(notityXml);
            WxPayResult wpr = new WxPayResult();
            String appid = m.get("appid").toString();
            String bank_type = m.get("bank_type").toString();
            String attach = m.get("attach").toString();
            String cash_fee = m.get("cash_fee").toString();
            String fee_type = m.get("fee_type").toString();
            String is_subscribe = m.get("is_subscribe").toString();
            String mch_id = m.get("mch_id").toString();
            String nonce_str = m.get("nonce_str").toString();
            String openid = m.get("openid").toString();
            String out_trade_no = m.get("out_trade_no").toString();
            String result_code = m.get("result_code").toString();
            String return_code = m.get("return_code").toString();
            String sign = m.get("sign").toString();
            String time_end = m.get("time_end").toString();
            String times = time_end.substring(0, 4) + "-"
                    + time_end.substring(4, 6) + "-" + time_end.substring(6, 8)
                    + " " + time_end.substring(8, 10) + ":"
                    + time_end.substring(10, 12) + ":"
                    + time_end.substring(12, 14);
            Timestamp tstamp = Timestamp.valueOf(times);
            String total_fee = m.get("total_fee").toString();
            int totalint = Integer.parseInt(total_fee);
            double pasint = totalint * 0.01;
            String trade_type = m.get("trade_type").toString();
            String transaction_id = m.get("transaction_id").toString();
            
            if ("SUCCESS".equals(result_code)) {
                // 支付成功
                // 處理附加數據
                
                // 判斷訂單是否已經存在
                
                if (rs.next()) {
                    if(transaction_id.equals(rs.getString("ddh"))){
                        System.out.println("訂單已經存在");
                    }
                } else {
                    
                    
                    
                    // ----------------------------------------------------發送短信-------------------------------------------
                    // 給用戶發短信
                    
 
                    // 給商家發短信
                    
                    
 
                }
                resXml = "<xml>"
                        + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                resXml = "<xml>"
                        + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[false]]></return_msg>"
                        + "</xml> ";
            }
 
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
 
    }
 
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

上面就是微信公衆號的核心代碼,須要源碼的能夠去個人地址下

https://download.csdn.net/download/dsn727455218/9325425

重點提示一下必定要在js的頁面中引入微信的js文件否則會調不起支付的

<script type="text/javascript" charset="UTF-8"
src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

 

二 APP支付

流程:

1.Android引入微信支付的SDK

2.拿商品信息請求統一下單接口

 

3.統一下單接口獲取預支付ID,後進行二次簽名把參數返回給前端

4.前端JS中接收到參數調起支付

5.支付成功頁面跳轉以及回調處理

具體騷操做:

首先在Constants.java中設置相關參數,具體請查看該文件註釋,同時根據註釋修改androidmanifest.xml文件

要保證: 包名和開放平臺一致,簽名和開放平臺一致,而且再公衆平臺作設置,詳情請閱讀: http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5,注意:此條僅僅適用於android,ios不受簽名文件限制

要保證回調類WXPayEntryActivity.java文件必須位於包名的wxapi目錄下,不然會致使沒法回調的狀況,注意:此條僅僅適用於android,ios有固定格式,請參考ios demo

上面是Android的注意事項

androidmanifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="你的項目包名"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk android:minSdkVersion="4" />
 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <activity
            android:name=".PayActivity"
            android:label="@string/app_name"
            android:exported="true"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="你的開發者ID"/>
            </intent-filter>
        </activity>
        
        <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"/>
        
 
        <receiver
            android:name="net.sourceforge.simcpux.AppRegister">
            <intent-filter>
                <action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
            </intent-filter>
        </receiver>
        
    </application>
 
</manifest>

PayActivity:調起支付類

public class PayActivity extends Activity {
 
    private static final String TAG = "MicroMsg.SDKSample.PayActivity";
 
    PayReq req;
    final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
    TextView show;
    Map<String,String> resultunifiedorder;
    StringBuffer sb;
    
    private IWXAPI api; // IWXAPI 是第三方app和微信通訊的openapi接口
 
    private Context context;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay);
 
        //微信appId
        api = WXAPIFactory.createWXAPI( this, Constants.APP_ID);
        api.registerApp(Constants.APP_ID);
        final Button appayBtn = (Button) findViewById(R.id.appay_btn);
        appayBtn.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                String url = "http://192.168.0.104:8080/wx_pay/servlet/TopayServlet";
 
                Toast.makeText(PayActivity.this, "獲取訂單中...", Toast.LENGTH_SHORT).show();
                try{
                    byte[] buf = Util.httpGet(url);
                    if (buf != null && buf.length > 0) {
                        String content = new String(buf);
                        Log.e("get server pay params:",content);
                        JSONObject json = new JSONObject(content); 
                       
                        if(null != json && json.getString("returnstatus").equals("success") ){
                             String retmsg = json.getString("retmsg");
                             JSONObject json2 = new JSONObject(retmsg); 
                            PayReq req = new PayReq();
                            //req.appId = "wxf8b4f85f3a794e77";  // 測試用appId
                            Log.e("get appid  :",json2.getString("appid"));
                            Log.e("get partnerid  :",json2.getString("partnerid"));
                            Log.e("get prepayid  :",json2.getString("prepayid"));
                            Log.e("get noncestr  :",json2.getString("noncestr"));
                            Log.e("get timestamp  :",json2.getString("timestamp"));
                            Log.e("get package  :",json2.getString("package"));
                            Log.e("get sign  :",json2.getString("sign"));
                            //從服務器獲取
                            req.appId           = json2.getString("appid");
                            req.partnerId       = json2.getString("partnerid");
                            req.prepayId        = json2.getString("prepayid");
                            req.nonceStr        = json2.getString("noncestr");
                            req.timeStamp       = json2.getString("timestamp");
                            req.packageValue    = json2.getString("package");
                            req.sign            = json2.getString("sign");
                            req.extData         = "app data"; // optional
                            Toast.makeText(PayActivity.this, "正常調起支付", Toast.LENGTH_SHORT).show();
                            // 在支付以前,若是應用沒有註冊到微信,應該先調用IWXMsg.registerApp將應用註冊到微信
                            
                            api.sendReq(req);
                            Log.e("get api.sendReq(req)  :",api.sendReq(req)+"");
                        }else{
                            Log.d("PAY_GET", "返回錯誤"+json.getString("retmsg"));
                            Toast.makeText(PayActivity.this, "返回錯誤"+json.getString("retmsg"), Toast.LENGTH_SHORT).show();
                        }
                    }else{
                        Log.d("PAY_GET", "服務器請求錯誤");
                        Toast.makeText(PayActivity.this, "服務器請求錯誤", Toast.LENGTH_SHORT).show();
                    }
                }catch(Exception e){
                    Log.e("PAY_GET", "異常:"+e.getMessage());
                    Toast.makeText(PayActivity.this, "異常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
                }
//                appayBtn.setEnabled(true);
            }
        });     
    }

WXPayEntryActivity:支付成功頁面跳轉類

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
    
    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
    
    private IWXAPI api;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        //微信APP_ID
        api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        api.handleIntent(getIntent(), this);
    }
 
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }
 
    @Override
    public void onReq(BaseReq req) {
    }
 
    @Override
    public void onResp(BaseResp resp) {
        Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
        String msg = "";
        if (resp.errCode == 0) {
            msg = "支付成功";
        } else if (resp.errCode == -1) {
            msg = "已取消支付";
        } else if (resp.errCode == -2) {
            msg = "支付失敗";
        }
        Toast.makeText(WXPayEntryActivity.this, resp.errCode+"------"+msg, Toast.LENGTH_SHORT).show();
        finish();
    }
}

PrepayId:統一下單接口

/**
 * Servlet implementation class prepayid
 */
public class PrepayId extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // key設置路徑:微信商戶平臺(pay.weixin.qq.com)-->帳戶設置-->API安全-->密鑰設置
 
    //TODO
    private static String KEY = "你的商戶平臺key";
 
    /**
     * Default constructor.
     */
    public PrepayId() {}
 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    @SuppressWarnings("rawtypes")
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
 
        SortedMap<String, String> map = new TreeMap<String, String>();
        //TODO 你的appid
        map.put("appid", "");
        //TODO 你的商戶id
        map.put("mch_id", "");
        map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
        map.put("body", "lidongliang");
        map.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
        map.put("total_fee", "1");
        map.put("spbill_create_ip", "192.168.0.105");
        map.put("notify_url", "你的回調地址");
        map.put("trade_type", "APP");
        String sign = createSign(map);
        map.put("sign", sign);
 
        // 生成XMl
        Set set = map.entrySet();
        Iterator it = set.iterator();
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            sb.append("<" + key + "><![CDATA[");
            sb.append(value);
            sb.append("]]></" + key + ">");
        }
        sb.append("</xml>");
 
        try {
            System.out.println("111111111" + sb.toString());
            String postData = NetUtil.doPost(url, sb.toString());
            System.out.println("222222222" + postData.toString());
            SortedMap<String, String> test = new TreeMap<String, String>();
            JSONObject json = XML.toJSONObject(postData).getJSONObject("xml");
 
            test.put("appid", json.getString("appid"));
            test.put("partnerid", json.getString("mch_id"));
            test.put("prepayid", json.getString("prepay_id"));
            test.put("package", "Sign=WXPay");
            test.put("noncestr", String.valueOf(System.currentTimeMillis()));
            test.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
            test.put("sign", createSign(test));
 
            response.getWriter().append(new JSONObject(test).toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {}
 
    /**
     * 微信支付簽名算法sign
     * 
     * @param characterEncoding
     * @param parameters
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static String createSign(SortedMap<String, String> parameters) {
        StringBuffer sb = new StringBuffer();
        // 全部參與傳參的參數按照accsii排序(升序)
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) 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);
        System.out.println("字符串拼接後是:" + sb.toString());
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        System.out.println("sign:" + sign);
        return sign;
    }
}

NotifyHandle:支付回調類

@Controller
@RequestMapping("notifyhandle")
public class NotifyHandle extends BaseAction{
    @Resource
    private ServiceSinggleService ssService;
    @Resource
    private ElutionRecordService edService;
    @Resource
    private AppUserService appuserService;
    @Resource
    private MsgJpushService mjService;
    private static final Logger logger = Logger.getLogger(NotifyHandle.class);
    @ResponseBody
    @RequestMapping(value="/notify")
    public String notify(ServiceSinggle ssinggle,ElutionRecord record,MsgJpush msgjpush,AppUser appuser,HttpServletRequest request,HttpSession session,HttpServletResponse response){
        String inputLine;
        String notityXml = "";
        String resXml = "";
        try {
            while ((inputLine = request.getReader().readLine()) != null) {
                notityXml += inputLine;
            }
            request.getReader().close();
            Map m = GetWxOrderno.parseXmlToList2(notityXml);
            String result_code = m.get("result_code").toString();
            if("SUCCESS".equals(result_code)){
                //查詢是否存在訂單
                String attach = m.get("attach").toString();
                String out_trade_no = m.get("out_trade_no").toString();
                String time_end = m.get("time_end").toString();
                String total_fee = m.get("total_fee").toString();
                int totalint = Integer.parseInt(total_fee);
                //訂單更新 繼續你的邏輯操做
            } else {
                resXml = "<xml>"
                        + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[false]]></return_msg>"
                        + "</xml> ";
            }
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return "";
    }
}

APP的微信支付就是這麼的簡單:上面我貼的核心代碼,一些工具類沒有貼出來須要demo能夠去下面地址下載

https://download.csdn.net/download/dsn727455218/10304062

若是遇到簽名錯誤,缺乏參數,返回-1,等錯誤請參考個人另外一篇文章:微信支付遇到的幾個問題

https://blog.csdn.net/dsn727455218/article/details/70139320

看着是否是很簡單,完美的解決。

到這裏已經完成了微信支付功能,若有須要能夠加我Q羣【308742428】你們一塊兒討論技術。

後面會不定時爲你們更新文章,敬請期待。

喜歡的朋友能夠關注下,粉絲也缺。

若是對你有幫助,請打賞一下!!!

相關文章
相關標籤/搜索