曾經(jīng)做過(guò)支付模塊,當(dāng)時(shí)只是考慮了正流程,其他的也沒(méi)有太多的考慮,感覺(jué)支付也挺簡(jiǎn)單的。然而,最近在項(xiàng)目中,全面負(fù)責(zé)支付這一模塊,瞬間覺(jué)得自己曾經(jīng)思維是多么的不縝密。廢話就不多說(shuō)了。邊寫邊整理一下這塊邏輯實(shí)現(xiàn)。
前提1:支付方式 1.支付寶支付 2.余額支付
前提2:支付返回結(jié)果,不以支付寶同步返回結(jié)果為準(zhǔn),是以本地服務(wù)器為基準(zhǔn)的。
前提3:在沒(méi)有安裝支付寶的前提下,余額支付與支付寶支付操作方式一樣。
基礎(chǔ)工作1:判斷是否安裝了支付寶APP
當(dāng)存在支付寶支付方式時(shí),我們需要做的第一件事情就是需要判斷手機(jī)是否安裝了支付寶APP。雖然在你拿著支付串去調(diào)用支付寶的時(shí)候,支付寶自己會(huì)識(shí)別,但是你自己程序內(nèi)的邏輯也需要進(jìn)行判斷,后面寫到的細(xì)節(jié)會(huì)解釋這塊內(nèi)容。
如何判斷你手機(jī)內(nèi)是否安裝了支付寶APP,見下面代碼:


同時(shí),還需要再plist進(jìn)行配置白名單,否則iOS9以上這個(gè)判斷無(wú)效。
基礎(chǔ)工作2:注冊(cè)監(jiān)聽home鍵是否進(jìn)入前臺(tái)。后面寫到的細(xì)節(jié)會(huì)解釋這塊內(nèi)容。

創(chuàng)建訂單的過(guò)程就不說(shuō)了,直接從拿著p++的訂單NSData串去調(diào)支付寶開始。
支付寶支付:
1.手機(jī)安裝了支付寶APP時(shí):
(1)調(diào)起支付寶時(shí),對(duì)于我們自己的APP來(lái)說(shuō),相當(dāng)于執(zhí)行了home鍵。我們的應(yīng)用進(jìn)入后臺(tái),支付寶應(yīng)用進(jìn)入前臺(tái)。此時(shí)為了避免重復(fù)下單,需要記錄我們APP的支付頁(yè)面此時(shí)執(zhí)行到流程的哪一步了。
(2)進(jìn)入支付寶頁(yè)面,我們可能會(huì)有4種操作方式。

A:對(duì)于iOS9以上系統(tǒng)來(lái)說(shuō),我們直接點(diǎn)擊左上角返回鍵,直接返回我們自己的應(yīng)用。
這種情況下返回我們的應(yīng)用,是不走我們生命周期函數(shù)的。也不會(huì)走支付寶同步回調(diào)的那個(gè)方法的,此時(shí)是沒(méi)有完成支付的。
存在的問(wèn)題:
如果我們前期不記錄離開我們自己應(yīng)用時(shí)的執(zhí)行狀態(tài),此時(shí)再次點(diǎn)擊支付按鈕,就是重復(fù)創(chuàng)建訂單重復(fù)獲取p++串,重復(fù)調(diào)用sdk了。這顯然不是我們想要的結(jié)果。
解決方法:
a.在執(zhí)行下面這段代碼調(diào)起支付寶之前,先記錄上次離開APP時(shí)這個(gè)界面執(zhí)行到哪一步了,(到這里,應(yīng)該是執(zhí)行到獲取p++串進(jìn)行調(diào)用支付寶sdk這個(gè)流程了)

