IAP流程
介紹
這里介紹的IAP使用服務(wù)器模式:
- 調(diào)用服務(wù)器接口創(chuàng)建一個(gè)商品的訂單
- 請求Apple的商品列表
- 選取商品調(diào)用蘋果支付
- 支付成功(會返回憑證)
- 把支付成功的返回憑證上傳到APP服務(wù)器(帶上訂單的ID,有利于后臺判斷是哪個(gè)訂單支付成功)
- APP服務(wù)器保存該憑證等數(shù)據(jù)并像蘋果服務(wù)器發(fā)起憑證驗(yàn)證柬批,驗(yàn)證成功則發(fā)送商品
配置
iTunesConnect上創(chuàng)建內(nèi)購項(xiàng)目啸澡。
開發(fā)流程
客戶端流程
1.初始化,添加一個(gè)交易隊(duì)列觀察者
[[SKPaymentQueue defaultQueue] addTransactionObserver:xxxx];
IAP支付的機(jī)制,每次支付行為或每筆交易被認(rèn)為是一個(gè)SKPaymentTransation,只有當(dāng)SKPaymentTransation被finishTransaction:,這次支付(交易)行為才算是正常結(jié)束了氮帐。即使這次支付途中被中斷,其實(shí)也并沒有丟失嗅虏。假設(shè)支付沒有完成 App 就退出了(比如崩潰),那么當(dāng)下次 App 重啟之后,只要設(shè)置了監(jiān)聽addTransactionObserver:,之前被中斷的支付就會接著進(jìn)行。
2.去蘋果服務(wù)器請求產(chǎn)品信息
NSSet* set = [NSSet setWithObjects:productId, nil];
SKProductsRequest* skr = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
self.skProductsRequest = skr;
self.skProductsRequest.delegate = self;
[self.skProductsRequest start];
3.請求回調(diào)
請求到IAP產(chǎn)品信息上沐,發(fā)起購買
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
if (response.products.count == self.arrayFromatProducts.count) {
[self parseFromattingPriceData:response.products];
}else{
SKPayment* p = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]];
[[SKPaymentQueue defaultQueue] addPayment:p];
}
}
請求失斊し:
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
if (self.requestProductFailure) {
self.requestProductFailure(error);
}
}
購買結(jié)果:
#pragma mark SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for (SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchased:{
NSLog(@"transaction.payment.productIdentifier:%@",transaction.payment.productIdentifier);
[self verifyPuschase:transaction];
break;
}
case SKPaymentTransactionStateRestored:{//已經(jīng)購買過該商品
[self verifyPuschase:transaction];
break;
}
case SKPaymentTransactionStateFailed:{
[[SKPaymentQueue defaultQueue]finishTransaction:tran];
if(transaction.error.code != SKErrorPaymentCancelled) {
NSLog(@"購買失敗");
} else {
NSLog(@"用戶取消交易");
}
break;
}
default:
break;
}
}
}
購買結(jié)果發(fā)送到服務(wù)端。服務(wù)端再到蘋果服務(wù)器驗(yàn)證憑證
收到
- (void)verifyPurchase:(SKPaymentTransaction *)transaction {
//先發(fā)服務(wù)端驗(yàn)證
//收到服務(wù)端驗(yàn)證成功后参咙,完成蘋果訂單龄广。
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
退出時(shí)移除觀察者
- (void)dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
服務(wù)端流程
服務(wù)端收到購買成功,發(fā)送到蘋果服務(wù)器驗(yàn)證蕴侧。
//沙盒測試環(huán)境驗(yàn)證
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式環(huán)境驗(yàn)證
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
沙盒測試
-
在用戶與職能中添加沙箱測試賬號择同。
xcode配置項(xiàng)目的bundleid與Apple后臺配置的bundleid一致。打開In App Purchase
退出iPhone的App Store賬號(因?yàn)槲覀冃枰褂蒙澈匈~號登錄)
xcode運(yùn)行App戈盈,購買商品奠衔,系統(tǒng)會讓你進(jìn)行登錄,這里我們點(diǎn)擊“使用現(xiàn)有的AppleID”就可以沙盒測試賬號進(jìn)行登錄了塘娶。
重試機(jī)制
IAP在實(shí)際使用中會有用戶返回內(nèi)購丟單的情況归斤。分析在整個(gè)流程中會有兩個(gè)環(huán)節(jié)失敗的情況。
- Apple支付成功后刁岸,客戶端沒有收到Apple支付的回調(diào)脏里,無法發(fā)起服務(wù)端驗(yàn)證。
【解決辦法】:App啟動(dòng)后要注冊對Apple支付結(jié)果回調(diào)的觀察虹曙。這樣Apple還會恢復(fù)支付狀態(tài)更新的回調(diào)迫横。
- 收到Apple支付成功后,發(fā)起服務(wù)端驗(yàn)證失敗酝碳。這樣在Apple那里已經(jīng)支付完成了矾踱,但是用戶卻沒有收到購買的商品。
【解決辦法】:增加重試, 延遲對蘋果訂單的確認(rèn)疏哗。
- 1呛讲、發(fā)起服務(wù)端驗(yàn)證接口失敗(網(wǎng)絡(luò)錯(cuò)誤或者業(yè)務(wù)錯(cuò)誤時(shí)),立即間隔一段時(shí)間重試
- 2贝搁、延遲對蘋果訂單的確認(rèn)吗氏,充值完成才確認(rèn)蘋果訂單。App啟動(dòng)的時(shí)候雷逆,對于未驗(yàn)證成功的支付弦讽,再次發(fā)起服務(wù)端驗(yàn)證。