最近做了iOS程序內購買,封裝了一下給上層調用,現在介紹下流程和簡單的實現。具體可以看我上傳到Github的代碼ZInAppPurchase,或者直接在CocoaPods拉取ZInAppPurchase。(第一次試試上傳到CocoaPods,還沒加demo)
程序內購買要做的話要考慮很多,像漏單處理、重新購買處理等等,對于游戲App來說更需要考慮。下面只介紹最簡單的流程和處理。
iOS程序內購買流程主要分幾步:
iTunes Connect商品配置添加沙箱技術測試員App內獲取購買商品驗證receipt主要是填寫完整信息和添加商品。
登錄iTunes Connect,進入”協議、稅務和銀行業務“。
如果Contracts In PRocess下有All(See Contract)和Contact Info、Bank Info、Tax Info三列,則表示已填寫;否則點擊Request按照提示進行操作。之后就會出現Contact Info、Bank Info、Tax Info三列,分別Set Up(需要同公司財務人員一起填寫)。
(如果沒有填寫完整只能添加免費訂閱商品)
登錄iTunes Connect,進入我的App——功能——App內購買項目,點擊+號。可以添加的類型有:消耗型項目、非消耗型項目、自動續訂訂閱、免費訂閱、非續訂訂閱。商品添加完屏幕快照就會變成準備提交狀態。
注意:產品 ID不可重復,如果刪除某個商品,以后這個產品的ID也不可用,即使它已經被刪除了;另外類型也不能改,選錯了只能重新增加一個商品。
登錄iTunes Connect,進入用戶和職能——沙箱技術測試員,點擊+號。(必須是未注冊的Apple賬號,用于測試購買)
根據productId獲取商品信息(可以獲取多個):
let productRequest = SKProductsRequest(productIdentifiers: Set<String>(arrayLiteral: productId))productRequest.delegate = selfproductRequest.start()實現SKProductsRequestDelegate:
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { if let product = response.products.first {// 獲取返回的商品 }}購買商品購買獲取的商品product:
if SKPaymentQueue.canMakePayments() {// 是否能且允許支付 let payment = SKPayment(product: product) SKPaymentQueue.defaultQueue().addTransactionObserver(self) SKPaymentQueue.defaultQueue().addPayment(payment)}實現SKPaymentTransactionObserver:
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch transaction.transactionState { case .Purchased: // Transaction is in queue, user has been charged. Client should complete the transaction. if let receiptUrl = NSBundle.mainBundle().appStoreReceiptURL, let receiptData = NSData(contentsOfURL: receiptUrl) { let receiptString = receiptData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) // 將receiptString發給服務器 } SKPaymentQueue.defaultQueue().finishTransaction(transaction) case .Failed: // Transaction was cancelled or failed before being added to the server queue. if let errorCode = transaction.error?.code { } SKPaymentQueue.defaultQueue().finishTransaction(transaction) default: break } }}receipt驗證可以本地驗證,也可以提交給App Store驗證。
參考鏈接:Validating Receipts With the App Store
我們是將receipt進行base64編碼后,傳給服務器,服務器判斷憑證是否已經存在或驗證過,再去POST給Apple服務器驗證。
沙箱環境POST的URLhttps://sandbox.itunes.apple.com/verifyReceipt
正式環境POST的URLhttps://buy.itunes.apple.com/verifyReceipt
驗證后Apple會返回數據,從中可以獲取product_id、quantity等,下面是正確時的返回數據:
{ "status": 0, "environment": "Sandbox", "receipt": { "receipt_type": "ProductionSandbox", "adam_id": 0, "app_item_id": 0, "bundle_id": "com.xxx.xxxxxx", "application_version": "999", "download_id": 0, "version_external_identifier": 0, "receipt_creation_date": "2016-05-26 04:35:08 Etc/GMT", "receipt_creation_date_ms": "1464237308000", "receipt_creation_date_pst": "2016-05-25 21:35:08 America/Los_Angeles", "request_date": "2016-05-26 06:40:32 Etc/GMT", "request_date_ms": "1464244832729", "request_date_pst": "2016-05-25 23:40:32 America/Los_Angeles", "original_purchase_date": "2013-08-01 07:00:00 Etc/GMT", "original_purchase_date_ms": "1375340400000", "original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles", "original_application_version": "1.0", "in_app": [ { "quantity": "1", "product_id": "000000", "transaction_id": "1000000213676495", "original_transaction_id": "1000000213676495", "purchase_date": "2016-05-26 04:35:08 Etc/GMT", "purchase_date_ms": "1464237308000", "purchase_date_pst": "2016-05-25 21:35:08 America/Los_Angeles", "original_purchase_date": "2016-05-26 04:35:08 Etc/GMT", "original_purchase_date_ms": "1464237308000", "original_purchase_date_pst": "2016-05-25 21:35:08 America/Los_Angeles", "is_trial_period": "false" } ] }}下面是在沙箱環境下的真機測試截圖(“測試”是所填寫的產品名稱,未登錄Apple ID時會提示登錄,已登錄時會提示輸入密碼/Touch ID):
IMG_6816.PNG
IMG_6814.PNG在iTunes Connect添加完App版本后,在App 內購買項目處添加該版本新增的App內購買項目。
新聞熱點
疑難解答