① Unity-android集成微信支付出現返回-1問題
前段時間出去玩了一段時間,回公司得知一個驚天消息——微信支付出問題了!!!這個問題比較奇怪,說是部分機型可以支付成功,部分機型如小米、三星無法調起支付,返回-1。
眾所周知返回-1的話代表了各種各樣的錯誤(坑),所以只好從頭開始排查,首先排查 WXPayEntryActivity.java 這個文件是否放在了 .wxapi包 下,及 manifest里的注冊是否為.wxapi.WXPayEntryActivity ,確定無誤後檢查後台返回的參數是否有誤
至此如果都正確,可以開始著手檢查在後台里的參數設置是否正確
這里需要注意的是應用簽名和應用包名,因為出問題的包不是由我打包的,我懷疑問題在於應用簽名對不上,最後發現果然如此。打包的同事使用了另一個keystore文件進行打包,導致應用簽名與後台填寫的不一致,於是重新生成了簽名更新後台設置,問題解決。
至於為什麼部分機型可以正常支付,而部分機型無法調起,我參照有些coder遇到的問題「微信支付只能成功調起一次」
因為成功支付的機型為公司測試機,而不成功的機型是用戶機,猜測因為公司測試機里曾經調試過微信支付,有正確的包名和簽名的緩存,微信在調起時直接讀取緩存值,驗證正確後直接調起,而當緩存值出錯時微信才會再次去讀取新的包名和簽名重新驗證,因此出現了部分機型可支付的問題。也因為這個原因, 修改完簽名後再次調試,第一次返回的還是-1,但再次點擊就可以成功調起,此後也沒有再返回-1。 個人猜測,如有錯誤歡迎指出討論。
微信支付的坑實在是太多了,還有OC編寫的iOS的IAP也有很多藏起來的坑,一直想把Unity內調用Java集成的微信、支付寶支付,使用OC集成的iOS內購詳細過程寫上來,但是一直犯懶。。這段時間一定要寫好,給自己做個記錄,也給大家作為一個參考。
② 單個APP接入多個微信支付寶支付的一種解決方案
背景
最近在對接微信支付寶支付的時候出現了一個需求,由於我們公司在不同的地區有分公司,為了實現財務對賬方便,不同公司的客戶需要打款到相應的公司的賬戶,也就是要實現介面分賬,一聽到這個需求,我一臉懵逼,之前做商城的時候,一個APP的收款不管是微信還是支付寶,都是只打到一個賬戶裡面去,現在需要實現不管對於微信支付還是支付寶支付都需要有多個支付賬戶,實現介面分賬,當時總經理提出這個需求,Android跟ios歷史性地異口同聲地說,這個做不到,並且從技術的角度在那兒跟總經理彈了一會兒琴,畢竟還是太年輕了,總經理說,這個肯定是可以實現的,因為在他眼裡,沒有什麼是實現不了的,然後我們就回去搬磚了,然後思考這個問題的解決方案。
分析問題
需要實現的技術點
用戶支付的時候,根據用戶的uid,來把錢達到相應的賬戶裡面去,判斷身份很簡單,問題主要在於如何使得一個APP接入多個微信或者支付寶賬戶,下面來逐個分析一下微信跟支付寶的接入方式
微信
對接過微信支付的應該很熟悉上面的這些東西,首先你得去微信開放平台注冊一個賬號,一年300塊錢,然後再在這個賬號裡面開通微信支付功能,所以一開始我們嘗試的就是不停地去騷擾微信客服,問問能不能通過一個微信支付賬號進行介面分賬,每次那邊的回答都是不可以,然後又問一個APP能不能申請多個微信支付賬號,那邊回答也說是不可以,卧槽,基本上到這個份上,我們已經是放棄了,因為如果一個APP不能申請多個微信支付賬號,那麼微信基本上是做不了介面分賬了,當時IOS了解到的微信支付情況是這個樣子的,下面看看支付寶的過程。
支付寶
支付接入的時候其實也比較郁悶,苦逼之處在於支付寶以前是支持介面分賬的,也就是只需要注冊一個支付寶主賬戶,然後在注冊幾個子賬戶就可以進行介面分賬,只是我們的APP生不逢時,支付寶關閉了這個服務,而且那邊的客服也是說一個APP只能注冊一個支付寶賬戶
發現希望
基本上到這里,我們已經打算放棄了,因為畢竟跟我們最初的設想是一樣的,但是還是有點不甘心,因為在跟支付寶的技術客服,注意是技術客服,不是普通的人工客服,當時跟他說了一下我們的使用場景,他說可以通過注冊多個支付寶賬號,其實這一點跟我之前的設想是一樣的,因為Android在介入支付寶的時候不需要應用的簽名,可以通過服務端動態下發簽名,從而調起支付寶支付,我突然間好像明白了什麼,因為之前的思路走不通的原因在於總是想通過一個APP來注冊多個支付寶賬號,沒有想到用多個支付寶賬戶來實線曲線救國。
支付寶實現介面分賬
注冊支付寶賬戶
支付寶應用名稱
支付寶應用信息
支付寶支付跟微信支付最大的區別在於Android客戶端的接入,需要應用的簽名,所以如果用兩個APP注冊的話勢必會導致簽名不一致,支付寶的注冊只需要填寫一個應用名稱就好了,注意應用名稱不能一樣,否則會失敗。
基本上到這里,支付寶實現介面分賬的鏈路打通了,測試也完全通過,吼吼
微信實現介面分賬
對於微信來說,一個APP對應唯一的APPID,注冊信息大致如下:
微信支付應用名稱
微信支付應用信息
受到支付寶的啟發,能不能注冊在微信開放平台注冊兩個賬號,然後申請兩個微信支付賬號,只不過這兩個賬號除了名稱不一樣以外,其餘地全都一樣,不過雖然這么想還是有點虛,因為IOS在跟客服溝通的時候客服只是說同一個APP只能申請一個微信支付賬號,但是我們反問客服微信的判斷規則是什麼的時候,微信那邊卻說不知道,如果是名稱,那麼就能夠通過審核,如果是應用的包名或者bundleid那基本上微信接入原生的APP支付徹底走不通了。
當時是分了兩步走,總經理說微信支付必須得接入,萬一不行只能接入微信H5支付,因為H5的話就可以實現動態下發了。所以當時H5支付跟原生支付的賬號同時在申請,服務端那邊也是在做兩手的准備,比較苦逼。最後萬幸的是,微信是通過應用名稱來判斷APP的唯一性,很幸運,可以完全放棄H5支付了,微信支付介面分賬也打通了。
小結
這篇文章沒有涉及到任何技術,但是這次實現一個APP實現多個介面分賬,確實讓我感觸很多,很多時候,我們在做一件事情的時候,會調用我們以往的經驗,有好也有壞,之前做的支付都是單個微信支付寶,按照之前的經驗,在嘗試之前就做出了錯誤的判斷,很多時候還是需要敢於拆掉思維里的牆,去嘗試一些新東西,包括在實現一些功能的時候,要勇於嘗試一些新的思維,新的解決方式,尤其是在用已有的知識實現不了或者實現起來比較痛苦的時候,畢竟改變是痛苦的,不改變只會更加痛苦。
③ 匯聚,杉德,微信原生支付,支付寶成功/失敗回調記錄
1、清除微信緩存,清除微信存儲空間,重新登錄微信
2、如果有更換包名,有更換簽名文件信息,清除編譯器緩存clean Project 、Invalidate Caches/Restart,並確保包名,簽名沒錯
額外補充說一句,無論是否支付成功、失敗,最好都是輪訓請求後端進行一個驗證操作。所以對結果是怎麼樣的,我們都可以不用關心
杉德小程序支付,匯聚小程序支付,當你取消支付,點擊小程序右邊的關閉圓圈的時候,WXEntryActivity 界面會自動消失,但不會走finish,onDestroy。所以要做檢測是否真的成功或者是否支付完成,需要自行在吊起微信支付頁面或者待確認界面進行輪訓請求後台,確定是否支付成功。
杉德小程序支付、匯聚小程序支付點擊返回商戶會走onResp,也會走finish,onDestroy
支付寶支付,不像微信一樣,當你取消支付,支付成功,支付寶會幫你回調handleMessage,所以你需要在這里處理你自己的邏輯
1、原生微信APP支付,只能回調WXPayEntryActivity
2、匯聚、杉德小程序支付只能回調WXEntryActivity ,點擊返回商戶會走onResp,也會走正常的完整生命周期。如果點擊的是小程序的圓圈關閉是不會走onResp,也就沒有了WXEntryActivity 完結的生命周期,當你切回原來自己APP界面的時候,是直接在你發起小程序支付的界面了。
④ 支付寶支付和包名有關系嗎
支付寶支付和和包支付是不同的兩個支付平台,他們屬於不同的兩個公司的,完全是不一樣的支付軟體
⑤ 如何讓一個應用程序一直在後台運行
1、保活手段
1 業界保活手段:黑色保活,灰色保活,白色保活
2 黑色保活:
1 不同的APP進程,用廣播相互喚醒,包括利用系統廣播進行喚醒
2 常見手段:
1 開機,網路切換,拍照,拍視頻等利用系統廣播喚醒APP
此場景Google已經意識到,在Android N 取消了 拍照,視頻,網路切換的廣播
2 接入第三方的SDK也會喚醒相應的APP進程
3 假如你手機里裝了支付寶,淘寶,UC等阿里系的APP,那麼你打開任何一個,都有可能喚醒其他的阿里系的APP
3 白色保活:
就是調用系統的API啟動一個前台Service進程,這樣會在通知欄生成一個Notification,用戶知道哪些進程正在運行
4 灰色保活
1 保活領域應用最為廣泛,利用系統的漏洞來啟動一個前台的Service進程,與「白色保活」不同的是,它不會在通知欄生成一個Notification,用戶無法察覺,但是優先順序要高於普通的後台進程。
2 實現思路
思路一:當API<18,啟動前台的Service直接傳入new Notification();
思路二:當API >= 18,同時啟動兩個id相同的前台Service,然後再將後啟動的Service做stop處理
代碼這樣寫:
[java]view plain
importandroid.app.Notification;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.Build;
importandroid.os.IBinder;
/**
*APP灰色保活
*Createdbyfflinon2016/4/23.
*/
{
privatefinalstaticintGRAY_SERVICE_ID=1001;
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
@Override
publicintonStartCommand(Intentintent,intflags,intstartId){
//API<18,此方法能有效地隱藏notification的圖標
if(Build.VERSION.SDK_INT<18){
startForeground(GRAY_SERVICE_ID,newNotification());
}else{
Intentintent1=newIntent(this,GrayInnerService.class);
startService(intent1);
startForeground(GRAY_SERVICE_ID,newNotification());
}
returnsuper.onStartCommand(intent,flags,startId);
}
//給API>=18的平台上做灰色保護手段
{
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
@Override
publicintonStartCommand(Intentintent,intflags,intstartId){
startForeground(GRAY_SERVICE_ID,newNotification());
stopForeground(true);
stopSelf();
returnsuper.onStartCommand(intent,flags,startId);
}
}
}
3 檢驗方法:
首先看系統通知欄有沒有Notification,如果沒有,就進入手機adb shell模式,輸入命令mpsys activity services PackageName
列印出指定包名的所有進程中的service信息,看下有沒有isForground=true的信息,如果有,就說明了該APP使用了灰色保活
4 使用灰色保活手段並不意味著你的應用就能永生不死,只能說提高了進程的優先順序,如果應用佔用了很大的內存,還是會被回收的
2、進一步理解保活
1 進程回收機制
系統出於體驗和性能上的考慮,APP在退出後台時系統並不會真正的kill掉這個進程,而是將其緩存起來,打開的應用越多,後台緩存的進程也就越多。在系統內存不足的情況下,系統開始根據自身的一套進程回收機制來判斷要回收掉哪些進程,這套殺死進程回收內存的機制叫 Low Memory Killer,它是基於Linux內核的OOM killer機制誕生的,該機制為每個系統分配了一個值,叫做oom_adj,代表了進程的優先順序,oom_adj越大,代表優先順序越低,越容易被回收,普通APP進程的oom_adj >=0,系統的可能會小於0.
2 查看oom_adj的值,需要用到兩個shell命令
ps | grep 包名
$cat /proc/進程id/oom_adj
3 結果發現,APP推到後台,UI進程的值降低最為明顯,因為它佔用的內存資源最多,因此,為了避免後台UI進程被殺,需要盡可能的釋放一些不用的圖片,音頻資源