b.返回到我們應(yīng)用時(shí),我們使用home鍵監(jiān)聽,再監(jiān)聽的方法里去請(qǐng)求后臺(tái)服務(wù)器是否支付成功。也就是支付查詢結(jié)果協(xié)議。當(dāng)然此時(shí)后臺(tái)肯定會(huì)告訴你支付沒(méi)有成功,后續(xù)處理方式因需求而異了。比如,重試,直接再次調(diào)起支付寶。
c.這里仍然需要注意一個(gè)小小的細(xì)節(jié)就是,home鍵監(jiān)聽稍微慢了些,也就是說(shuō)先返回我們應(yīng)用,之后也就是1s左右,home鍵監(jiān)聽的方法才執(zhí)行,此時(shí)頁(yè)面支付按鈕仍然是可點(diǎn)擊的,為了防止他點(diǎn)擊,我們?nèi)匀豢梢栽谟涗浬洗雾?yè)面流程執(zhí)行到哪一步的地方同時(shí)將頁(yè)面可點(diǎn)擊狀態(tài)設(shè)置為不可點(diǎn)擊,等到請(qǐng)求回支付查詢結(jié)果協(xié)議后,變成可點(diǎn)擊狀態(tài)。這個(gè)處理也是因需求而異了。
B:我們點(diǎn)擊取消,返回我們自己的應(yīng)用
當(dāng)我們?cè)谥Ц秾氈悬c(diǎn)擊取消,此時(shí)支付寶會(huì)同步回調(diào)到我們的應(yīng)用中,告訴我們支付失敗,這里需要注意一個(gè)細(xì)節(jié)。
a.我們的應(yīng)用先執(zhí)行回調(diào)方法,后home鍵監(jiān)聽的方法才執(zhí)行,這個(gè)時(shí)候產(chǎn)生問(wèn)題
存在問(wèn)題:
在回調(diào)方法里會(huì)查詢一次支付結(jié)果請(qǐng)求,在home鍵監(jiān)聽方法里也會(huì)查詢一次支付結(jié)果請(qǐng)求。這樣顯然不合理。也會(huì)影響后續(xù)的操作。
解決方法: 【我的這種解決方法不是最優(yōu)啦?!?/p>
因?yàn)檎{(diào)起支付寶進(jìn)行支付,后續(xù)可能存在多種情況返回我們自己的應(yīng)用,方便統(tǒng)一且不容易出錯(cuò),在手機(jī)安裝了支付寶APP應(yīng)用的前提下,不管哪種方式返回我們自己的應(yīng)用,都已home鍵監(jiān)聽為主,進(jìn)行查詢支付結(jié)果。這樣就避免查詢2次的可能。如果不以home鍵監(jiān)聽為主的話,我們會(huì)先請(qǐng)求支付查詢結(jié)果,后由支付寶再打開我的APP。如果查詢結(jié)果很快,當(dāng)查詢結(jié)果這個(gè)協(xié)議后續(xù)還有其他邏輯,比如延遲返回上一頁(yè),這時(shí)就會(huì)產(chǎn)生時(shí)間問(wèn)題。比如支付寶打開我們的APP慢了些,導(dǎo)致支付寶返回我們APP直接返回到支付頁(yè)面的上一頁(yè)了
【有看我文章的小伙伴們,幫我一下,怎么實(shí)現(xiàn),同步線程中,執(zhí)行2個(gè)延時(shí)方法。也就是說(shuō),讓2個(gè)延時(shí)方法同步執(zhí)行。我目前測(cè)試得到的結(jié)果是,同步線程中,存在2個(gè)延遲執(zhí)行的方法,他們兩個(gè)并不是同步執(zhí)行。也就是說(shuō)存在同步線程異步執(zhí)行的問(wèn)題?!?/p>
C:我們點(diǎn)擊home鍵,將支付寶應(yīng)用掛起,此時(shí)重新點(diǎn)擊我們自己的應(yīng)用切換到前臺(tái)。
重新點(diǎn)擊我們的應(yīng)用進(jìn)入前臺(tái),此時(shí)是不走支付頁(yè)面的生命周期函數(shù)的。
存在問(wèn)題:與A一樣
解決方法:與A一樣
D:我們正常支付,支付成功或者失敗后,自動(dòng)返回我們自己的應(yīng)用。
存在問(wèn)題:與B一樣。
解決方法:與B一樣。
2.手機(jī)沒(méi)有安裝支付寶及采用余額支付時(shí)
手機(jī)沒(méi)有安裝支付寶,當(dāng)我們拿著支付寶串去調(diào)支付寶時(shí)候,會(huì)通過(guò)支付寶sdk在我們的應(yīng)用內(nèi)直接調(diào)起支付寶網(wǎng)頁(yè)進(jìn)行支付。這時(shí)候就不會(huì)涉及到我們的APP打開支付寶或者支付寶打開我們的APP這些操作,也不會(huì)有因?yàn)槲覀儜?yīng)用于支付寶應(yīng)用相互之間相互打開中間所產(chǎn)生的home鍵監(jiān)聽問(wèn)題。
余額支付,直接在應(yīng)用內(nèi)完成,不會(huì)調(diào)起支付寶。所以,余額支付與手機(jī)沒(méi)有安裝支付寶支付的操作是一樣的。他們只需要在支付回調(diào)方法里處理邏輯。
總結(jié):
感覺(jué)自己寫的比較固執(zhí)。大部分是按照項(xiàng)目需求進(jìn)行寫了。還有些細(xì)節(jié)可能因需求而異不會(huì)那么做,也就沒(méi)寫了。但是主流程我覺(jué)得還是可以跟大家分享的。有不當(dāng)?shù)牡胤?,希望看到的朋友們能幫我指出?lái)。重要的是我提的問(wèn)題,這個(gè)很急,有知道的朋友聯(lián)系我呀(QQ:702042658)。超級(jí)感謝了。