最近在做內(nèi)購功能冀膝, 內(nèi)購的整個(gè)流程比較長,牽扯面很廣霎挟,要簽合同填銀行賬號(hào)稅務(wù)等窝剖,要在后臺(tái)填商品列表。前面的操作在網(wǎng)上都有很詳細(xì)的步驟酥夭,按照網(wǎng)上的步驟來操作赐纱,這部分很快就能搞定,今天主要要說的是在這整個(gè)流程中踩到的坑熬北。
1.協(xié)議未完全生效疙描,而我未可知,導(dǎo)致調(diào)試?yán)速M(fèi)大量的時(shí)間蒜埋。我做這個(gè)功能也是接盤的淫痰,別人把前面的配置都配置好了,然后代碼層面由我實(shí)現(xiàn)整份,結(jié)果在測試的過程中待错,就是調(diào)用不起來內(nèi)購彈框籽孙,可能有很多原因?qū)е铝诉@個(gè)問題,但是我從來沒有往協(xié)議配置方面想過火俄,最后是在無意中發(fā)現(xiàn)犯建,原來第一部分就沒有過,這部分改好了之后瓜客,遇到了下面的問題适瓦。
2.內(nèi)購很經(jīng)典的問題,掉單問題谱仪。為了解決這個(gè)問題玻熙,我上網(wǎng)搜索了很多資料,想要找到最好的方案去解決疯攒,結(jié)果是一把血淚史嗦随。關(guān)于這個(gè)問題,主要分了三個(gè)部分去解決:
1).將訂單信息保存到本地敬尺,每次打開app時(shí)自動(dòng)檢測本地是否有未完成的訂單枚尼。我這邊為了保證盡量不掉單,所以在服務(wù)端未給我返回完成時(shí)砂吞,這筆訂單是不會(huì)被finish的署恍,所以每次打開app都會(huì)走一個(gè)支付未完成的代理,這個(gè)大家應(yīng)該都知道蜻直。在每次打開app走這個(gè)代理時(shí)盯质,會(huì)根據(jù)系統(tǒng)給到的訂單信息匹配本地保存的未完成的訂單信息,去服務(wù)端進(jìn)行再次verify袭蝗, 通過這種模式去保證不掉單唤殴。
2).上面那種方式如果遇到支付出問題時(shí)還卸載了app,那上面那種方式就沒辦法保證了到腥,網(wǎng)上給了好幾種方案朵逝,首先可以寫到鑰匙串中,好多人都是這種實(shí)現(xiàn)的乡范,卸載了之后也不會(huì)被刪除配名,但是個(gè)人不太喜歡這種方式,從內(nèi)心一直拒絕晋辆。第二種是要服務(wù)端配合渠脉,在create order的時(shí)候透傳appstore的商品id, 然后在合適的時(shí)機(jī)瓶佳,根據(jù)appstore的商品id去請求有無該商品的未完成的訂單芋膘,如果有,就獲取該訂單信息進(jìn)行verify,這種方式總結(jié)來說为朋,就是服務(wù)端能提供一個(gè)接口臂拓,讓你通過蘋果的商品id獲取到該商品id下未完成的訂單,獲取到訂單信息就能進(jìn)行校驗(yàn)了习寸。同時(shí)這里還有一個(gè)問題胶惰,如果有多個(gè)訂單怎么弄,蘋果有個(gè)機(jī)制霞溪,如果一筆相同商品id的訂單未完成孵滞,下次再次支付不會(huì)生成新的訂單,會(huì)把之前的訂單恢復(fù)鸯匹,我目前測試下來是這樣坊饶,不知道是不是有異常沒有考慮到。
? ?針對第2個(gè)case忽你,當(dāng)時(shí)還用了第三種方法幼东,鑒于上面提到的方案都太復(fù)雜臂容,我一直希望有一種更簡便的方案能解決這個(gè)問題科雳。在經(jīng)過查詢之后,發(fā)現(xiàn)一個(gè)讓我踩坑了許久的方案脓杉。SKMutablePayment中有兩個(gè)字段說是可以透傳糟秘,applicationUsername和requestData。applicationUsername說是可能會(huì)丟失球散,但是requestData不會(huì)丟失尿赚,我當(dāng)時(shí)看到這個(gè)很興奮,這個(gè)發(fā)現(xiàn)不就意味著這個(gè)問題可能很優(yōu)雅的解決掉了蕉堰,我只要把orderId通過requestData透傳過去凌净,然后上面提到的方案都可以去掉了。然后我很開心的開始寫了屋讶,由于我這邊項(xiàng)目用了SwiftyStoreKit進(jìn)行iap的開發(fā)冰寻,這個(gè)庫中并沒有把requestData暴露出來,為了實(shí)現(xiàn)這個(gè)功能皿渗,我把源碼改了斩芭,暴露了requestData,然后測試發(fā)現(xiàn)真的把orderId透傳出來了乐疆,我很開心划乖,問題總算圓滿解決了。但是挤土,我測試的一直用的ios11.4的手機(jī)很正常琴庵,用了一個(gè)ios12.4的手機(jī)測試就一直提示無法連接上itunes connect,因?yàn)檫@個(gè)錯(cuò)誤之前也經(jīng)常報(bào),我覺得肯定是其他原因引起的迷殿,當(dāng)時(shí)也沒有在意尉桩,然后就提審了,審核一直不通過贪庙,截的圖是一直在轉(zhuǎn)圈蜘犁,轉(zhuǎn)了很長時(shí)間提示無法連接。這個(gè)時(shí)候我感覺有問題了止邮,然后加了很多賬號(hào)到testflight中下載進(jìn)行測試这橙,部分手機(jī)可以,部分手機(jī)就不行导披,然后我再去仔細(xì)看了實(shí)現(xiàn)代碼屈扎,發(fā)現(xiàn)SwiftyStoreKit官方給的demo中把大部分的errorcode給吃掉了,統(tǒng)一輸出無法連接撩匕, 這部分代碼當(dāng)時(shí)也沒認(rèn)真看就直接移植過來了鹰晨。然后通過打印出來的code發(fā)現(xiàn),報(bào)的是unauthorizedRequestData止毕,The app is attempting to use SKPayment's requestData property, but does not have the appropriate entitlement模蜡,說是非法使用了requestData字段,然后這個(gè)錯(cuò)誤是從ios12.2才加入的扁凛,所以高版本的支付一直報(bào)錯(cuò)忍疾。估計(jì)是蘋果發(fā)現(xiàn)好多人使用這個(gè)字段來透傳,但是蘋果設(shè)置這個(gè)字段本意不是如此谨朝,才禁了這個(gè)字段卤妒。
? ? 最后我只能將requestData方案從代碼中移除,還好我當(dāng)時(shí)這3種方案都實(shí)現(xiàn)了字币,所以改動(dòng)也不是太大则披,移除了requestData透傳方案,使用本地保存和服務(wù)端配合的方式也能達(dá)到盡量不掉單洗出,但是我覺得最好鑰匙串中也存一份士复,做一層校驗(yàn),這樣更保險(xiǎn)了共苛,可能還有些未考慮到的case判没,待補(bǔ)充。主要是那個(gè)坑踩的我有點(diǎn)懵隅茎,謹(jǐn)以此記澄峰。