1. 程式人生 > >微信SDK踩過的那些坑。。登入分享支付

微信SDK踩過的那些坑。。登入分享支付

由於第一次接微信SDK。沿路踩過一個又一個大大小小的坑,以此做一下記錄。

對於安卓版來說。前期一些基本jar匯入。xml配置什麼的都基本不會有什麼問題,按照微信文件來就可以了。

第一個坑在出在簽名上,第三方應用要拉起微信必須保證2點:

1.應用中的包名(Mainfext.xml中的package)必須與後臺配置的一致。

2.應用生成不能是debug包,必須是正式的簽名包。這個簽名必須與後臺配置的一致。

在第一點上,會出錯的概率還是比較小的。

主要出錯會在第2點上,微信官方有微信簽名檢測工具。用檢測工具檢測到的簽名是一串小寫並且中間沒有冒號的字串。

而在後臺配置的卻是直接從在eclipse打簽名包時直接複製出來的MD5簽名。(大寫,並且中間夾雜:)

所以後臺配置的簽名必須與打包時的簽名一致。必須是小寫無冒號的字串

第二個坑出現在接登入的時候,在拉起微信授權登入之後無法自動返回第三方應用。

問題出在判斷微信是否安裝上。用了api.openWXApp(),導致開啟微信後無法返回,修改為 api.isWXAppInstalled()就完美解決問題了。

  1. publicstaticvoid sendMsgtoWX()  
  2. {  
  3.  System.out.println("hwt c-----------------sendMsgtoWX");  
  4.     if(api.isWXAppInstalled())  
  5.     {     
  6.             // send oauth request 
  7.             SendAuth.Req req = new SendAuth.Req();  
  8.             req.scope = "snsapi_userinfo";  
  9.             req.state = "login_state";  
  10.             api.sendReq(req);  
  11.     }  
  12.     else
  13.     {  
  14.         ShowMsg(1);  
  15.     }  

第三個坑出現在分享圖片的時候。微信對於圖片分享中,對圖片的大小做了限定。圖片分享中主要是兩部分,一個分享出去就直接能看到的一張比較小的圖。還有一張就是點選之後出現的圖片。兩張圖片的具體大小沒有做測試。但是知道第一個圖片必須比較小。太大就會出現無法拉起分享的情況。第二張圖片比較大。基本1M左右應該都沒什麼問題。

  1. //分享圖片到微信
  2.    publicvoid shareImgToWeixin(String path,int type)//type = 1 好友。type = 2 朋友圈
  3.    {  
  4.      System.out.println("----------shareToWeixin--path:"+path);  
  5.         File file = new File(path);  
  6.         if (!file.exists()) {  
  7.             ShowMsg(2);  
  8.             return;  
  9.         }  
  10.         if(api.isWXAppInstalled())  
  11.         {  
  12.             if(type == 1)  
  13.             {  
  14.                 Bitmap bmp = BitmapFactory.decodeFile(path);  
  15.                 WXImageObject imgObj = new WXImageObject(bmp);  
  16.                         imgObj.setImagePath(path+"screenshot.png");  
  17.                 int num1 =bmp.getByteCount();  
  18.                  int w =bmp.getWidth();  
  19.                  int h =bmp.getHeight();  
  20.                  float scal = 100/(float)w;  
  21.                  w = (int)(w*scal);  
  22.                  h = (int)(h*scal);  
  23.                  System.out.println("----------thumbBmp w:"+w+"h:"+h);  
  24.                 Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, w,h, true);  
  25.                 int num =thumbBmp.getByteCount();  
  26.                  System.out.println("----------thumbBmp num1:"+num1+"------num:"+num);  
  27.                 bmp.recycle();  
  28.                 WXMediaMessage msg = new WXMediaMessage();  
  29.                 msg.mediaObject = imgObj;  
  30.                 msg.thumbData = Util.bmpToByteArray(thumbBmp, true);  
  31.                 SendMessageToWX.Req req = new SendMessageToWX.Req();  
  32.                 req.scene = (type == 1)?SendMessageToWX.Req.WXSceneSession:SendMessageToWX.Req.WXSceneTimeline;  
  33.                 req.transaction = buildTransaction("img");  
  34.                 req.message = msg;  
  35.                 api.sendReq(req);    
  36.             }  
  37.         }  
  38.     }  

