內(nèi)購(gòu)
一. 內(nèi)購(gòu)的簡(jiǎn)介
-
何謂內(nèi)購(gòu)
- 在iOS的App中, 如果你要購(gòu)買(mǎi)某件商品, 使用蘋(píng)果的支付方式進(jìn)行購(gòu)買(mǎi), 即為內(nèi)購(gòu)
- 蘋(píng)果規(guī)定, 如果你在App中銷(xiāo)售商品, 跟App功能相關(guān), 那么你就必須得通過(guò)內(nèi)購(gòu)的方式購(gòu)買(mǎi)
- 比如游戲中常見(jiàn)的關(guān)卡/游戲幣購(gòu)買(mǎi)
-
內(nèi)購(gòu)的缺點(diǎn)
- 從商家的角度來(lái)看, 蘋(píng)果會(huì)從內(nèi)購(gòu)中抽成, 比例為3 : 7, 也就是說(shuō)你賣(mài)10塊錢(qián)的東西, 蘋(píng)果會(huì)平白拿走你3塊錢(qián), 真流氓....
- 從用戶(hù)的角度來(lái)看, 內(nèi)購(gòu)支付, 需要用戶(hù)綁定銀行卡, 操作流程比較繁瑣, 比如本人, 第一次看到內(nèi)購(gòu)的步驟就不想用這個(gè)方法了
- 從商品的價(jià)格角度來(lái)看, 內(nèi)購(gòu)只能用蘋(píng)果指定的價(jià)格售賣(mài), 不能自定義, 再次重申蘋(píng)果的流氓度
-
為什么要用內(nèi)購(gòu)
- 內(nèi)購(gòu)作為一種營(yíng)銷(xiāo)方式: free + 內(nèi)購(gòu), 在一定意義上還是能起到不錯(cuò)的收益
- 如果你的App是采用直接收取App費(fèi)用的方式, 那么估計(jì)你在國(guó)內(nèi)是賣(mài)不出去了, 因?yàn)?strong>不符合國(guó)人的消費(fèi)習(xí)慣
- 廣告: 一般廣告都會(huì)內(nèi)嵌在App中, 他可以給開(kāi)發(fā)者帶來(lái)收益
- free+內(nèi)購(gòu)的模式, 可以先讓用戶(hù)體驗(yàn)?zāi)愕腁pp, 然后在讓用戶(hù)決定是否要掏錢(qián), 比較親民
- 但是, App中的某些業(yè)務(wù)功能, 蘋(píng)果規(guī)定必須使用蘋(píng)果內(nèi)購(gòu), 如果你沒(méi)使用, 蘋(píng)果是不會(huì)上架你的App的(流氓!!!重要的事情說(shuō)三遍)
- 不過(guò)相對(duì)的, 在AppStore中下載軟件, 都是可以放心使用的, 這點(diǎn)還是要給蘋(píng)果點(diǎn)個(gè)贊的
- 內(nèi)購(gòu)作為一種營(yíng)銷(xiāo)方式: free + 內(nèi)購(gòu), 在一定意義上還是能起到不錯(cuò)的收益
二. 內(nèi)購(gòu)的流程模擬
- 當(dāng)App創(chuàng)建出來(lái)時(shí)候, 你要告訴蘋(píng)果你要出售哪些物品
- 服務(wù)器作為提供方法, 將商品提供給購(gòu)買(mǎi)的用戶(hù)
- 蘋(píng)果公司要驗(yàn)證你的商品是否可以銷(xiāo)售, 同意的話才能賣(mài)
- 當(dāng)用戶(hù)購(gòu)買(mǎi)某個(gè)內(nèi)購(gòu)物品的時(shí)候, 會(huì)向App的服務(wù)器發(fā)送請(qǐng)求
- 當(dāng)服務(wù)器收到用戶(hù)的請(qǐng)求之后, 會(huì)給用戶(hù)一個(gè)連接, 類(lèi)似于開(kāi)具一個(gè)售賣(mài)小票
- 用戶(hù)此時(shí)要將在蘋(píng)果方付賬
- 當(dāng)蘋(píng)果方受理了用戶(hù)的購(gòu)買(mǎi)請(qǐng)求時(shí), 就會(huì)給交費(fèi)后的用戶(hù)授權(quán), 然后通知服務(wù)器給用戶(hù)發(fā)放產(chǎn)品
三. 內(nèi)購(gòu)的簡(jiǎn)單測(cè)試
-
在App管理中心 ,創(chuàng)建一個(gè)App, 并且填寫(xiě)App的信息
- 創(chuàng)建一個(gè)可以?xún)?nèi)購(gòu)的套裝ID, 即一個(gè)明確的APP ID
- 在ITunes Connect的用戶(hù)與智能中, 要?jiǎng)?chuàng)建一個(gè)沙箱技術(shù)測(cè)試員
-
創(chuàng)建一個(gè)需要銷(xiāo)售的商品, 并且添加到App
- 重點(diǎn): 添加內(nèi)購(gòu)商品時(shí), 需要保證稅務(wù)信息的完整性, 如果不完整, 產(chǎn)品信息不完全, 就無(wú)法申請(qǐng)內(nèi)購(gòu)
-
內(nèi)購(gòu)的產(chǎn)品類(lèi)型
- 非消耗品
- 購(gòu)買(mǎi)之后就一直存在, 不會(huì)消耗掉, 比如游戲中的關(guān)卡
- 非消耗物品購(gòu)買(mǎi)之后, 擁有永久的使用權(quán)利, 并且能被用戶(hù)再次下載, 且可以在其他設(shè)備上下載
- 消耗品
- 有使用次數(shù)的物品
- 一般被設(shè)定為某些可消耗的物品或是服務(wù), 并且使用之后不能再次下載
- 消耗品不能再用戶(hù)的設(shè)備之間跨設(shè)備使用, 他一般與用戶(hù)的賬號(hào)綁定的
- 其他類(lèi)型
- 免費(fèi)訂閱
- 自動(dòng)續(xù)費(fèi)訂閱
- 非自動(dòng)續(xù)費(fèi)訂閱
- 這三種一般適用于iBooks中, 但是目前大陸市場(chǎng)還不支持iBooks的各種訂閱.....
- 非消耗品
-
內(nèi)購(gòu)的代碼實(shí)現(xiàn)
- 配置App的Bundle ID, 要與配置內(nèi)購(gòu)信息時(shí)的Bundle ID相同
- 代碼實(shí)現(xiàn)
首先要導(dǎo)入StoreKit.framework框架
-
創(chuàng)建一個(gè)工具類(lèi), 并且創(chuàng)建一個(gè)類(lèi)方法, 用于發(fā)送商品的請(qǐng)求
class func getData(resultBlock: (goodsIds: Set<String>)->()) { resultBlock(goodsIds: ["com.fh.neigou.wupin1", "com.fh.neigou.wupin2"]) }
-
從App服務(wù)器請(qǐng)求數(shù)據(jù)列表, 并且向蘋(píng)果服務(wù)器請(qǐng)求可以銷(xiāo)售的商品列表
// 1. 從服務(wù)器請(qǐng)求, 需要被銷(xiāo)售的商品, 但是, 具體商品能不能被銷(xiāo)售, 還需要到蘋(píng)果服務(wù)器去驗(yàn)證才可以 DataTool.getData { (goodsIds) in // 2. 想蘋(píng)果服務(wù)器發(fā)送一個(gè)請(qǐng)求, 來(lái)驗(yàn)證, 哪些商品可以被銷(xiāo)售 // productIdentifiers: 驗(yàn)證的時(shí)候, 是靠商品的ID, 來(lái)進(jìn)行驗(yàn)證 let request = SKProductsRequest(productIdentifiers: goodsIds) // 開(kāi)始發(fā)送請(qǐng)求, 進(jìn)行驗(yàn)證(接口都封裝在方法內(nèi)部) // 接收請(qǐng)求下來(lái)的結(jié)果 request.delegate = self request.start() }
-
在代理方法中, 獲取并顯示銷(xiāo)售列表
// 當(dāng)蘋(píng)果服務(wù)器驗(yàn)證哪些商品可以被銷(xiāo)售, 完成之后, 就會(huì)通過(guò)這個(gè)方法, 來(lái)告訴我們驗(yàn)證的結(jié)果 func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { // 需要展示可以被銷(xiāo)售的商品 print(response.products) products = response.products print(response.invalidProductIdentifiers) }
-
點(diǎn)擊購(gòu)買(mǎi)商品, 創(chuàng)建支付對(duì)象, 放入隊(duì)列中, 并且設(shè)置交易隊(duì)列的監(jiān)聽(tīng)對(duì)象, 監(jiān)聽(tīng)每一筆交易
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { // 購(gòu)買(mǎi)點(diǎn)擊的商品 // 1. 取出商品 let product = products[indexPath.row] // 2. 購(gòu)買(mǎi)商品 // 2.1 根據(jù)商品開(kāi)一個(gè)小票 let payment = SKPayment(product: product) // 2.2 拿著小票去付款 // 添加到一個(gè)支付隊(duì)列里面 // 只要把一個(gè)支付對(duì)象, 放到支付隊(duì)列里面, 就開(kāi)始進(jìn)入支付流程 SKPaymentQueue.defaultQueue().addPayment(payment) // 2.3 設(shè)置交易隊(duì)列的監(jiān)聽(tīng)對(duì)象, 監(jiān)聽(tīng)里面存放的每一筆交易 SKPaymentQueue.defaultQueue().addTransactionObserver(self) }
-
調(diào)用支付的代理方法, 當(dāng)一筆交易的狀態(tài)發(fā)生改變時(shí), 就會(huì)調(diào)用這個(gè)方法, 獲取支付的狀態(tài)
for transaction in transactions { switch transaction.transactionState { case .Deferred: print("延遲購(gòu)買(mǎi)") case .Failed: print("支付失敗") // 應(yīng)該移除交易 queue.finishTransaction(transaction) case .Purchased: print("支付成功") // 應(yīng)該移除交易 queue.finishTransaction(transaction) case .Purchasing: print("正在支付") case .Restored: print("恢復(fù)購(gòu)買(mǎi)") // 應(yīng)該移除交易 queue.finishTransaction(transaction) default: print("交易可能掛了...") } }
-
恢復(fù)購(gòu)買(mǎi), 對(duì)于用戶(hù)已經(jīng)購(gòu)買(mǎi)過(guò)的商品, 可以直接發(fā)送請(qǐng)求, 并且給用戶(hù)提供商品
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
-
內(nèi)購(gòu)的測(cè)試
- 創(chuàng)建測(cè)試者賬號(hào)
- 在iTunes Connect中的用戶(hù)和職能中創(chuàng)建
- 創(chuàng)建沙箱技術(shù)測(cè)試人員
- 要注意, 測(cè)試賬號(hào)不能是注冊(cè)的真實(shí)存在的App ID
- 最好使用真機(jī)進(jìn)行測(cè)試, 并且賬號(hào)為添加的測(cè)試者賬號(hào)
- 創(chuàng)建測(cè)試者賬號(hào)
-
查看內(nèi)購(gòu)的銷(xiāo)售情況
- 登錄iTunes Connect
- 進(jìn)入銷(xiāo)售趨勢(shì), 在里面可以看到最近購(gòu)買(mǎi)的情況