1. 程式人生 > IOS開發 >Apple IAP 二三事

Apple IAP 二三事

一、概述

1、簡介

  • IAP (In-App Purchase)即應用內購買,是App內購買「虛擬數字產品」的支付方式;AndroidiOS都有IAP支付;判斷APP是否需要IAP的標準:使用者付費購買的商品/服務是否為「虛擬數字產品」;

  • 更通俗的解釋:看商品/服務的實際消費場景是在 App 內,還是 App外;如果在 App內即可完成消費的,蘋果要求使用 IAP,如電子書、充值類虛擬貨幣、遊戲/直播中道具等;在App外完成消費,可以使用第三方支付;典型如線下電影票、實物電商、打車、外賣等。

  • Apple對IAP態度嚴苛,很大一部分原因是:Apple可以從IAP支付流水中,抽成30%;很多App不願意使用IAP支付,通過欺騙稽核方式

    繞開IAP支付,其實這會給App帶來非常大的風險,嚴重可能導致App被下架。

2、IAP商品種類

  • 消耗型專案:只可使用一次的產品,使用之後即失效,必須再次購買,如:遊戲幣、一次性虛擬道具等

  • 非消耗型專案:只需購買一次,不會過期或隨著使用而減少的產品。如:電子書

  • 自動續期訂閱:允許使用者在固定時間段內購買動態內容的產品。除非使用者選擇取消,否則此類訂閱會自動續期,如:Apple Music這類按月訂閱的商品

  • 非續期訂閱:允許使用者購買有時限性服務的產品,此 App 內購買專案的內容可以是靜態的。此類訂閱不會自動續期

    IAP商品交易成功後,Apple收取30%的手續費,如果商品是30元,你只能得到21元;不過自動續訂的商品第二年開始只成15%

3、Pre Develop

二、支付流程對比

1、微信/支付寶の支付流程

  • 目前,微信/支付寶絕對是國內最主流的第三方支付,和IAP相比,他們都提供了非常好的技術支援;(雖無緣於支付寶,但必須給支付寶點贊!)

  • App內,微信/支付寶的支付流程簡述如下:

    • App內發起支付請求;(調起微信/支付寶支付有兩種,SDK方式 和 schema方式,建議前者)
    • App跳到支付寶/微信客戶端,引導使用者完成支付;
    • 使用者完成支付的同時,微信/支付寶伺服器回撥App的伺服器,告知支付結果;App中也會收到微信/支付寶SDK中的支付回撥結果(業務上,一般不以SDK回撥結果做最終結果);
    • App的伺服器收到回撥後,完成訂單驗證和發貨操作;
    • 從微信/支付寶返回第三方App,App去自己的伺服器查詢商品支付結果;
  • 在整個支付流程中,如果發生使用者支付成功,但是的Server回撥出錯了(可能是網路,也可能是App伺服器異常),到賬使用者沒有收到貨物,這會對支付體驗造成非常大的打擊;

  • 但是,微信/支付寶的伺服器非常靠譜:檢測回撥失敗後會重試,能最大程度(錯誤重試機制)保證將結果同步給第三方App伺服器;

2、IAPの支付流程

  • App內,IAP的支付流程,簡述如下:

    • App內,通過IAP API(StoreKit),發起支付請求;
    • 使用者在App內完成支付;(獲取商品資訊->建立交易加入到交易佇列->使用者支付->支付完成)
    • 使用者完成支付的同時,IAP 伺服器回撥APP,通知購買成功,並把票據(receipt)寫入到 APP 沙盒中
    • App需要將票據(receipt) 上傳給App伺服器;
    • App伺服器再將票據(receipt) 發給Apple伺服器去驗證;只有驗證成功,App伺服器才能去發貨。
  • 在整個支付流程中,使用者在端上扣款成功,只是開始;後續的支付驗證至少需要保證App上傳票據成功App伺服器將票據交給Apple伺服器成功App伺服器獲取訂單驗證結果成功;否則,掉單是必然出現的事情;簡單來說:使用者扣款成功後,IAP支付的嚴峻挑戰開始了;

  • Apple將每次IAP支付行為被抽象成一個事務(SKPaymentTransaction),只有事務被正常結束(finishTransaction:),該次支付行為才算完成。即使支付中途被中斷,但是這次事務並沒有丟失。eg: 支付未完成,App Crash了,下次App重啟(需addTransactionObserver:),之前被中斷的事務會接著進行。

    StoreKit框架主要提供三部分功能:In-App Purchase(IAP,應用程式內購買)、Recommendations and reviews(建議和評論) 和 Apple Music(蘋果音樂,國內幾乎不用);IAP的API在StoreKit框架。

