目錄
準備工作
微信登錄和支付
支付寶登錄和支付
對比
準備工作
微信
注冊微信開放平臺歧沪,成為開發(fā)者(開發(fā))
注冊你的App熊咽,會給你一個AppId和AppSecret
注冊微信商戶平臺,成為商戶(收錢)
會給你一個商戶ID
共有三個ID:AppID铁材、AppSecret、PID
支付寶
注冊螞蟻金服開放平臺,成為開發(fā)者(開發(fā))
開放平臺會給你的App一個AppId(支付寶沒有AppSecret)
注冊螞蟻金服商家中心亩鬼,成為商家(收錢)
商家中心會給你一個商家ID
共有兩個ID:AppID、PID
微信登錄和支付
開放平臺創(chuàng)建應(yīng)用
首先阿蝶,你在微信開放平臺上要有自己的應(yīng)用
平臺會讓你上傳你的App的logo雳锋,名稱,簡述什么的羡洁,因為這些在你調(diào)用微信App的時候用得著玷过。
微信登錄
首先,要在開放平臺中為你的App申請相關(guān)接口(微信登錄是默認開放給你的)
然后筑煮,就是代碼工作了辛蚊。
我是用ShareSDK套件統(tǒng)一實現(xiàn)的微信登錄,集成ShareSDK的方法見在App中集成ShareSDK真仲。
登錄過程就是調(diào)用ShareSDK的函數(shù)袋马,傳入微信登錄的參數(shù)
然后,用一個listener去監(jiān)聽登錄授權(quán)
這個listener會監(jiān)聽到一個Platform對象秸应,從Plateform對象中可以取出用戶id飞蛹、昵稱、頭像等
so easy
微信支付
支付的基本流程
實現(xiàn)微信支付灸眼,流程上比登錄復(fù)雜多了卧檐,具體流程如下:
1.授權(quán)
微信第三方支付是需要去開放平臺申請權(quán)限的:
2.簽約
相關(guān)的商家需要去在線簽約:
3.文檔
微信在官方文檔中提供了很多種支付方式,我們使用的是其中的App支付:
根據(jù)官方文檔焰宣,支付流程如下:
看起來很復(fù)雜霉囚,其實大概分這么幾步:
1.你的業(yè)務(wù)服務(wù)器和微信后臺交互生成訂單,微信后臺給業(yè)務(wù)服務(wù)器一個預(yù)交易訂單號
(微信后臺準備好支付數(shù)據(jù))
2.你的業(yè)務(wù)服務(wù)器給你的App預(yù)交易訂單號
(你的后臺通知你的App去調(diào)起微信支付)
3.你的App調(diào)起微信App支付匕积,把預(yù)交易訂單號傳給微信App
(你的App發(fā)起微信App支付)
4.微信App告知你的App支付完成盈罐,微信后臺告知你的業(yè)務(wù)服務(wù)器支付完成
(App對App,后臺對后臺)
整個故事情節(jié)大概是這樣的
需要注意的是闪唆,微信官方文檔有這么一句話:
注意一定不能以客戶端返回作為用戶支付的結(jié)果盅粪,應(yīng)以服務(wù)器端的接收的支付通知或查詢API返回的結(jié)果為準。
就是說悄蕾,你的App只負責(zé)觸發(fā)下一步業(yè)務(wù)流程票顾,是否支付成功要以你的業(yè)務(wù)服務(wù)器收到的通知為準础浮。
支付的具體實現(xiàn)
代碼實現(xiàn)上,微信的官方文檔說的挺明白的奠骄,照做吧:
1.在gradle里添加引用
2.初始化一個IWXAPI實例
3.利用IWXAPI實例去請求調(diào)起支付
4.實現(xiàn)一個給微信支付回調(diào)的Activity
在支付完成時豆同,微信App會自動打開這個回調(diào)Activity,如果你沒有定義這個Activity的外觀含鳞,你會發(fā)現(xiàn)影锈,手機白屏了
你可以好好畫畫這個Activity的界面,也可以不去管它蝉绷,在完成下面的操作后鸭廷,直接關(guān)掉。
這個回調(diào)Activity熔吗,主要功能是接收微信反饋的支付結(jié)束事件
反饋的BaseResp對象沒啥有用信息靴姿,因為微信的App支付接口純粹是個觸發(fā)器,只能用來通知支付結(jié)束磁滚,你從它的反饋信息里佛吓,無法得到訂單號。
那業(yè)務(wù)服務(wù)器怎么知道是哪個訂單完成了支付呢垂攘?
你的App和業(yè)務(wù)服務(wù)器自己想辦法吧维雇。
支付寶登錄和支付
【高能預(yù)警】支付寶的文檔晒他,真的超級爛吱型!超級爛!超級爛陨仅!你可以信任它的支付津滞,但不可以信任它的文檔!
【嚴正警告】除了你抓到的真實數(shù)據(jù)灼伤,不要相信支付寶的官方文檔和Demo代碼触徐,要小心支付寶!要小心支付寶狐赡!要小心支付寶撞鹉!
開放平臺創(chuàng)建應(yīng)用
首先,你在螞蟻金服開放平臺上要有自己的應(yīng)用
平臺會讓你上傳你的App的logo颖侄,名稱鸟雏,簡述什么的,因為這些在你調(diào)用支付寶App的時候用得著览祖。
支付寶登錄
ShareSDK里沒有集成支付寶登錄孝鹊,我們需要自己實現(xiàn)。
登錄的基本流程
1.授權(quán)
首先展蒂,你要去開放平臺請求授權(quán)
每個App有對應(yīng)的授權(quán)功能列表
點擊圖中右上角的“繼續(xù)添加”又活,可以看到支付寶提供的接口列表苔咪,其中有很多迷惑性的名字,要選擇恰當(dāng)?shù)慕涌诜?wù)皇钞,我們需要選擇的是App支付寶登錄
2.簽約
很多服務(wù)悼泌,是需要簽約之后才能生效的
簽約過程需要一定的周期松捉,而且需要公司相關(guān)人員出面
3.文檔
是的夹界,雖然支付寶的文檔很爛,但是隘世,原始文檔還是要看的可柿,App支付寶登錄產(chǎn)品介紹
把里面的流程圖摘出來
眼花了是不是?梳理一下步驟:
1.你的App調(diào)起支付寶App授權(quán)丙者,用戶確認后复斥,支付寶App返回一個openid和authcode
(支付寶App認可你,給你兩樣?xùn)|西械媒,一個是用戶id目锭,一個是安全信物)
2.你拿著authcode向支付寶后臺服務(wù)換一個token
(因為你有安全信物,所以支付寶后臺也認可你)
3.有了這個token纷捞,其實你就有權(quán)限去做很多事情了痢虹,比如,再去支付寶后臺查查用戶的昵稱主儡,頭像什么的奖唯,對應(yīng)的接口是支付寶用戶信息查詢接口(這是一個后臺接口,我也是在后臺做的查詢)
(因為支付寶后臺認可你糜值,所以你可以去后臺查詢用戶的昵稱和頭像)
整個流程涉及到你和支付寶雙方的App丰捷,雙方的后臺服務(wù)器,故事情節(jié)大概可以這樣理解
這個故事還有另外一個版本:
支付寶:“你要用戶ID寂汇,還要登錄病往?好啊,沒問題”
支付寶:“神馬骄瓣?你要用戶昵稱和頭像荣恐?保安!保安累贤!保安叠穆!...”
登錄的具體實現(xiàn)
在調(diào)起支付寶App登錄時,其實就是從我們的App里調(diào)用支付寶App一個接口函數(shù)的過程臼膏,大概分三步:
1.準備函數(shù)的參數(shù)(按照規(guī)定的格式硼被,拼出一個請求的String)
2.調(diào)用函數(shù)(支付寶接口中AuthTask的authV2)
3.接收函數(shù)的返回值(一個Map),從中取出authcode和用戶openid
步驟很簡單吧渗磅,支付寶還貼心的提供了demo代碼嚷硫,具體流程是這樣的
1.用開放平臺給你的AppId检访,商戶PId,RSA私鑰一起仔掸,拼出請求的String
最終拼出來的authInfo大概長這個樣子
2.調(diào)用AuthTask的authV2函數(shù)
3.把返回的Map映射為AuthResult函數(shù)脆贵,從中取出authcode和用戶id
當(dāng)然這個過程是異步的,看起來很簡單是吧起暮?可是卖氨,當(dāng)我們仔細觀摩支付寶官方Demo代碼的時候,我們就會發(fā)現(xiàn)...
demo代碼里有這樣一段話
也就是說负懦,第一步是錯的筒捺,你不要自己去拼參數(shù),因為你的App不能持有RSA私鑰纸厉!
為什么系吭?因為不安全啊,RSA私鑰放在App里颗品,攻擊者很容易通過逆向你的App來搞出你的RSA私鑰肯尺,所以這幾乎就相當(dāng)于面向社會公開了你的銀行卡密碼啊
那你怎么獲取這個參數(shù)呢?也就是這個authInfo呢躯枢?
我們看authInfo里面的這些字段则吟,其實就是sign需要用到RSA加密,而sign又是安全不可逆的闺金,所以我們可以向我們自己的業(yè)務(wù)服務(wù)要這個sign逾滥。
那么業(yè)務(wù)服務(wù)器是怎樣生成的這個sign呢?
業(yè)務(wù)服務(wù)器保存有RSA嘍...
業(yè)務(wù)服務(wù)器败匹,請你一定要安全啊...
支付寶支付
支付的基本流程
1.授權(quán)(參考登錄)
2.簽約(參考登錄)
3.文檔(參考登錄寨昙,這次的官方文檔位置在App支付)
根據(jù)官方文檔,App支付的流程是這樣的:
我再來梳理一下步驟掀亩,梳理一下步驟:
1.你的業(yè)務(wù)服務(wù)器做好訂單信息舔哪,安全簽名后發(fā)給你的App
(你的業(yè)務(wù)服務(wù)器負責(zé)RSA加密)
2.你的App拿著訂單信息,去請求支付寶App支付
(支付寶App解密訂單信息槽棍,確認訂單安全)
3.支付寶App通知你的App支付完成捉蚤;同時,支付寶后臺服務(wù)通知你的業(yè)務(wù)服務(wù)器支付完成)
(App對App炼七,后臺對后臺)
整個流程涉及到你和支付寶雙方的App缆巧,雙方的后臺服務(wù)器,故事情節(jié)大概可以這樣理解
需要注意的是豌拙,支付寶官方文檔里有這么一句話:
同步返回的數(shù)據(jù)陕悬,只是一個簡單的結(jié)果通知,商戶確定該筆交易付款是否成功需要依賴服務(wù)端收到支付寶異步通知的結(jié)果進行判斷
這句話的意思就是說按傅,雖然你的App也會收到反饋捉超,但是必須以業(yè)務(wù)服務(wù)器為準
你的App收到支付成功的反饋胧卤,其實是用來觸發(fā)下一步業(yè)務(wù)操作的
支付的具體實現(xiàn)
支付的具體實現(xiàn)如下:
1.業(yè)務(wù)服務(wù)器發(fā)訂單信息到你的App,你可能會給服務(wù)器開放一個這樣的接口:
public void payAli(String orderinfo) {...}
2.你的App調(diào)用支付寶的接口
Map result = alipay.payV2(orderInfo, true);
3.你的App收到支付結(jié)束的通知拼岳,從支付寶App的返回值中尋找自己需要的數(shù)據(jù)
然后枝誊,你就可以告訴你的業(yè)務(wù)服務(wù)器:
“哥,支付寶App剛剛跟我說惜纸,他們給過錢了”
你的業(yè)務(wù)服務(wù)器很可能會問你:
“給錢的是靠墻的那桌叶撒,還是靠窗的那桌?”
你說:
“我...我找找”
然后堪簿,你就會栽進坑里...
要小心支付寶痊乾!
關(guān)于支付結(jié)果的一個坑
前面說過皮壁,App支付時椭更,需要異步調(diào)起一個PayTask執(zhí)行支付操作,真正執(zhí)行支付的是這行代碼:
Map result = alipay.payV2(orderInfo, true); //執(zhí)行支付操作
result就是支付寶反饋給App的支付結(jié)果蛾魄,在(成功/失敗/超時/取消)支付操作后虑瀑,我們把這個Map通過Message傳遞給Handler,Handler里會把這個Map映射為PayResult對象滴须,根據(jù)PayResult去處理后續(xù)邏輯舌狗。
根據(jù)支付寶官方文檔及Demo代碼,我們通過PayResult對象的ResultStatus(=9000)就可以判斷是否支付成功扔水,交易訂單號也可以從PayResult中找到痛侍,但是這里有個潛在的大坑:如何獲取交易訂單號,支付寶并沒有做完全的說明魔市,事實上:
--當(dāng)交易成功時主届,我們要從PayResult的result字段中獲取成功交易信息(但是,交易失敗時result字段為空待德,而且官方文檔沒有提到這一點)
--當(dāng)交易失敗時君丁,我們要從PayResult的memo字段中獲取原始交易信息(但是,官方文檔沒有確認這一點)
--當(dāng)交易取消時将宪,PayResult的result字段為空绘闷,memo字段值為“操作已取消”
而且我們不能根據(jù)這個現(xiàn)象做決策,還記得嗎较坛,要小心支付寶印蔗!要小心支付寶!要小心支付寶丑勤!
對自己負責(zé)任的做法是华嘹,在支付的一開始,就要對支付寶的不靠譜有所防備确封,我的做法是除呵,在異步執(zhí)行PayTask的時候再菊,我自己把原始支付信息記錄下來,因為原始支付信息是我們自己的后臺業(yè)務(wù)服務(wù)器發(fā)給我們的颜曾,在與支付寶的合作中纠拔,只有我們自己人是可信賴的,所以原始信息是可信賴的泛豪,我從原始信息中取出交易訂單號稠诲,放進Map里,哪個Map诡曙?這個Map:
Map result = alipay.payV2(orderInfo, true); //執(zhí)行支付操作
在這行代碼下臀叙,我會向Map中增加一條信息,就是我們自己的后臺業(yè)務(wù)服務(wù)器發(fā)給我的原始支付信息价卤。
這樣的話劝萤,原始支付信息會在Map中,隨著Message一起發(fā)給處理支付結(jié)果的Handler慎璧。
Handler仍然會把Map轉(zhuǎn)換為PayResult
而我會這樣獲取交易訂單號:
1.先從PayResult的result字段中床嫌,嘗試解析支付寶的成功交易信息
2.如果上一步取到的結(jié)果為空,就從Map中取出我們的原始交易信息
實際上就是加一層保險胸私,以確毖岽Γ可以獲取到交易訂單號
如果有人問,為什么不根據(jù)交易成功或失敗岁疼,分別從PayResult的result或memo中獲取交易信息阔涉?
我只能說,too naive捷绒,這可是文檔超級爛的支付寶瑰排,你可以信任它的支付,但不可以信任它的文檔疙驾!
我最后說一遍凶伙,要小心支付寶!要小心支付寶它碎!要小心支付寶函荣!
關(guān)于支付寶沙箱
支付寶在螞蟻金服的官方開放平臺提供了一個貌似很有用的沙箱環(huán)境,可以在沙箱中模擬支付行為扳肛。
這個沙箱呢傻挂,其實還是挺有用的,這個測試環(huán)境會提供一套虛擬的賬戶挖息,用來模擬交易行為金拒,幫助檢查你的接口寫得有沒有問題(支付寶:反正給你沙箱了,文檔我就隨便寫寫吧)。
另外绪抛,你順便還可以在沙箱里體驗一下资铡,擁有1/10個億,是什么感覺...
當(dāng)然幢码,支付寶沙箱提供了對應(yīng)的沙箱App
不過笤休,等你興沖沖去下載的時候,你會發(fā)現(xiàn)症副,沙箱App只提供Android版店雅,而且...
這個沙箱App,基本沒啥用罢晗场闹啦!沒啥用啊T印窍奋!沒啥用啊圣勒!
沒錯摧扇,如果你要在App中對接支付寶登錄和支付寶支付圣贸,沙箱環(huán)境跟你是沒有關(guān)系的,后臺能用上沙箱環(huán)境扛稽,至于App端么...
還是老老實實等真實線上環(huán)境搭好吁峻,用1分錢大法來測試吧...
對比
ID
微信需要三個ID:AppID、AppSecret在张、PID
支付寶需要亮哥ID:AppID用含、PID
多平臺跳轉(zhuǎn)
微信過于分散,從開放平臺就不容易跳轉(zhuǎn)到商戶平臺
螞蟻金服集中的比較好帮匾,各平臺互相跳轉(zhuǎn)地很舒服
引用
微信使用gradle引用啄骇;支付寶使用jar包引用
登錄
微信登錄已經(jīng)集成在ShareSDK了;支付寶沒有集成
支付
雙方都要求以服務(wù)器收到的信息為準瘟斜,但是微信要求的更徹底缸夹,微信的返回值連訂單號都沒有
調(diào)微信App支付時,你的App不知道訂單號(預(yù)交易訂單號不是訂單號)螺句;調(diào)支付寶App支付時虽惭,你的App知道訂單號(而且知道詳細的交易信息)
微信App是通過接口回調(diào)異步反饋的;支付寶App是通過函數(shù)返回值異步反饋的
微信主要通過后臺對后臺的方式傳遞訂單和支付信息蛇尚;支付寶則是主要通過App
(如果說支付行為好像是上樓簽合同的話芽唇,在微信App支付里,你的后臺是那個上樓送合同的人取劫,你的App只是個按電梯開關(guān)的匆笤;在支付寶App支付研侣,你的App是那個拿著合同上樓的人)
微信先通過后臺完成支付,然后通知App炮捧;支付寶先通過App完成支付义辕,然后后臺跟進
微信支付成功會跳轉(zhuǎn)Activity(要自己寫);支付寶是純邏輯處理
分享
都在ShareSDK中集成了
文檔
微信的文檔結(jié)構(gòu)是這樣的
支付寶的文檔結(jié)構(gòu)是這樣的
看起來好像差不多寓盗,但是你真正用過之后就會發(fā)現(xiàn)灌砖,這就是兩種文檔,它們之間的區(qū)別是這樣的: