為什麼要IAP
相對來說,應用內支付的用戶體驗,和微信支付、支付寶相比,還是有一定差距的,但是為什麼要開發應用內支付呢? 這個和蘋果的AppStore的審核政策有關。在官方的 (App Store Review Guidelines) 中, 有如下幾條意見:
1.2 Apps utilizing a system other than the In-App Purchase API (IAP) to purchase content, functionality, or services in an App will be rejected.
在 App 內使用非IAP的系統來購買內容、功能或服務將被拒絕。
11.3 Apps using IAP to purchase physical goods or goods and services used outside of the App will be rejected.
IAP 購買實物或者應用外的商品或服務將會被拒絕;
11.4 Apps that use IAP to purchase credits or other currencies must consume those credits within the App.
通過 IAP 購買的積分或者其他貨幣必須只在App內使用。
這問題就來了,如果要購買的服務,即在IOS內使用,也在Android等IOS系統外使用,那應該是使用規則11.2或者規則11.3來執行? 比如說視頻網站,視頻既可以在IOS上看,也可以在Android上看,那是否是需要通過IAP來購買?蘋果公司在這一點上採取模糊的策略。愛奇藝、騰訊視頻,在IOS上購買會員,只能用IAP支付。這就和蘋果公司的審核有關。
IAP支付流程
一般IAP支付的開發流程,首先需要一些準備工作,包括:
在developer.apple.com上配置一個App ID,使用該ID生成和安裝相應的Provisioning Profile文件。
登錄到iTunes Connect,使用App ID創建一個新的應用,在該應用中,創建應用內付費項目,設置好價格和Product ID以及購買介紹和截圖。
添加一個用於在sandbox付費的測試用戶,填寫相關的稅務,銀行,聯繫人信息。
完成這些準備工作後,既可以進入正式的開發,開發代碼我們這裡就不說了,流程如下:
用戶選擇要購買的內容並點擊購買按鈕;
用戶通過App Store帳戶驗證
蘋果伺服器驗證用戶請求
蘋果伺服器從用戶帳號扣款
蘋果向用戶返回購買成功信息
軟體接收並顯示用戶購買信息
老司機都能看出來,這裡有好多好多的坑。
用戶訪問AppStore時使用的是Apple的帳號,不是應用系統的帳號。也就是說,我們並不知道到底是誰在購買這個內容。比如在應用中有兩個帳號A和B,用A帳號登錄後,上IAP買了東西,然後用B帳號來登錄,也上IAP買東西, 這兩次購買,用的是同一個Apple帳號。蘋果也不會告訴你,到底是哪個帳號付了錢。帳號坑在單次購買中還沒什麼問題,但碰到訂閱的情況,得好好處理下。從上述流程可以看出,蘋果伺服器都是和客戶端打交道的,這裡面似乎沒有應用伺服器什麼事情。只有在客戶端接收到蘋果返回信息後,才可以把這個信息轉發給應用伺服器。如果用戶一直不打開手機上的應用,那應用伺服器就一直收不到通知了。好在後來蘋果提供了一個驗證功能,應用伺服器可以把接收到的返回信息(加密後的字符串)發送給蘋果伺服器來驗證和解密。
IAP訂閱
IAP Subscription又是一個大坑。官方的文檔在這裡。內容不多,沒有說明的東西卻很多。
續費周期的計算
IAP主要提供給周期性訂閱的音樂、電子書等內容使用。 一般就按月來計算周期。蘋果是以自然月來算權益周期。比如在1月3號買了權益,到2月3號,這個權益就過期啦,需要在此之前完成續費。 那問題來了,1月31號買的權益,到幾號過期?以自然月算,這個權益會在3月1日前到期,如果2月份,3月份都續費了,到4月份,也是享受到4月30日了。
自動續費
應用開發應該不需要關心續費的細節。蘋果會做自動處理。在權益到期前10天,蘋果檢查用戶帳戶是否可以扣款,商品價格是否有變動。在權益到期前24小時,蘋果開始扣款,如果失敗,會多次重試,直到成功。問題來了,這個重試,會延續到用戶權益過期後一小段時間,蘋果沒有說這段時間該算是有權益還是沒有,但開發人員需要注意應該如何處理。
免費試用
免費試用不是強制需求,但這有利於用戶判斷是否值得購買這個物品。免費試用期是在itunes connect中設置。 當用戶第一次購買這個東西的時候, 客戶端接收到的Receipt中包含免費試用信息。在免費期快到的時候,蘋果發起第一次扣款。整個過程和自動續費類似,唯一區別是第一個月是免費的。
Receipt 驗證
客戶端接收到 Receipt 之後,需要提交到伺服器端進行處理,開通權益。 這就來了個問題:Receipt應該在客戶端還是伺服器端解析?當然需要在伺服器端處理,這樣可以防止越獄後的一些插件,如IAP Cracker、IAP Free等偽造交易憑證,欺騙蘋果伺服器,開通權益。 此外,還需注意,客戶端和伺服器端之間需通過HTTPS以及參數籤名等方式來確保通訊安全。 伺服器端接收到Receipt之後,首先驗證請求的有效性, 然後將Receipt發送到蘋果伺服器上進行驗證和解析。 接收到蘋果處理結果後, 將Receipt中的user_id, product_id、purchase_date、transaction_id等做驗證和處理。
IAP破解和防禦
既然Iap的驗證主要是在蘋果伺服器端和手機客戶端進行,並且是使用域名。這簡直是為攻擊打開了一扇大門,而不僅僅是漏洞。早期的IAP內購解鎖工具IAP cracker對IAP的破解比較簡單粗暴。寫過IAP程序的人都知道, 程序中基本都是用transactionState來判斷交易是否成功。
transactionState 有四個狀態:
SKPaymentTransactionStatePurchasing
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateFailed
SKPaymentTransactionStateRestored
SKPaymentTransactionStatePurchased 表示購買成功了。只要修改這個變量值,如果客戶端應用直接根據交易狀態來處理業務流程,那就會收到這個假的交易成功信息,接下來用戶就能不花錢得到所買的物品。這個過程,甚至都不需要接入網絡。
另一個工具IAPfree功能更強大,安裝使用也複雜很多。它是通過修改DNS,讓客戶端訪問黑客提供的伺服器來取代訪問蘋果伺服器,實現所謂的MITM中間人攻擊。當用戶在客戶端觸發購買流程時,會被引導到偽裝的蘋果伺服器上,不扣款而直接返回扣款成功收據。用戶不需要支付任何資金,客戶端能夠拿到完整的收據。如果是在客戶端處理收據驗證也沒有任何問題。為了避免用戶所使用的設備被封,這些軟體甚至可以提供偽造UDID的功能。為此,蘋果特別說明,一定要在伺服器端驗證用戶購買信息,驗證內容包括收據籤名,證書,產家信息等,確保收據無誤後,才能授予權益。如果發現有詐,則將用戶拉黑。
兩套帳戶體系
蘋果支付的帳戶體系,當然是以apple id為基礎的,它允許用戶在多臺設備上共用一個帳戶。一臺設備上,一般只有一個激活帳戶。但對應用系統來說,大部分是允許多個帳號登陸的。這對續費來說就是個大問題。用戶以帳戶a登錄後,發起續費,獲得權益。然後以帳號B登錄了,顯然,A的權益不會衍生給B。過幾天A開始續費了,續費之後,切換到B帳號登錄,客戶端在B帳號登錄時得到續費的收據並發送給應用伺服器。那這算是誰的續費請求?當然是A的。在這個apple id發起的續費請求,所有的收據都會有一個相同的原始交易號original transaction Id。在用戶發起訂閱時,需要記錄這個id和帳號的關係,每次續費,需要在解析收據後,根據原始交易號從這裡獲取真正的充值帳戶,不能從客戶端提交的用戶id作為憑據。
還是這個坑,如果在帳戶b登錄後也發起訂閱請求,會怎麼樣?這個調用將會失敗,所以需要阻止用戶發起這樣的請求,或者設置多個產品副本來讓用戶購買。
分成,定價和國際化
在iTunes中的給的產品定價必須是稅前的,蘋果和商家的分成,也是按稅前算。商家給出在一個主要銷售國家和地區(比如國內的基本就是中國了)的價格,即基準價格。在其他地區的銷售價格,蘋果會自動根據當前的匯率來換算成當地的貨幣。當然,也可以自己修改設定在這些國家或者地區的當地價格。目前是支持到155個國家。還要特別注意版權問題。
基準價格調整,如果是往高了調整, 則在用戶下一次續費時,需要用戶確認。如果往低了調,那就不需要用戶確認,直接扣款了。
蘋果對商家的產品價格體系有分組(Group)的概念,同國內說的價格體系,比如白金會員、黃金會員、貴賓等,在同一個Group裡面,用戶只能選擇一個檔,比如用戶要麼是白金要麼是黃金會員,不會同時是。
在同一個分組中,如果用戶訂閱時間超過一年(365天),則商家可以得到來自這個用戶收益的更多的分成,目前是85%。這個訂閱時間不包括免費試用期。 同時可以有60天的寬限。也就是說,這一年中,如果用戶曾經停止續費,然後又開始繼續續費,只要中間不續費的時間不超過60天就行。
更多的坑
目前用的是IOS 10.0 版本, 這個版本和IAP有關的坑,先記錄下:
沙盒環境,沒法做取消訂閱操作。 只能在線上模擬。 所以產品設計和開發時,儘量不要依賴取消訂閱操作,也應該不依賴於這個操作。
沙盒環境下,有些receipt可能會收不到transaction id,線上的暫未發現這個問題。
蘋果提供單個收據和列表收據兩種格式。推薦使用列表數據,但問題是,這個列表收據的長度,蘋果也不知道最多會有多少。
Android IAP
好吧,用這個話題作總結,不是太好。IOS上用蘋果支付是被逼的,android上用IAP是圖什麼?支付寶和微信支付有這麼多用戶基數,接入也很方便,費用比IAP便宜多了。如果你有接入android IAP經驗,期待分享。
相關閱讀
支付系統設計:支付系統的帳戶模型(一)
支付系統設計:對帳處理(二)
支付系統設計:銀行卡支付(三)
支付系統設計:綁卡、籤約和身份驗證(四)
雷鋒網(公眾號:雷鋒網)註:本文由人人都是產品經理社區作者@鳳凰牌老熊(微信公眾號:shamphone)原創發布。鳳凰牌老熊,程式設計師 & 架構師。先後在中科輔龍、三星(中國)研究院和國內一些大型的網際網路公司工作過。2014年加入愛奇藝,負責數據倉庫和支付系統的建設。文章未經許可,不得轉載。
雷鋒網原創文章,未經授權禁止轉載。詳情見轉載須知。