3、總結

  • 對比第三方支付和IAP支付流程發現:

    • 微信/支付寶的扣款後,交易驗證工作是在伺服器之間通訊完成的;只要使用者產生了交易,他們的伺服器會回撥App伺服器,交易的可靠性由支付寶/微信服務保證的;
    • 而IAP扣款後,交易驗證是App驅動App伺服器完成的;但是移動裝置所處的網路環境遠比服務端複雜;扣款成功後,後續的下發票據 和 App上傳票據都面臨嚴峻的考驗(網路異常、App伺服器異常、Apple伺服器異常等)。
  • 簡單來說:Apple預期將支付流程中最重要的驗證環節交給了App開發者;和國內的微信/支付寶套路完全不同;

  • 此外,雖然Apple為保障交易驗證完成,提供了事務機制,但是事務機制最大的問題是:如果某一個事務在當次App生命週期內未能正常結束,只能在下次App重啟後,中斷的事務才能恢復;這其實是對使用者傷害比較大:扣了款,可能很長時間收不到貨。

三、優化IAP驗證

1、思路

  • 完善重試機制;儘可能多的重試,保證使用者扣款後能比較及時收到貨物;

  • 建立業務訂單和IAP訂單對映機制;Apple只負責告訴一個交易事務成功or失敗,不關心是否對映到業務訂單好;

2、完善重試機制

  • 不依賴蘋果事務機制重試;當Apple通知使用者交易成功(SKPaymentTransactionStatePurchased),立刻持久化交易資料到keychain,儲存成功後,finish掉交易。

    補充1:交易資料持久化到keychain好處有二:儲存到keychain的資料被加密,安全可靠;即使App被解除安裝,keychain中資料也不會被刪除;

    補充2:扣款成功後,可能蘋果沒有告知交易成功,可能下次甚至下下下次啟動,才告知交易成功;因此,App啟動後,監聽交易事務佇列,當收到交易事務完成通知,立刻持久化交易資料;

  • 建設交易驗證佇列;每筆交易資料持久化成功後,嘗試訂單驗證,驗證包含兩步:上傳票據 和 查詢訂單狀態;只有兩步都完成,才能算一個訂單驗證結束;

  • 豐富交易驗證的時機

    • App冷啟動後x秒,keyChain 中還有沒有處理完的交易,一個個去發起校驗;
    • 使用者發生新購買,扣款成功,交易資料持久化成功後,發起驗證操作;
    • App從後臺切換到前臺x秒,無網切到有網,前臺停留x分鐘等情況下,如果 keyChain 中有未驗證完成的交易,發起驗證請求;
    • ...

