參考我之前的筆記 蘋果內購筆記,在客戶端向蘋果購買成功之后,我們需要進行二次驗證。
二次驗證
IOS在沙箱環境下購買成功之后,向蘋果進行二次驗證,確認用戶是否購買成功。
當應用向Apple服務器請求購買,成功之后,Apple會返回以下四個數據給應用
四個驗證數據
productIdentifier:cosmosbox.strikehero.gems60
state: Purchased
receipt:
ewoJInNpZ25hdHVyZSIgPSAiQXF1M3JiR1grbmJMeGVvZS9VZGlMa3dQWVlBdkQr
VTE1L1NRL2Y0cGZlaFlBOWFaVGhSbTNMVXpHc25TUGd3aVBoMmsxSTVFaVpweGp6
aEZsS0JDVXBPeHEyWFk5N1lHUGUzMFo0cThMRllDZWJPeHFzWlJaUU01N2xtZFo0
bDN6eHNnaWpGemFiYkRXLzM4cm1EeXFTT0FSYzRES3dXTGFpc2EzYUY5d2JwbUFB
QURWekNDQTFNd2dnSTdvQU1DQVFJQ0NCdXA0K1BBaG0vTE1BMEdDU3FHU0liM0RR
RUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pT
//receipt省略幾十行
transactionIdentifier: 1000000160385706
1. 產品標識符: product Identifier
在itunes store應用內定義的產品ID,例如com.公司名.產品名.道具名(com.xxxx.video.vip)
2. 交易狀態: state
| Purchased | 購買成功 |
| Restored | 恢復購買 |
| Failed | 失敗 |
| Deferred | 等待確認,兒童模式需要詢問家長同意 |
3. Receipt
很長的一段字符串,大概49行,作為二次驗證的重要依據
4. 交易標識符: transaction Identifier
我們需要把Receipt發送給蘋果的蘋果的服務器驗證,用戶的購買信息是否真實
驗證服務器地址
在測試服務器中,發送receipt蘋果的測試服務器( https://sandbox.itunes.apple.com/verifyReceipt )驗證
在正式服務器中(已上線Appstore),發送receipt到蘋果的正式服務器( https://buy.itunes.apple.com/verifyReceipt )驗證
當我們把應用提交給蘋果審核時,蘋果也是在sandbox環境購買,其產生的購買憑證,也只能連接蘋果的測試驗證服務器,所以我們可以先發到蘋果的正式服務器驗證,如果蘋果返回21007,則再一次連接測試服務器進行驗證。
驗證購買信息
以下是把客戶端的購買信息發送到蘋果測試服務器進行確認,蘋果返回的數據:
ISN: url: https://sandbox.itunes.apple.com/verifyReceipt ORIGINAL JSON: { "receipt": { "original_purchase_date_pst":"2015-06-22 20:56:34 America/Los_Angeles", //購買時間,太平洋標准時間 "purchase_date_ms":"1435031794826", //購買時間毫秒 "unique_identifier":"5bcc5503dbcc886d10d09bef079dc9ab08ac11bb",//唯一標識符 "original_transaction_id":"1000000160390314", //原始交易ID "bvrs":"1.0",//iPhone程序的版本號 "transaction_id":"1000000160390314", //交易的標識 "quantity":"1", //購買商品的數量 "unique_vendor_identifier":"AEEC55C0-FA41-426A-B9FC-324128342652", //開發商交易ID "item_id":"1008526677",//App Store用來標識程序的字符串 "product_id":"cosmosbox.strikehero.gems60",//商品的標識 "purchase_date":"2015-06-23 03:56:34 Etc/GMT",//購買時間 "original_purchase_date":"2015-06-23 03:56:34 Etc/GMT", //原始購買時間 "purchase_date_pst":"2015-06-22 20:56:34 America/Los_Angeles",//太平洋標准時間 "bid":"com.cosmosbox.StrikeHero",//iPhone程序的bundle標識 "original_purchase_date_ms":"1435031794826"//毫秒 }, "status":0 //狀態碼,0為成功 }
蘋果返回狀態碼
| Status | 描述 |
| 21000 | App Store不能讀取你提供的JSON對象 |
| 21002 | receipt-data域的數據有問題 |
| 21003 | receipt無法通過驗證 |
| 21004 | 提供的shared secret不匹配你賬號中的shared secret |
| 21005 | receipt服務器當前不可用 |
| 21006 | receipt合法,但是訂閱已過期。服務器接收到這個狀態碼時,receipt數據仍然會解碼並一起發送 |
| 21007 | receipt是Sandbox receipt,但卻發送至生產系統的驗證服務 |
| 21008 | receipt是生產receipt,但卻發送至Sandbox環境的驗證服務 |
更詳細的請參考:http://www.2cto.com/kf/201504/389224.html
最好在客戶端存一個數據庫,跟蹤訂單的狀態,防止用戶訂單在某個環節出現問題時無法尋找到訂單進行二次處理。
去AppStore請求數據時有時候會出現錯誤,你可以iTunes connect里的connect us去給他們寫郵件反饋問題。但是大部分時間你等等就能解決了,對就是什么也不做等着。也許那一天他就好了。
單機/服務器模式
IOS 應用內支付(內購 /In App Purchase)有兩種模式:
1) 單機模式
2) 服務器模式
單機模式
單機模式的流程可以簡單的總結為以下幾步:
1) app從app store 獲取產品信息
2) 用戶選擇需要購買的產品
3) app發送支付請求到app store
4) app store 處理支付請求,並返回transaction信息
5) app將購買的內容展示給用戶
服務器模式
服務器模式的主要流程如下所示:
1) app從服務器獲取產品標識列表
2) app從app store 獲取產品信息
3) 用戶選擇需要購買的產品
4) app 發送 支付請求到app store
5) app store 處理支付請求,返回transaction信息
6) app 將transaction receipt 發送到服務器
7) 服務器收到收據后發送到app stroe驗證收據的有效性
8) app store 返回收據的驗證結果
9) 根據app store 返回的結果決定用戶是否購買成功
兩種模式比較
上述兩種模式的不同之處主要在於:交易的收據驗證,內建模式沒有專門去驗證交易收據,而服務器模式會使用獨立的服務器去驗證交易收據。內建模式簡單快捷,但容易被破解。服務器模式流程相對復雜,但相對安全。
國內連接蘋果服務器的穩定性
開發之初,蘋果方就很負責的告知:我們的服務器不穩定。真正開發之后,發現蘋果方果然是很負責的,不僅是不穩定,而且足夠慢。app store server驗證一個收據需要3-6s時間。
1.用戶能否忍受3-6s的等待時間
2.如果app store server 宕機,如何確保成功付費的用戶能夠得到正常服務。
對於第一個問題,我們有理由相信用戶完全無法忍受,所以采用異步驗證的方式,服務器收到客戶端的請求后,就將請求放到MCQ中去處理。
對於第二個問題,由於蘋果人員很負責人的告知:我們的服務器不穩定,所以不排除收據驗證超時的情況。對於驗證超時的收據,保存到數據庫中並標記為驗證超時,定時任務每隔一定的時間去app store驗證,確保能夠獲取收據的驗證結果。