在微信支付中遇到的問題還是挺多的,因為微信的流程中資料的接收和傳送都是xml格式的。由於之前沒有對xml格式做過處理,走了不少彎路。

其實流程很簡單,就是將資料拼成xml格式post發過去,再解析xml格式的資料獲得引數。微信第一部分統一下單,由於各種原因我們放在了客戶端中處理。服務端只是生成了一個商戶訂單號。

由於我們的專案ios和安卓是同一套程式碼。所以我們將第一部分統一下單放在了cocos中實現。

其中需要注意的幾點是:在生成簽名的時候,必須把需要傳送過去的引數,除了sign本身之外都需要打進去,少一個都不行。簽名就按照微信官方文件來就可以了。

需要簽名的引數大寫與小寫所生成的簽名是不一樣的。所以,我把需要簽名的引數都是小寫,再在最後轉化為大寫。還有簽名中的key並非AppID或AppSectet,而是在商戶平臺設定的,官方描述為“key設定路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設定-->API安全-->金鑰置”。

  1. void WXMessage::SendFirstDate(std::string out_trade_no,std::string price,std::string body)  
  2. {  
  3.     //網路非同步連線方法
  4.     HttpRequest* request = new HttpRequest();  
  5.     request->setUrl("https://api.mch.weixin.qq.com/pay/unifiedorder");  
  6.     request->setRequestType(HttpRequest::Type::POST);  
  7.     request->setResponseCallback(this, httpresponse_selector(WXMessage::onHttpRequestCompleted));  
  8.     std::string postData = "";  
  9.     postData += "<xml>";  
  10.     postData += "\n";  
  11.     postData += "<appid><![CDATA["+(std::string)wx_appid+"]]></appid>";  
  12.     postData += "\n";  
  13.     postData += "<mch_id><![CDATA["+(std::string)wx_mchid+"]]></mch_id>";  
  14.     postData += "\n";  
  15.     postData += "<nonce_str><![CDATA["+rand_str()+"]]></nonce_str>";  
  16.     postData += "\n";  
  17.     postData += "<sign><![CDATA["+Getsign(out_trade_no,price,body)+"]]></sign>";  
  18.     postData += "\n";  
  19.     postData += "<body><![CDATA["+body+"]]></body>";  
  20.     postData += "\n";  
  21.     postData += "<out_trade_no><![CDATA["+out_trade_no+"]]></out_trade_no>";  
  22.     postData += "\n";  
  23.     postData += "<total_fee>"+price+"</total_fee>";  
  24.     postData += "\n";  
  25.     postData += "<spbill_create_ip><![CDATA["+GetIP()+"]]></spbill_create_ip>";  
  26.     postData += "\n";  
  27.     postData += "<notify_url><![CDATA["+(std::string)wx_notify_url+"]]></notify_url>";  
  28.     postData += "\n";  
  29.     postData += "<trade_type><![CDATA["+(std::string)wx_trade_type+"]]></trade_type>";  
  30.     postData += "\n";  
  31.     postData += "</xml>;       <pre name="code" class="cpp">  
request->setRequestData(postData.c_str(),postData.size());
    HttpClient::getInstance()->send(request);
    request->release();
}
  1. void WXMessage::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)  
  2. {  
  3.     if (!response) {  
  4.         return;  
  5.     }  
  6.     if (0 != strlen(response->getHttpRequest()->getTag())) {  
  7.         log("%s completed",response->getHttpRequest()->getTag());  
  8.     }  
  9.     long statusCode = response->getResponseCode();  
  10.     char statusString[64] = {};  
  11.     sprintf(statusString, "HTTP Status Code: %ld, tag = %s",statusCode,response->getHttpRequest()->getTag());  
  12.     log("response code: %ld",statusCode);  
  13.     if (!response->isSucceed()) {  
  14.         log("response failed");  
  15.         log("error buffer: %s",response->getErrorBuffer()