首先我們先看一個Android微信支付時遇到的一個錯誤提示:
onPayFinish, errCode = -1?
當你參數簽名都沒有問題的時候,出現這個提示,請按照如下操作:
在你的項目測試android微信的組件(微信分享、微信支付等)的時候,一定要用你自己的keystore簽名出來測試,如果用debug.keystore肯定是不成功的!
1,在微信開放平臺申請app_id,app_key我就不在這里敘述了,稍后我會把開發文檔一并上傳的,你也可以去微信開放平臺自行查看(差不多一個周才會通過審核)?
https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=44d65f9f1df0d4725b941e217a0bf769fbb51b3a
2,下面我就來說一說微信支付開發時需要注意的地方:
2.1 首先來看一下,微信支付的架構和流程圖?
?
?
3.2 再來看一下成功調起微信支付的界面?
?
3下面開始講解配置工程
3.1 這里必須要有wxapi這個包名,同時必須有WXPayEntryActivity這個類名,否則無法調起微信支付,(開發文檔沒有標注,廢了好大周章)?
3.2 支付成功通知:在WXPayEntryActivity的OnResp中處理,不能以微信返回的通知界面為準(我遇到的情況,網絡不穩定的時候,微信返回界面提示支付失敗,但是收到微信通知其實已經支付成功了),必須要去自己的服務器查詢支付狀態,這里微信建議用輪循機制去查詢(最好聽微信勸,O(∩_∩)O哈哈~)
[java] view plaincopyprint?
@Override?????public?void?onResp(BaseResp?resp)?{?????????Log.d(TAG,?”onPayFinish,?errCode?=?”?+?resp.errCode);???????????if?(resp.getType()?==?ConstantsAPI.COMMAND_PAY_BY_WX)?{?????????????AlertDialog.Builder?builder?=?new?AlertDialog.Builder(this);?????????????builder.setTitle(R.string.app_tip);?????????????builder.setMessage(getString(R.string.pay_result_callback_msg,?resp.errStr?+”;code=”?+?String.valueOf(resp.errCode)));?????????????builder.show();?????????}?????}?? @Overridepublic void onResp(BaseResp resp) {Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle(R.string.app_tip);builder.setMessage(getString(R.string.pay_result_callback_msg, resp.errStr +";code=" + String.valueOf(resp.errCode)));builder.show();}}
3.3 生成prepay_id,在服務器完成,由服務器去跟微信服務器交互,客戶端不需要參與
[java] view plaincopyprint?
??????????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”,?Constants.APP_ID));?????????????packageParams.add(new?BasicNameValuePair(“body”,?“APP?pay?test”));??????????????????????????packageParams.add(new?BasicNameValuePair(“mch_id”,?Constants.MCH_ID));?????????????packageParams.add(new?BasicNameValuePair(“nonce_str”,?nonceStr));?????????????packageParams.add(new?BasicNameValuePair(“notify_url”,?“http://121.40.35.3/test”));?????????????packageParams.add(new?BasicNameValuePair(“out_trade_no”,genOutTradNo()));?????????????packageParams.add(new?BasicNameValuePair(“spbill_create_ip”,“127.0.0.1”));?????????????packageParams.add(new?BasicNameValuePair(“total_fee”,?“1”));?????????????packageParams.add(new?BasicNameValuePair(“trade_type”,?“APP”));?????????????????String?sign?=?genPackageSign(packageParams);?????????????packageParams.add(new?BasicNameValuePair(“sign”,?sign));????????????????String?xmlstring?=toXml(packageParams);???????????????return?xmlstring;???????????}?catch?(Exception?e)?{?????????????Log.e(TAG,?”genProductArgs?fail,?ex?=?”?+?e.getMessage());?????????????return?null;?????????}?????????}?? /*** 獲取預支付訂單號:* prepay_id(服務器完成)!!!* 注意:如果服務端開發文檔跟客戶端demo里的參數不一樣,以demo里的參數為準,* 否則服務器傳過來的參數無法調起微信支付!!!* */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", Constants.APP_ID));packageParams.add(new BasicNameValuePair("body", "APP pay test"));/**這里用的是mach_id,跟sign簽名時參數名不同,一定要注意*/packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));packageParams.add(new BasicNameValuePair("notify_url", "http://121.40.35.3/test"));packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1"));packageParams.add(new BasicNameValuePair("total_fee", "1"));packageParams.add(new BasicNameValuePair("trade_type", "APP"));String sign = genPackageSign(packageParams);packageParams.add(new BasicNameValuePair("sign", sign));String xmlstring =toXml(packageParams);return xmlstring;} catch (Exception e) {Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());return null;}}
3.4 獲取二次簽名sign
[java] view plaincopyprint?
private?void?genPayReq()?{????????????req.appId?=?Constants.APP_ID;??????????req.partnerId?=?Constants.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”);????????????show.setText(sb.toString());????????????Log.e(”orion”,?signParams.toString());????????}??private void genPayReq() {req.appId = Constants.APP_ID;req.partnerId = Constants.MCH_ID;req.prepayId = resultunifiedorder.get("prepay_id");
// req.packageValue = "prepay_id="+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));/*** 這里的package參數值必須是Sign=WXPay,否則IOS端調不起微信支付,* (參數值是"prepay_id="+resultunifiedorder.get("prepay_id")的時候Android可以,IOS不可以)*/signParams.add(new BasicNameValuePair("package", req.packageValue));/**注意二次簽名這里不再是mch_id,變成了prepayid;*/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");show.setText(sb.toString());Log.e("orion", signParams.toString());}
3.5 起調微信支付
[java] view plaincopyprint?
private?void?sendPayReq()?{??????????msgApi.registerApp(Constants.APP_ID);??????????msgApi.sendReq(req);??????}??private void sendPayReq() {msgApi.registerApp(Constants.APP_ID);msgApi.sendReq(req);}
3.6 配置Manifest.xml,權限什么的按照文檔的配置就行了
[html] view plaincopyprint?
<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=“wxd930ea5d5a258f4f”/>?????????????</intent-filter>?????????</activity>?? <activityandroid: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不要忘了--><intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/><data android:scheme="wxd930ea5d5a258f4f"/></intent-filter></activity>
4,支付通知接口和退款接口按照開發文檔即可,這里不再贅述
5, 在你的項目測試微信支付的時候,一定要用你自己的keystore簽名出來測試,如果用debug.keystore肯定是不成功的,切記,切記,不要鬧烏龍!!!
好了,就寫這么多吧,以此文來祭奠我和同事被騰訊坑死的那幾天,如果有不懂的童鞋可以給我留言,或者QQ:1031012395聯系我,大家可以去這個地址下載微信支付v3.0版本的開發文檔和demo,以及一個成功的微信支付demo app,輪詢事件大家可以參考我的下一篇blog,從別人那里轉來的,寫的挺詳細的?
http://download.csdn.net/detail/baidu_17508977/8521101
補充問題:
微信支付v3 body中文無法支付問題
String nonceStr = genNonceStr();xml.append(“</xml>”);// Yuebai Steam Car Wash ServiceList<NameValuePair> packageParams = new LinkedList<NameValuePair>();packageParams.add(new BasicNameValuePair(“appid”, Constants.APP_ID));
packageParams.add(new BasicNameValuePair(“body”, “月白洗車”));// 這個一改就無法支付packageParams.add(new BasicNameValuePair(“mch_id”, Constants.MCH_ID));packageParams.add(new BasicNameValuePair(“nonce_str”, nonceStr));packageParams.add(new BasicNameValuePair(“notify_url”, HttpConstant.wxapi));packageParams.add(new BasicNameValuePair(“out_trade_no”, orderid));packageParams.add(new BasicNameValuePair(“spbill_create_ip”, “127.0.0.1”));int a = (int) (Integer.parseInt(m) * 100);packageParams.add(new BasicNameValuePair(“total_fee”, a + “”));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.toString().getBytes(), “ISO8859-1”);//這句加上就可以了吧xml轉碼下?
另外說明的是,如果想增加參數,請先看看下面的內容。
簽名算法
簽名生成的通用步驟如下:
第一步,設所有發送或者接收到的數據為集合M,將集合M內非空參數值的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特別注意以下重要規則:
◆ 參數名ASCII碼從小到大排序(字典序);◆ 如果參數的值為空不參與簽名;◆ 參數名區分大小寫;◆ 驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,將生成的簽名與該sign值作校驗。◆ 微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。
key設置路徑:微信商戶平臺(pay.weixin.qq.com)–>賬戶設置–>API安全–>密鑰設置
舉例:
假設傳送的參數如下:
appid: wxd930ea5d5a258f4f
mch_id: 10000100
device_info: 1000
body: test
nonce_str: ibuaiVcKdpRxkhJA
第一步:對參數按照key=value的格式,并按照參數名ASCII字典序排序如下:
stringA=”appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA”;
第二步:拼接API密鑰:
stringSignTemp=”stringA&key=192006250b4c09247ec02edce69f6a2d”
sign=MD5(stringSignTemp).toUpperCase()=”9A0A8659F005D6984697E2CA0A9CF3B7”
最終得到最終發送的數據:
<xml>
<appid>wxd930ea5d5a258f4f</appid>
<mch_id>10000100</mch_id>
<device_info>1000<device_info>
<body>test</body>
<nonce_str>ibuaiVcKdpRxkhJA</nonce_str>
<sign>9A0A8659F005D6984697E2CA0A9CF3B7</sign>
<xml>
微信提供相關接口在線簽名驗證工具:點擊進入。
?
?
所以,如果我們增加兩個參數:attach、device_info就必須根據參數名ASCII字典序增加,如下圖位置。如果將參數attach放在trade_type之后肯定就會報簽名錯誤。
List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
packageParams.add(new BasicNameValuePair("appid", Constant.weixin_appID));
packageParams.add(new BasicNameValuePair("attach", mOrderNo));
packageParams.add(new BasicNameValuePair("body", "訂單-" + mOrderNo)); //商品描述
packageParams.add(new BasicNameValuePair("device_info", "ANDROID"));
packageParams.add(new BasicNameValuePair("mch_id", Constant.MCH_ID));
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
packageParams.add(new BasicNameValuePair("notify_url", "http://wap.baidu.com/wechat_notify.php"));
packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));
packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
packageParams.add(new BasicNameValuePair("total_fee", String.valueOf((int) (mMoney * 100))));//商品金額,以分為單位
packageParams.add(new BasicNameValuePair("trade_type", "APP"));
?
最后再為大家分享點干貨。
在計算訂單總價的時候,有時會出現***.09999999999999998的現象,這個是浮點數計算出現的問題,得需要?BigDecimal解決高精度計算。
下面是我的解決方法,大家有更好的可以分享下。
[java] view plaincopyprint?
?????????public?double?calculatingTotalPriceNoFreight()?{??????????double?total?=?0.00;??????????for?(ShopCartItem?cartItem?:?getDataList())?{??????????????double?orderPrice?=?calculatingOrderPrice(cartItem);??????????????total?+=?orderPrice;??????????}??????????????????????return?MathUtil.round(total,?2,?BigDecimal.ROUND_HALF_EVEN)?;??????}??/** 總訂單的價格(不包含運費)* @return*/public double calculatingTotalPriceNoFreight() {double total = 0.00;for (ShopCartItem cartItem : getDataList()) {double orderPrice = calculatingOrderPrice(cartItem);total += orderPrice;}//double值保留 2 位小數,使用銀行家舍入法return MathUtil.round(total, 2, BigDecimal.ROUND_HALF_EVEN) ;}
MathUtil.Java
[java] view plaincopyprint?
package?com.haier.cabinet.customer.util;????import?java.math.BigDecimal;????public?class?MathUtil?{???????????????????????public?static?double?round(double?value,?int?scale,?????????????????int?roundingMode)?{??????????????BigDecimal?bd?=?new?BigDecimal(value);??????????????bd?=?bd.setScale(scale,?roundingMode);????????????double?d?=?bd.doubleValue();??????????????bd?=?null;??????????????return?d;??????????}???????????????????????????public?static?double?sum(double?d1,double?d2){???????????BigDecimal?bd1?=?new?BigDecimal(Double.toString(d1));???????????BigDecimal?bd2?=?new?BigDecimal(Double.toString(d2));???????????return?bd1.add(bd2).doubleValue();???????}???????????????????????public?static?double?sub(double?d1,double?d2){???????????BigDecimal?bd1?=?new?BigDecimal(Double.toString(d1));???????????BigDecimal?bd2?=?new?BigDecimal(Double.toString(d2));???????????return?bd1.subtract(bd2).doubleValue();???????}?????????????????????public?static?double?mul(double?d1,double?d2){???????????BigDecimal?bd1?=?new?BigDecimal(Double.toString(d1));???????????BigDecimal?bd2?=?new?BigDecimal(Double.toString(d2));???????????return?bd1.multiply(bd2).doubleValue();???????}?????????????????????????public?static?double?mul(int?n,double?d2){???????????BigDecimal?bd1?=?new?BigDecimal(Integer.toString(n));???????????BigDecimal?bd2?=?new?BigDecimal(Double.toString(d2));???????????return?bd1.multiply(bd2).doubleValue();???????}????????????????????????public?static?double?div(double?d1,double?d2,int?scale){?????????????????????????????????BigDecimal?bd1?=?new?BigDecimal(Double.toString(d1));???????????BigDecimal?bd2?=?new?BigDecimal(Double.toString(d2));???????????return?bd1.divide??????????????????(bd2,?scale,?BigDecimal.ROUND_HALF_UP).doubleValue();??????}??????????????????public?static?String?double2String(double?d){??????????BigDecimal?bg?=?new?BigDecimal(d?*?100);??????????double?doubleValue?=?bg.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();??????????return??String.valueOf((int)doubleValue);??????}????}??package com.haier.cabinet.customer.util;import java.math.BigDecimal;public class MathUtil {/** * 對double數據進行取精度. * @param value double數據. * @param scale 精度位數(保留的小數位數). * @param roundingMode 精度取值方式. * @return 精度計算后的數據. */ public static double round(double value, int scale, int roundingMode) { BigDecimal bd = new BigDecimal(value); bd = bd.setScale(scale, roundingMode); double d = bd.doubleValue(); bd = null; return d; } /** * double 相加 * @param d1 * @param d2 * @return */ public static double sum(double d1,double d2){ BigDecimal bd1 = new BigDecimal(Double.toString(d1)); BigDecimal bd2 = new BigDecimal(Double.toString(d2)); return bd1.add(bd2).doubleValue(); } /** * double 相減 * @param d1 * @param d2 * @return */ public static double sub(double d1,double d2){ BigDecimal bd1 = new BigDecimal(Double.toString(d1)); BigDecimal bd2 = new BigDecimal(Double.toString(d2)); return bd1.subtract(bd2).doubleValue(); } /** * double 乘法 * @param d1 * @param d2 * @return */ public static double mul(double d1,double d2){ BigDecimal bd1 = new BigDecimal(Double.toString(d1)); BigDecimal bd2 = new BigDecimal(Double.toString(d2)); return bd1.multiply(bd2).doubleValue(); } /** * double 乘法 * @param n* @param d2 * @return */ public static double mul(int n,double d2){ BigDecimal bd1 = new BigDecimal(Integer.toString(n)); BigDecimal bd2 = new BigDecimal(Double.toString(d2)); return bd1.multiply(bd2).doubleValue(); } /** * double 除法 * @param d1 * @param d2 * @param scale 四舍五入 小數點位數 * @return */ public static double div(double d1,double d2,int scale){ // 當然在此之前,你要判斷分母是否為0, // 為0你可以根據實際需求做相應的處理 BigDecimal bd1 = new BigDecimal(Double.toString(d1)); BigDecimal bd2 = new BigDecimal(Double.toString(d2)); return bd1.divide(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();}/*** 將double類型數據轉為字符串* @param d* @return*/public static String double2String(double d){BigDecimal bg = new BigDecimal(d * 100);double doubleValue = bg.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();return String.valueOf((int)doubleValue);}}
2016-08-30補充:
微信官網上對于支付返回-1是這樣的描述的,??可能的原因:簽名錯誤、未注冊APPID、項目設置APPID不正確、注冊的APPID與設置的不匹配、其他異常等。
我犯的錯和他描述的都不一樣。
1、新建一個微信支付demo的工程,將包名和簽名上傳給微信。并保證apk是通過keystore方式打了簽名的,用官方的工具做簽名。
2、將官方的demo示例參考一下,
權限部分:
[html] view plaincopyprint?
??????<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”??<!-- WeixinPay --><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"
[html] view plaincopyprint?
<activity?android:name=“.MainActivity”???????android:exported=“true”>???????<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=“wxd31ef1f4dd******”/>???????</intent-filter>???</activity>???<activity?android:name=“.AlipayH5Activity”></activity>???<activity?android:name=“com.*******.paydemo.wxapi.WXPayEntryActivity”???????android:exported=“true”???????android:launchMode=“singleTop”>???</activity></span>?? <activity android:name=".MainActivity"android:exported="true"><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="wxd31ef1f4dd******"/></intent-filter></activity><activity android:name=".AlipayH5Activity"></activity><activity android:name="com.*******.paydemo.wxapi.WXPayEntryActivity"android:exported="true"android:launchMode="singleTop"></activity></span>
Activity部分的邏輯代碼:
[java] view plaincopyprint?
IWXAPI?api?=?WXAPIFactory.createWXAPI(MainActivity.this,?null);??????????????????????????????????api.registerApp(ConstUtil.APP_ID);??????????????????????????????????PayReq?request?=?new?PayReq();??????????????????????????????????request.appId?=?ConstUtil.APP_ID;??????????????????????????????????request.partnerId?=?ConstUtil.PARTNER_ID;??????????????????????????????????request.prepayId?=?wxPrepayEntity.getPrepay_id();??????????????????????????????????request.nonceStr?=?wxPrepayEntity.getReq_noncestr();??????????????????????????????????request.timeStamp?=?wxPrepayEntity.getReq_timestamp();??????????????????????????????????request.packageValue?=?wxPrepayEntity.getReq_package();??????????????????????????????????request.sign?=?wxPrepayEntity.getReq_sign();??????????????????????????????????????????????????????????????????????api.sendReq(request);??IWXAPI api = WXAPIFactory.createWXAPI(MainActivity.this, null);//通過工廠創建對象api.registerApp(ConstUtil.APP_ID);PayReq request = new PayReq();request.appId = ConstUtil.APP_ID;request.partnerId = ConstUtil.PARTNER_ID;request.prepayId = wxPrepayEntity.getPrepay_id();request.nonceStr = wxPrepayEntity.getReq_noncestr();request.timeStamp = wxPrepayEntity.getReq_timestamp();request.packageValue = wxPrepayEntity.getReq_package();request.sign = wxPrepayEntity.getReq_sign();
// request.extData = "app data"; // optional// 在支付之前,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信api.sendReq(request);每一個參數都很關鍵的,如果簽名和包名確定都沒有問題,那么基本上是傳遞的參數有問題。最好跟做后臺的同事一起看看就能解決問題。
比如partnerId傳錯了就會出現簽名錯誤,再比如timeStamp,你用了自定義的時間戳與服務器的不一致,也會出現錯誤。
排查錯誤最好把sign這個字段的值打印出來,與服務器生成的信息做比較,參數值沒有問題才會不出問題!
Android微信支付無法調起支付的原因
1.第一種原因就是上邊的這些參數有問題。一般都是秘鑰有問題。需自己登陸商家版后臺修改??
2.需要知道微信支付是需要打包才能運行。這也是蛋疼的一點,測試只能通過log和Toast來推斷。掉不起來可以去微信開放平臺看自己配置的參數是否正確。
3.微信支付跟支付寶支付不一樣。微信支付同一訂單不會第二次跳到支付頁面 提示支付失敗,同一訂單第二次支付的時候直接在請求遇支付訂單的時候就會返回preayid為空。
所以童鞋們應該在吊起支付這一步判斷一下 ,比較服務器很容易出錯導致訂單狀態沒有改,讓用戶一直付款。
4.無法接受回調結果是因為微信規定接受支付那個類的必須在manifest里配置的包名+.wxapi里? 所以這也是比較蛋疼的一點。
5.微信支付支付過的訂單再次獲取prepare_id為null 無法掉起支付。
6. 微信支付同一訂單只能綁定一個價格 列如: ?33訂單最初的價格為1,這是獲取prepareid可以獲取到值,如果對33的價格進行修改,如果沒有生成過預支付訂單可以獲取,
如果已經生成過則獲取到的prepareid為null ?不可以調起支付
Android快速實現微信支付
如果你已經成功集成了微信登錄和分享,那么此文將助你快速集成微信支付,此文基于微信支付SDK3.1.1,也就是目前為止最新的SDK
1)微信官方的集成文檔
2)微信官方資源下載
資源下載
不過我相信,即便你看了微信的官方文檔,你依然不知道微信支付怎么集成,因為微信支付的官方文檔簡直太…..
如果你已經準備好了資源包,接下來正式開始集成
我們需要的資源其實有以下幾樣,在開始前,就這些轉備好吧
1)微信支付的APPID
2)微信支付依賴包 >>> libammsdk.jar
3)一個Activity類 >>> WXPayEntryActivity.java
這里需要特別說明一下,這個Activity類,直接從上下載到的范例代碼中copy到自己的工程中即可,這個頁面是在你調起微信支付完成支付(或取消或失敗)后,再回到你的App時會調用的一個頁面。頁面的布局可以是你自定義的布局,直接放圖講解:
先說一下這個類的路徑,網上也有一大堆介紹了,我直接放圖,路徑一定,而且必須是這樣的:
WXPayEntryActivity 的路徑
在這個類中需要注意的地方有兩個:
1、這個類中的布局是可以自定義的,如果你不需要展示什么布局,而是要跳轉頁面,把這段代碼刪除即可
回調頁面的布局
2、回調結果的處理,下面是官方的處理方式,直接給了一個dialog,很多人會摸不著頭腦,如果你不需要這個dialog,直接刪除就好了,不需要把官方demo中的布局和資源都復制過來
官方的處理方式
下面是我自定義的處理方式,比較簡單,就是土司顯示了一下支付結果,如果你需要支付成功后跳轉,那么直接在這里startActivity即可,別忘記最后要將這個頁面finish()
自定義的處理方式
這個類中的其余的回調方法,我們都不需要去操作
然后我們就可以開始支付了,支付很簡單,真的很簡單
參數列表
這是微信支付需要我們攜帶的參數,對于新人來說,可能比較困惑的是我怎么生成這些參數呢?其實這些參數都是服務器返回給我們的,APPID我們可以自己保存在本地一份,其余的都是服務器返回給我們的,大概介紹一下流程:
發起支付的流程,提交訂單的時候的參數根據項目需要配置
最后,服務器返回給我們微信支付的參數后,我們就可以愉快的支付了,這里是關鍵一步,注意!!
發起支付的關鍵步驟
至此我們已經可以調起微信支付頁面來支付了
最后還有一個需要注意的是,很多人被這一步坑了,就是關于微信開放平臺簽名的問題。其實只要你手機上的程序的簽名和你在微信平臺登記的簽名一致即可,無論是debug版本,還是release版本
參考文章:http://www.jianshu.com/p/c97639279d2e
總結
以上是生活随笔為你收集整理的android 微信支付问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。