支付系統設計:應用內支付(五)

4 評論 41297 瀏覽 223 收藏 15 分鐘

應用內支付指使用手機操作系統自帶的支付功能來支持支付。目前國內主要的應用內支付有 Google Pay、Apple Pay、小米支付、華為支付等。 其中Apple Pay是典型的一個應用內支付,Android平臺的各種支付也一般是沿用Apple Pay的設計。

為什么要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支付的開發流程,首先需要一些準備工作,包括:

  1. 在developer.apple.com上配置一個App ID,使用該ID生成和安裝相應的Provisioning Profile文件。
  2. 登錄到iTunes Connect,使用App ID創建一個新的應用,在該應用中,創建應用內付費項目,設置好價格和Product ID以及購買介紹和截圖。
  3. 添加一個用于在sandbox付費的測試用戶,填寫相關的稅務,銀行,聯系人信息。

完成這些準備工作后,既可以進入正式的開發,開發代碼我們這里就不說了,流程如下:

  1. 用戶選擇要購買的內容并點擊購買按鈕;
  2. 用戶通過App Store賬戶驗證
  3. 蘋果服務器驗證用戶請求
  4. 蘋果服務器從用戶帳號扣款
  5. 蘋果向用戶返回購買成功信息
  6. 軟件接收并顯示用戶購買信息

老司機都能看出來,這里有好多好多的坑。

用戶訪問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 有四個狀態:

  1. SKPaymentTransactionStatePurchasing
  2. SKPaymentTransactionStatePurchased
  3. SKPaymentTransactionStateFailed
  4. SKPaymentTransactionStateRestored

SKPaymentTransactionStatePurchased 表示購買成功了。 只要修改這個變量值,如果客戶端應用直接根據交易狀態來處理業務流程,那就會收到這個假的交易成功信息,接下來用戶就能不花錢得到所買的物品。這個過程,甚至都不需要接入網絡。

另一個工具IAPfree功能更強大,安裝使用也復雜很多。它是通過修改DNS,讓客戶端訪問黑客提供的服務器來取代訪問蘋果服務器,實現所謂的MITM中間人攻擊。當用戶在客戶端觸發購買流程時,會被引導到偽裝的蘋果服務器上,不扣款而直接返回扣款成功收據。用戶不需要支付任何資金,客戶端能夠拿到完整的收據。如果是在客戶端處理收據驗證也沒有任何問題。為了避免用戶所使用的設備被封,這些軟件甚至可以提供偽造UDID的功能。 為此,蘋果特別說明,一定要在服務器端驗證用戶購買信息,驗證內容包括收據簽名,證書,產家信息等,確保收據無誤后,才能授予權益。如果發現有詐,則將用戶拉黑。

兩套賬戶體系

蘋果支付的賬戶體系,當然是以apple id為基礎的,它允許用戶在多臺設備上共用一個賬戶。一臺設備上,一般只有一個激活賬戶。但對應用系統來說,大部分是允許多個賬號登陸的。這對續費來說就是個大問題。 用戶以賬戶a登錄后,發起續費,獲得權益。然后以賬號B登錄了,顯然,A的權益不會衍生給B。過幾天A開始續費了,續費之后,切換到B賬號登錄,客戶端在B賬號登錄時得到續費的收據并發送給應用服務器。那這算是誰的續費請求?當然是A的。在這個apple id發起的續費請求,所有的收據都會有一個相同的原始交易號original transaction Id。在用戶發起訂閱時,需要記錄這個id和賬號的關系,每次續費,需要在解析收據后,根據原始交易號從這里獲取真正的充值賬戶,不能從客戶端提交的用戶id作為憑據。

還是這個坑,如果在賬戶b登錄后也發起訂閱請求,會怎么樣?這個調用將會失敗,所以需要阻止用戶發起這樣的請求?;蛘咴O置多個產品副本來讓用戶購買。

分成,定價和國際化

在iTunes中的給的產品定價必須是稅前的,蘋果和商家的分成,也是按稅前算。商家給出在一個主要銷售國家和地區(比如國內的基本就是中國了)的價格,即基準價格。在其他地區的銷售價格,蘋果會自動根據當前的匯率來換算成當地的貨幣。當然,也可以自己修改設定在這些國家或者地區的當地價格。目前是支持到155個國家。還要特別注意版權問題。

基準價格調整,如果是往高了調整, 則在用戶下一次續費時,需要用戶確認。如果往低了調,那就不需要用戶確認,直接扣款了。

蘋果對商家的產品價格體系有分組(Group)的概念,同國內說的價格體系,比如白金會員、黃金會員、貴賓等,在同一個Group里面,用戶只能選擇一個檔,比如用戶要么是白金要么是黃金會員,不會同時是。

在同一個分組中,如果用戶訂閱時間超過一年(365天),則商家可以得到來自這個用戶收益的更多的分成,目前是85%。這個訂閱時間不包括免費試用期。 同時可以有60天的寬限。也就是說,這一年中,如果用戶曾經停止續費,然后又開始繼續續費,只要中間不續費的時間不超過60天就行。

更多的坑

目前用的是IOS 10.0 版本, 這個版本和IAP有關的坑,先記錄下:

  1. 沙盒環境,沒法做取消訂閱操作。 只能在線上模擬。 所以產品設計和開發時,盡量不要依賴取消訂閱操作,也應該不依賴于這個操作。
  2. 沙盒環境下,有些receipt可能會收不到transaction id,線上的暫未發現這個問題。
  3. 蘋果提供單個收據和列表收據兩種格式。推薦使用列表數據,但問題是,這個列表收據的長度,蘋果也不知道最多會有多少。

Android IAP

好吧,用這個話題作總結,不是太好。IOS上用蘋果支付是被逼的,android上用IAP是圖什么?支付寶和微信支付有這么多用戶基數,接入也很方便,費用比IAP便宜多了。如果你有接入android IAP經驗,期待分享。

相關閱讀

支付系統設計:支付系統的賬戶模型(一)

支付系統設計:對賬處理(二)

支付系統設計:銀行卡支付(三)

支付系統設計:綁卡、簽約和身份驗證(四)

 

作者:鳳凰牌老熊,程序員 & 架構師,來自中科大的本科,研究生在軟件所學習。先后在中科輔龍、三星(中國)研究院和國內一些大型的互聯網公司呆過。在中科輔龍公司負責電子政務內容管理系統建設,負責研發龍馭系列產品的研發,這款產品最終實施到2000多個電子政務網站上,期間也參與了一些支付反洗錢以及支付系統的建設。之后在三星中國研究院,負責自然語言處理(NLP)以及智能家居相關項目。智能家居項目在2014CES消費電子展上作為三星重點項目推介。2014年開始加入愛奇藝公司,負責數據倉庫和支付系統的建設。

本文由@鳳凰牌老熊(微信公眾號:shamphone) 原創發布于人人都是產品經理 。未經許可,禁止轉載。

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 有徒弟不,微信:wwwwcwdsj

    回復
  2. 感謝~

    來自廣東 回復
  3. 有幫助,謝謝

    來自浙江 回復
  4. 連續這么多篇,作者辛苦了 寫的很專業

    來自廣東 回復