? ? ? ?最近幾個(gè)星期牢撼,應(yīng)產(chǎn)品需求開(kāi)發(fā)了應(yīng)用內(nèi)支付流程夏醉,即IAP爽锥。提筆寫下大致過(guò)程,分享與大家交流畔柔。我這里是從development開(kāi)發(fā)者中心創(chuàng)建證書和配置文件氯夷,在iTunes后天創(chuàng)建應(yīng)用,創(chuàng)建虛擬商品靶擦,接入OC代碼這樣一套邏輯來(lái)寫的腮考,如果新手不太明白具體內(nèi)容,建議先看看蘋果官方文檔的中文翻譯版本玄捕,了解一二2任怠!枚粘!
1馅闽,配置Developer.apple.com
(1)登錄到Developer.apple.com,創(chuàng)建證書馍迄,即開(kāi)發(fā)者開(kāi)發(fā)證書
(2)為應(yīng)用建立建立一個(gè)不帶通配符的App ID
(3)用該App ID生成和安裝相應(yīng)的Provisioning Profile文件
(4)添加真機(jī)測(cè)試的手機(jī)
2福也,配置iTunes Connect
(1)登錄到iTunes Connet,用該App ID創(chuàng)建一個(gè)新的應(yīng)用柬姚,大致信息填寫
(2)在功能模塊拟杉,創(chuàng)建虛擬物品
這里的產(chǎn)品ID,最好寫的有意義量承,在后面代碼接入購(gòu)買的時(shí)候用到
(3)設(shè)置稅務(wù)和銀行卡信息
我這邊是經(jīng)理事先填好的,需要的話穴店,請(qǐng)看這里http://openfibers.github.io/blog/2015/02/28/in-app-purchase-walk-through/
(4)創(chuàng)建應(yīng)用的沙盒測(cè)試賬號(hào)
點(diǎn)擊用戶與職能
點(diǎn)擊+號(hào)撕捍,根據(jù)具體信息填寫
3,接入代碼
(1)設(shè)置bundleID泣洞,填加證書和配置文件忧风,保證能在手機(jī)上跑起來(lái)
(2)普及一個(gè),我這邊學(xué)到的知識(shí)
IAP的支付流程分為兩種球凰,一種是有服務(wù)器參與的狮腿,一種是沒(méi)有服務(wù)器參與的腿宰。有服務(wù)器參與就是說(shuō),在購(gòu)買之前缘厢,需要把產(chǎn)品的相關(guān)信息發(fā)送到服務(wù)器吃度,服務(wù)器驗(yàn)證購(gòu)買憑證,如果成功贴硫,我們能拿到訂單字符串椿每,發(fā)起支付購(gòu)買,完成之后英遭,蘋果服務(wù)器返回結(jié)果间护,我們拿到結(jié)果在跟服務(wù)器驗(yàn)證,驗(yàn)證成功后挖诸,可以由服務(wù)器發(fā)放具體的商品汁尺;沒(méi)有服務(wù)器參與的話,就是跳過(guò)了驗(yàn)證過(guò)程多律,是由客戶端自己處理邏輯均函。具體在看代碼吧。
官方的兩張圖菱涤,有服務(wù)器和無(wú)服務(wù)器
(3)需要在工程中引入 Storekit.framework框架
? ? ? ? ? 支付控制器中 #import <StoreKit/StoreKit.h>
? ? ? ? ? 遵守兩個(gè)代理協(xié)議 SKProductsRequestDelegate 和 SKPaymentTransactionObserver苞也, 前者是獲取產(chǎn)品信息的回調(diào),后者是購(gòu)買的觀察者粘秆。
(4)創(chuàng)建一個(gè)獲取產(chǎn)品信息的請(qǐng)求
NSSet * set = [NSSet setWithArray:@[prodectId]]; // 這個(gè)就是產(chǎn)品ID如迟,在iTunes后臺(tái)創(chuàng)建
SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers: set];
request.delegate = self; // 遵守SKProductsRequestDelegate代理
[request start];
查詢產(chǎn)品信息的回調(diào)函數(shù)
- ?(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
? ? ? ? ? ? NSArray *myProduct = response.products; ? ?// 獲取到的商品數(shù)組
? ? ? ? ? ? if (myProduct.count == 0) {
? ? ? ? ? ? ? ? ? ? // 沒(méi)有獲取到
? ? ? ? ? ?{
// 代碼到此,就是有商品了攻走。這時(shí)就有兩種操作殷勘,一種是向服務(wù)器驗(yàn)證購(gòu)買憑證,獲取訂單字符串昔搂,發(fā)起購(gòu)買玲销;一種是直接拿商品ID發(fā)起購(gòu)買。
? ? ? ? ? ? SKMutablePayment *mPayment = [[SKMutablePayment alloc] init];
? ? ? ? ? ? mPayment.productIdentifier = productID; // 產(chǎn)品ID
? ? ? ? ? ? [[SKPaymentQueue defaultQueue] addPayment:mPayment]; ?// 調(diào)起支付界面摘符,發(fā)起購(gòu)買
}
(5)把控制器設(shè)置為監(jiān)聽(tīng)購(gòu)買操作的觀察者贤斜,這一步,在ViewDidLoad中設(shè)置
? ?[[SKPaymentQueue defaultQueue] ?addTransactionObserver: self];
購(gòu)買結(jié)果的回調(diào)
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray*)transactions {
? ? ? ? ? ?for (SKPaymentTransaction *transaction in transactions) {
? ? ? ? ? ? ? ? ? ? ? ? ? switch (transaction.transactionState) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?case SKPaymentTransactionStatePurchasing:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"商品加入列表逛裤,正在購(gòu)買中...");?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case SKPaymentTransactionStatePurchased:? ? // 購(gòu)買完成
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"購(gòu)買完成");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [self finishedTransaction:transaction];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case SKPaymentTransactionStateFailed:? ? ? // 交易失敗
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[self failedTransaction:transaction];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?case SKPaymentTransactionStateRestored: //已經(jīng)購(gòu)買過(guò)該商品
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"已經(jīng)購(gòu)買過(guò)該商品");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [self alreadyBuyWithTransaction:transaction];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?default:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ?}
}
注: 完成購(gòu)買的操作中瘩绒,如果有服務(wù)器,需要向服務(wù)器驗(yàn)證購(gòu)買結(jié)果带族,如果沒(méi)有锁荔,就直接完成。
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
調(diào)起支付后蝙砌,輸入注冊(cè)的沙盒賬號(hào)即可點(diǎn)擊購(gòu)買阳堕。
注:這里有幾個(gè)注意事項(xiàng)
一跋理,測(cè)試支付的ipa必須使用[App-Store]證書
二,越獄機(jī)器無(wú)法測(cè)試IAP
三恬总,用SandBox賬號(hào)測(cè)試支付的時(shí)候,必須把在系統(tǒng)[設(shè)置]里面把[Itunes Store 與 App Store]登錄的非 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SandBox賬號(hào)注銷掉,否則向蘋果服務(wù)器請(qǐng)求不到訂單信息
四前普,Sandbox賬號(hào)不要在正式支付環(huán)境登陸支付,登陸過(guò)的正式支付環(huán)境的SandBox賬號(hào)會(huì)失效
五越驻,所有在itunes上配置的商品都必須可購(gòu)買,不能有某些商品根據(jù)商戶自己的服務(wù)器的數(shù)據(jù)在某個(gè)時(shí)期出現(xiàn)免費(fèi)的情況
六汁政,商品列表不能按照某些特定條件進(jìn)行排序(比如說(shuō)下載量)
七,非消耗型商品必須的有恢復(fù)商品功能
八缀旁,非消耗類型的商品不要和商戶自己的服務(wù)器關(guān)聯(lián)