3、訂單對映

  • 訂單對映指:業務訂單和IAP訂單的對映,本質是將業務訂單號 orderID 繫結到蘋果的交易訂單上;
  • 發起IAP支付後,我們給Apple的是一個SKPayment物件,最後監聽到的是SKPaymentTransaction物件(有SKPayment屬性物件);我們可以通過利用SKPaymentapplicationUsername欄位實現訂單對映;
  • 建立交易物件時,將業務訂單號 orderID賦值給SKPaymentapplicationUsername;等支付成功後,通過SKPaymentTransactiond物件的payment獲取到業務訂單號 orderID,從而實現了業務訂單和IAP訂單對映繫結
  • 重要說明:利用applicationUsername透傳業務訂單號 orderID 有失敗的概率,一些情況下會導致applicationUsername透傳的值丟失(訂單號丟失問題);如果不處理的話,會發生掉單;
  • 總的來說,利用applicationUsername實現訂單繫結雖然有不足,但是從ROI上評估還是可行的;訂單號丟失問題可以交給伺服器處理:服務端只要驗證交易是正確的,且該使用者的確有交易記錄,自動生成訂單重新發貨 or 最近訂單(時間、金額)匹配;即便這麼做,依然有case被遺漏,但能保證大盤基本OK。

4、票據的問題

  • iOS 7後(App幾乎都是iOS 9起步),從[[NSBundle mainBundle] appStoreReceiptURL]]中獲得的receipt(票據)資料;App上傳票據資訊的話,將其中的資料一起上傳
  • iOS 7後,[[NSBundle mainBundle] appStoreReceiptURL]]中的票據資訊是一個receipt listin_app欄位),本身帶有“自動修復的特性”,如果使用者某次支付沒有正確完成,後續也沒有被成功恢復;當他產生下一次成功支付後,[[NSBundle mainBundle] appStoreReceiptURL]]中會包含這幾次支付的receipt
  • 獲取不到票據情況:如監聽到交易成功了,但是從[[NSBundle mainBundle] appStoreReceiptURL]]中獲得的資料是空,遇到此類問題,可以打標記後續重試;
  • 票據無效,驗證失敗的情況也可能遇到,這時候,讓使用者提供了支付資訊,走補償 or 退款吧;

5、to be continued

  • 保障扣過款的IAP訂單儘快得到驗證,是IAP問題中首要解決的問題;本節中簡單介紹了相關一些思路;我相信,做好這些能hold住大多數問題;
  • 雖然IAP總體體驗被微信/支付寶吊打,但是由於iOS使用者被教育了這麼多年,Apple在新iOS版本上也有些不為認知的優化;總體上來說,IAP支付還可以,沒有早年那麼糟糕;
  • 做好以上這些事,不是終點;優化產品體驗,做好使用者教育工作,也能很好幫助實現總目標。

四、IAP周邊建設

1、完善監控埋點

  • 支付環節中,對關鍵路徑埋點,包括但不限於:持久化交易資料操作、上傳票據操作、查詢操作,結束驗單操作等;
  • 監控異常的情況,包括但不限於:持久化交易資料失敗、上傳失敗,applicationUsername獲取訂單號為空、查詢失敗等;
  • 開發階段,儘可能多展示除錯日誌資訊;

2、響應使用者反饋

  • 再好的方案,也無法hold所有的IAP問題,建立使用者反饋響應機制,及時響應使用者反饋;關注使用者關注的;
  • 例1:部分使用者反饋無法支付,排查發現,是網路原因導致獲取SKProduct失敗;因此,嘗試提前拉取SKProduct;
  • 例2:部分使用者反饋,iOS 13上必選Crash,排查得知:iOS13把SKProductRequst的回撥放到了子執行緒;如果在這個回撥中有UI操作,必然Crash。
  • 將典型的,數量比較多的使用者反饋集中集中起來,針對問題,嘗試優化方案;同時,注意安撫使用者的情緒;

3、其他

  • 要加強沉澱,包括但不限於:IAP優化方案、問題排查和解決記錄,使用者反饋和處理記錄等;

  • 雖然,Apple提供了Testflight包,使用者可以IAP沙盒支付;針對沙盒支付,Server要做好驗證,這些非真實金錢交易,要特殊處理。

參考文章

iOS 內購(In-App Purchase)總結

談談蘋果應用內支付(IAP)的坑

iOS IAP應用內購詳細步驟和問題總結指南

蘋果IAP開發中的那些坑和掉單問題

貝聊 IAP 實戰之見坑填坑

貝聊 IAP 實戰之訂單繫結