1:去微信開放平臺注冊應用https://open.weixin.QQ.com/cgi-bin/index?t=home/index&lang=zh_CN&token=2c0fee9c43e1eb8f9febcc7cb73abf598e2d4011
這里需要注意的是:
微信提供的簽名生成工具把包名添加上去就可以獲取簽名注意:把要獲取簽名的應用安裝在手機上https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android2.apk
創建移動應用并成功之后會收到騰訊發來的郵件:
Paste_Image.png通過郵件你能獲得重要的參數:(1):AppID(2):微信支付商戶號(4):前往商戶平臺完成入駐(4):API秘鑰(自己設置即可,注意一定要32位字母加數字的組合)記得保存好秘鑰,以后要使用
開發前的準備
先了解下交互時序圖,統一下單API、支付結果通知API和查詢訂單API等都涉及簽名過程,調用都必須在商戶服務器端完成。如圖8.6所示。

下載開發工具包https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&lang=zh_CN
1.在項目中引入微信開發包
引入jar2.在AndroidManifest.xml中添加相應的權限
signingConfigs { debug { storeFile file("你的keystore路徑") storePassWord "xxx" keyAlias "xxx" keyPassword "xxx" } release { storeFile file("你的keystore路徑") storePassword "xxx" keyAlias "xxx" keyPassword "xxx" }}3.在MainActivity中注冊到為微信
注冊微信api= WXAPIFactory.createWXAPI(this,ConfigUtil.Wechat_Appid,true);api.registerApp(ConfigUtil.Wechat_Appid);4.在點擊的時候向微信發送請求
發送請求case R.id.wechat_pay: PayReq request = new PayReq(); request.appId = ConfigUtil.Wechat_Appid; request.partnerId = "1327244301"; request.PRepayId= "wx2016092009564343e737275f0904349502"; request.packageValue = "Sign=WXPay"; request.nonceStr= "70vhVHnJj6ph7mf9"; request.timeStamp= "1474336603"; request.sign= "815BC8D5508FD90F7A978856B2174E21"; api.sendReq(request); break;5.配置回調[1]在微信管理后臺中配置的包名下新建wxapi包[2]在wxapi包下新建WXPayEntryActivity的類(注意這個類的位置和名稱不能改變)
新建WXPayEntryActivity類[3]WXPayEntryActivity類實現IWXAPIEventHandler繼承Activity,該布局文件自己定義即可
WXPayEntryActivity類實現[4]在AndroidManifest.xml中注冊activity
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, ConfigUtil.Wechat_Appid); api.handleIntent(getIntent(), this);} @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); }[6]實現onResp
public void onResp(BaseResp baseResp) { Log.d(TAG, "onPayFinish, errCode = " + baseResp.errCode); if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("標題"); builder.setMessage(String.valueOf(baseResp.errCode)); builder.show(); }}baseResp.errCode是返回的錯誤碼
錯誤碼注意:WXPayEntryActivity類必須叫這個名必須在wxapi包下
微信調不起來:檢查簽名是否正確包名是否與微信后臺配置的一致檢查是否添加權限檢查代碼 是否在初始化時注冊微信 是否正確發送請求微信支付調用起來沒有回調:查看包名是否正確類名是否正確在AndroidManifest.xml是否注冊activity
解決方法:實在掉不起來微信(包名正確簽名正確)就重新安裝微信客戶端 和重新安裝 測試項目
預支付訂單和sign最好在服務器中完成,但若是就想在客戶端做怎么弄呢?為方便,那么我這里就直接給出代碼,可供大家參考:
/** *該類用于在客戶端處理吊起微信支付前,生成prepay_id和sign的方式舉例, * 但建議在服務器端處理prepay_id和sign **/public class PayActivity extends Activity { // appid // 請同時修改 androidmanifest.xml里面,.PayActivity里的屬性<data // android:scheme=""/>為新設置的appid public static String APP_ID; // 商戶號 public static String MCH_ID ; // API密鑰,在商戶平臺設置 public static String API_KEY ; private String body; private String total; PayReq req; final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null); Map<String, String> resultunifiedorder; StringBuffer sb; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); APP_ID= getIntent().getStringExtra("appid"); MCH_ID=getIntent().getStringExtra("partnerid"); API_KEY=getIntent().getStringExtra("apikey"); body=getIntent().getStringExtra("body"); req = new PayReq(); sb = new StringBuffer(); msgApi.registerApp(APP_ID); // 生成prepay_id GetPrepayIdTask getPrepayId = new GetPrepayIdTask(); getPrepayId.execute(); } private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String, String>> { private ProgressDialog dialog; @Override protected void onPreExecute() { dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip), getString(R.string.getting_prepayid)); } @Override protected Map<String, String> doInBackground(Void... params) { String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder"); String entity = genProductArgs(); Log.e("orion", entity); byte[] buf = Util.httpPost(url, entity); //執行與獲取預付款訂單請求,并獲得訂單byte String content = new String(buf); Log.e("orion", content); Map<String, String> map = decodeXml(content); return map; } @Override protected void onPostExecute(Map<String, String> result) { if (dialog != null) { dialog.dismiss(); } sb.append("prepay_id/n" + result.get("prepay_id") + "/n/n"); resultunifiedorder = result; if (result.get("prepay_id") != null) { genPayReq(); //吊起支付請求 } else { Toast.makeText(getapplicationContext(), "調用微信支付失敗!", Toast.LENGTH_SHORT).show(); } } } public Map<String, String> decodeXml(String content) { try { Map<String, String> xml = new HashMap<String, String>(); XmlPullParser parser = Xml.newPullParser(); parser.setInput(new StringReader(content)); int event = parser.getEventType(); while (event != XmlPullParser.END_DOCUMENT) { String nodeName = parser.getName(); switch (event) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if ("xml".equals(nodeName) == false) { // 實例化student對象 xml.put(nodeName, parser.nextText()); } break; case XmlPullParser.END_TAG: break; } event = parser.next(); } return xml; } catch (Exception e) { Log.e("orion", e.toString()); } return null; } private String genNonceStr() { Random random = new Random(); return md5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private long genTimeStamp() { return System.currentTimeMillis() / 1000; } private String genOutTradNo() { Random random = new Random(); String out_trade_no = MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); return out_trade_no; } private String genProductArgs() { StringBuffer xml = new StringBuffer(); try { String nonceStr = genNonceStr(); xml.append("</xml>"); List<NameValuePair> packageParams = new LinkedList<NameValuePair>(); packageParams.add(new BasicNameValuePair("appid", APP_ID)); packageParams.add(new BasicNameValuePair("body", body));//物品 packageParams.add(new BasicNameValuePair("mch_id", MCH_ID)); packageParams.add(new BasicNameValuePair("nonce_str", nonceStr)); packageParams.add(new BasicNameValuePair("notify_url", "http://baidu.com")); packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo())); packageParams.add(new BasicNameValuePair("spbill_create_ip", getPhoneIp())); packageParams.add(new BasicNameValuePair("total_fee", getIntent().getStringExtra("total_fee")));//金額 packageParams.add(new BasicNameValuePair("trade_type", "APP")); String sign = genPackageSign(packageParams); packageParams.add(new BasicNameValuePair("sign", sign)); String xmlstring = toXml(packageParams); return new String(xmlstring.getBytes(), "ISO8859-1"); // return xmlstring; } catch (Exception e) { // Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage()); return null; } } private void genPayReq() { req.appId = APP_ID; req.partnerId = MCH_ID; req.prepayId = resultunifiedorder.get("prepay_id"); req.packageValue = "Sign=WXPay"; req.nonceStr = genNonceStr(); req.timeStamp = String.valueOf(genTimeStamp()); List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add(new BasicNameValuePair("appid", req.appId)); signParams.add(new BasicNameValuePair("noncestr", req.nonceStr)); signParams.add(new BasicNameValuePair("package", req.packageValue)); signParams.add(new BasicNameValuePair("partnerid", req.partnerId)); signParams.add(new BasicNameValuePair("prepayid", req.prepayId)); signParams.add(new BasicNameValuePair("timestamp", req.timeStamp)); req.sign = genAppSign(signParams); sb.append("sign/n" + req.sign + "/n/n"); sendPayReq(); Log.e("orion", signParams.toString()); } /** * 獲取預支付訂單時需要生成的PackageSign簽名 */ private String genPackageSign(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(API_KEY); String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); Log.e("orion", packageSign); return packageSign; } //吊起支付時需要生成的AppSign簽名 private String genAppSign(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(API_KEY); this.sb.append("sign str/n" + sb.toString() + "/n/n"); String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); Log.e("orion", appSign); return appSign; } private String toXml(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); sb.append("<xml>"); for (int i = 0; i < params.size(); i++) { sb.append("<" + params.get(i).getName() + ">"); sb.append(params.get(i).getValue()); sb.append("</" + params.get(i).getName() + ">"); } sb.append("</xml>"); Log.e("orion", sb.toString()); return sb.toString(); } // 發起微信支付 private void sendPayReq() { msgApi.registerApp(APP_ID); msgApi.sendReq(req); } public static String getPhoneIp() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { return inetAddress.getHostAddress().toString(); } } } } catch (Exception e) { } return "127.0.0.1"; }}其中Util中涉及的代碼如下:
public static byte[] httpPost(String url, String entity) { if (url == null || url.length() == 0) { Log.e(TAG, "httpPost, url is null"); return null; } HttpClient httpClient = getNewHttpClient(); HttpPost httpPost = new HttpPost(url); try { httpPost.setEntity(new StringEntity(entity)); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); HttpResponse resp = httpClient.execute(httpPost); if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode()); return null; } return EntityUtils.toByteArray(resp.getEntity()); } catch (Exception e) { Log.e(TAG, "httpPost exception, e = " + e.getMessage()); e.printStackTrace(); return null; } }其他文檔:
微信開發平臺官網:申請流、業務流程、訂單簽名算法及驗證
微信支付集成及爬坑:代碼詳談
集成微信登錄 :http://www.jianshu.com/p/d95e4343e231
Android實現點擊支付按鈕,彈起自定義輸入法進行密碼輸入: 點我哦!
微信掃一掃揭秘: 猛戳這里!
新聞熱點
疑難解答