相信不少的碼友在項目中都須要接入微信支付,雖然說微信支付已成爲一個廣泛的現象,可是接入的過程當中不免會遇到各類各樣的坑,這一點支付寶的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】你們一塊兒討論技術。
後面會不定時爲你們更新文章,敬請期待。
若是對你有幫助,請打賞一下!!!