0.前言:
實在躲不過去了灌闺,只能妥協了。??
1.準備工作:
1.1.在ASC配置協議抚官、稅務和銀行業(yè)務的信息,這一步可以交給PM完成阶捆。
1.2.在ASC里面配置項目的內購項凌节。首次添加內購項時,內購項填寫完整后需要和主項目一起提交審核洒试。后期新增內購項時可以在內購項列表里面單獨添加倍奢。
注意:
①內購項配置時的產品ID必須唯一,不能重復垒棋。(和已刪除的也不要重復)
②根據自己的實際業(yè)務選擇消費類型卒煞。
2.配置沙箱賬號:
2.1.登錄ASC,選擇“用戶和訪問”叼架,選擇“沙盒”里面的“測試員”畔裕,點擊“+”彈出配置頁衣撬,如圖2.1.
注意事項:
①里面的所有信息均不必是真實信息,可以隨便填寫扮饶。
②電子郵件:可以隨便填寫具练,但必須不能和現有的真實賬號重復(盡量蒙個唯一的)。
3.代碼集成
3.1.新建一個iap的單例類:iapTool甜无。
說明:之所以用單例來實現扛点,就是為了保證訂單的生命周期,防止交易中岂丘,由于當前類銷毀導致的一系列問題陵究。
3.2.在iapTool.m中引入系統(tǒng)的內購頭文件
import <StoreKit/StoreKit.h>
3.3.遵循兩個代理
<SKPaymentTransactionObserver,
SKProductsRequestDelegate>
3.4.在iapTool初始化里面添加支付監(jiān)聽。
說明:之所以在此處添加監(jiān)聽是為了保證監(jiān)聽的完整性以及監(jiān)聽的可復用性奥帘。
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
3.5.根據內購項ID(ASC里面自己配置的)铜邮,去蘋果服務器請求產品信息。
//檢測是否允許內購
if ([SKPaymentQueue canMakePayments])
{
NSSet *productSet = [NSSet setWithArray:@[@"自己的內購ID"]];
SKProductsRequest *productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productSet];
productRequest.delegate = self;
[productRequest start];
} else {
//已禁止內購
}
3.6.執(zhí)行相關代理
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
SKProduct *requestProduct = nil;
for (SKProduct *product in response.products) {
if([product.productIdentifier isEqualToString:@"自己的內購ID"]) {
requestProduct = product;
}
}
if (requestProduct) {
//開始下單
SKPayment *payment = [SKPayment paymentWithProduct:requestProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
} else {
//沒有查詢到相應的產品信息翩概。
}
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(@"請求動作失敗");
}
- (void)requestDidFinish:(SKRequest *)request
{
NSLog(@"請求動作完成");
}
3.7.監(jiān)聽下單結果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
{
for(SKPaymentTransaction *payment in transaction) {
switch (payment.transactionState) {
case SKPaymentTransactionStatePurchased:
{
NSLog(@"交易完成");
//結束交易
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
//獲取收據
NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
NSString *receipt = [data base64EncodedStringWithOptions:0];
NSLog(@"獲取收據 receipt 牲距, 發(fā)給本地服務器,用于交易驗證钥庇,根據驗證結果下發(fā)商品");
break;
}
case SKPaymentTransactionStatePurchasing:
NSLog(@"交易中");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"恢復購買");
break;
case SKPaymentTransactionStateFailed:
{
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
NSLog(@"交易失敗");
if(payment.error.code != SKErrorPaymentCancelled)
{
NSLog(@"交易失旊咕稀:%@", payment.error.localizedDescription);
} else
{
NSLog(@"交易失斊酪獭:取消了交易");
}
break;
}
case SKPaymentTransactionStateDeferred:
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
NSLog(@"未知錯誤");
break;
default:
break;
}
}
}
3.8.將收據發(fā)給本地服務器
將交易完成后的收據信息(receipt)發(fā)送給自己的服務器难述,并存儲。同時本地服務器須再次校驗訂單信息吐句,確保準確胁后,并根據校驗結果做對應處理(下發(fā)對應的商品,或者給出失敗原因)
說明:服務器請求蘋果的訂單校驗接口時的請求時間較長嗦枢,未報錯就耐心等待??
4.注意事項:
4.1.監(jiān)聽到支付結果后攀芯,務必要將交易置為完成狀態(tài),防止無效監(jiān)聽文虏。
//將交易置為完成狀態(tài)
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
4.2.用沙箱進行調試的過程中及其不穩(wěn)定侣诺,例如:某些機型調不通、循環(huán)彈出驗證或ID的登錄頁面氧秘、每次的步驟不一樣年鸳、二次驗證巨慢等一系列問題。
不要慌!丸相,這些基本是蘋果服務器的問題搔确,和本地代碼關系不大。
如果不放心可以選擇給蘋果的技術支持反饋一下(反饋周期巨長??)。
4.3.首次上線內購項膳算,記得將已經通過批準的內購項目添加到app的提交審頁面里面座硕,一起提交審核。
4.4.如果需要做消費類型為“自動續(xù)訂型”的業(yè)務畦幢,需要單獨處理坎吻,本篇文章未涉及缆蝉。
4.5.開始調起支付的時候宇葱,需提前檢測一下訂單,將已完成的訂單結束交易刊头。
//檢查訂單黍瞧,若有已完成未結束的交易,須首先結束交易原杂。直到符合條件后再開始新的交易印颤。
NSArray *transactions = [SKPaymentQueue defaultQueue].transactions;
if (transactions.count > 0) {
SKPaymentTransaction *transaction = [transactions firstObject];
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(@"find unfinish transacion and finish this transacion");
return;
}
}
說明:
①注意代碼中 return 的使用,要適時返回??穿肄。
②注意當前代碼的使用位置年局,要放在請求內購詳情之前??
5.如有需要,歡迎討論
支付完整上線思路咸产,脫坑指南
@end