問(wèn)題:iOS內(nèi)購(gòu)漏單的問(wèn)題

事由:
不久前,有用戶反映,大概意思是這樣:蘋(píng)果扣款成功了,但是沒(méi)有發(fā)放應(yīng)得的內(nèi)購(gòu)產(chǎn)品,這錢(qián)花哪去了?
這是一個(gè)嚴(yán)重的漏單問(wèn)題,已經(jīng)得到了及時(shí)解決,現(xiàn)寫(xiě)篇文章總結(jié)一下。
原理概念:
IAP:是指In-App Purchase,顧名思義,一種應(yīng)用內(nèi)的支付(內(nèi)購(gòu))。但I(xiàn)AP不是特指蘋(píng)果的內(nèi)購(gòu)支付方式,應(yīng)用也可以有其自己的內(nèi)購(gòu)支付方式。
這里來(lái)說(shuō)一下Apple的IAP。下圖是蘋(píng)果內(nèi)購(gòu)的支付流程圖。

支付流程解釋
1.客戶端向Appstore請(qǐng)求購(gòu)買(mǎi)產(chǎn)品,Appstore驗(yàn)證產(chǎn)品成功后,從客戶端的Apple賬戶中扣費(fèi)。
2.Appstore向客戶端返回一段receipt-data(票據(jù)),里面記錄了本次交易的證書(shū)和簽名信息。
3.客戶端向我們可以信任的服務(wù)器(后臺(tái))提供receipt-data
4.服務(wù)器對(duì)receipt-data進(jìn)行一次base64編碼
5.把編碼后的receipt-data發(fā)往itunes.appstore進(jìn)行驗(yàn)證
6.itunes.appstore返回驗(yàn)證結(jié)果給服務(wù)器
7.服務(wù)器對(duì)商品購(gòu)買(mǎi)狀態(tài)以及商品類(lèi)型,向客戶端發(fā)放相應(yīng)的道具與推送數(shù)據(jù)更新通知
問(wèn)題:
以上七個(gè)步驟實(shí)際上是一個(gè)很安全的支付流程了。那問(wèn)題會(huì)出在哪里呢?
出現(xiàn)的兩種驗(yàn)證方式:
IAP built-in Model(本地驗(yàn)證):此種方式跳過(guò)來(lái)3-7步,在第2步中拿到票據(jù)直接向itunes.appstore請(qǐng)求驗(yàn)證票據(jù),根據(jù)票據(jù)的結(jié)果來(lái)修改數(shù)據(jù)。有一些單機(jī)游戲因?yàn)椴簧婕昂笈_(tái)服務(wù)器會(huì)采取此種方式,但由此單來(lái)的不安全也很明顯,比如一些越獄的手機(jī)會(huì)很容易對(duì)此進(jìn)行一些數(shù)據(jù)操作。這里暫不做討論。
IAP Server Model(服務(wù)器驗(yàn)證):如果把數(shù)據(jù)放在服務(wù)器做校驗(yàn)(如實(shí)走完1-7的流程),就不用擔(dān)心客戶端出現(xiàn)偽造票據(jù)等問(wèn)題。但是這樣還會(huì)出現(xiàn)問(wèn)題。
想象一下,如果得到票據(jù)說(shuō)明蘋(píng)果已經(jīng)扣款成功,就在這時(shí)向服務(wù)器發(fā)送票據(jù)驗(yàn)證的時(shí)候出現(xiàn)來(lái)異常,這個(gè)時(shí)候可能網(wǎng)絡(luò)突然斷了,未把票據(jù)發(fā)送的服務(wù)器驗(yàn)證,導(dǎo)致明明已經(jīng)扣了款,卻沒(méi)有收到相應(yīng)的內(nèi)購(gòu)產(chǎn)品,出現(xiàn)了漏單問(wèn)題。
所以如何解決此問(wèn)題?解決流程如下
一:得到票據(jù),立即保存本地,并向服務(wù)器驗(yàn)證
二:驗(yàn)證成功,刪除本地保存數(shù)據(jù)。若未成功,再次驗(yàn)證重試。
三:APP重啟時(shí),如有本地票據(jù)則與服務(wù)器進(jìn)行認(rèn)證,若認(rèn)證成功則刪除票據(jù)。
四:若以上流程還未能解決漏單問(wèn)題,則可在APP增加類(lèi)似找回按鈕,依據(jù)本地保存票據(jù)進(jìn)行找回(流程三)。
注:服務(wù)器需建立表單記錄票據(jù)數(shù)據(jù),避免多次增加內(nèi)購(gòu)產(chǎn)品。