0.前言:
實在躲不過去了,只能妥協(xié)了。??
1.準(zhǔn)備工作:
1.1.在ASC配置協(xié)議、稅務(wù)和銀行業(yè)務(wù)的信息,這一步可以交給PM完成。
1.2.在ASC里面配置項目的內(nèi)購項。首次添加內(nèi)購項時,內(nèi)購項填寫完整后需要和主項目一起提交審核。后期新增內(nèi)購項時可以在內(nèi)購項列表里面單獨添加。

注意:
①內(nèi)購項配置時的產(chǎn)品ID必須唯一,不能重復(fù)。(和已刪除的也不要重復(fù))
②根據(jù)自己的實際業(yè)務(wù)選擇消費類型。

2.配置沙箱賬號:
2.1.登錄ASC,選擇“用戶和訪問”,選擇“沙盒”里面的“測試員”,點擊“+”彈出配置頁,如圖2.1.

注意事項:
①里面的所有信息均不必是真實信息,可以隨便填寫。
②電子郵件:可以隨便填寫,但必須不能和現(xiàn)有的真實賬號重復(fù)(盡量蒙個唯一的)。
3.代碼集成
3.1.新建一個iap的單例類:iapTool。
說明:之所以用單例來實現(xiàn),就是為了保證訂單的生命周期,防止交易中,由于當(dāng)前類銷毀導(dǎo)致的一系列問題。
3.2.在iapTool.m中引入系統(tǒng)的內(nèi)購頭文件
import <StoreKit/StoreKit.h>
3.3.遵循兩個代理
<SKPaymentTransactionObserver,
SKProductsRequestDelegate>
3.4.在iapTool初始化里面添加支付監(jiān)聽。
說明:之所以在此處添加監(jiān)聽是為了保證監(jiān)聽的完整性以及監(jiān)聽的可復(fù)用性。
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
3.5.根據(jù)內(nèi)購項ID(ASC里面自己配置的),去蘋果服務(wù)器請求產(chǎn)品信息。
//檢測是否允許內(nèi)購
if ([SKPaymentQueue canMakePayments])
{
NSSet *productSet = [NSSet setWithArray:@[@"自己的內(nèi)購ID"]];
SKProductsRequest *productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productSet];
productRequest.delegate = self;
[productRequest start];
} else {
//已禁止內(nèi)購
}
3.6.執(zhí)行相關(guān)代理
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
SKProduct *requestProduct = nil;
for (SKProduct *product in response.products) {
if([product.productIdentifier isEqualToString:@"自己的內(nèi)購ID"]) {
requestProduct = product;
}
}
if (requestProduct) {
//開始下單
SKPayment *payment = [SKPayment paymentWithProduct:requestProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
} else {
//沒有查詢到相應(yīng)的產(chǎn)品信息。
}
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(@"請求動作失敗");
}
- (void)requestDidFinish:(SKRequest *)request
{
NSLog(@"請求動作完成");
}
3.7.監(jiān)聽下單結(jié)果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
{
for(SKPaymentTransaction *payment in transaction) {
switch (payment.transactionState) {
case SKPaymentTransactionStatePurchased:
{
NSLog(@"交易完成");
//結(jié)束交易
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
//獲取收據(jù)
NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
NSString *receipt = [data base64EncodedStringWithOptions:0];
NSLog(@"獲取收據(jù) receipt , 發(fā)給本地服務(wù)器,用于交易驗證,根據(jù)驗證結(jié)果下發(fā)商品");
break;
}
case SKPaymentTransactionStatePurchasing:
NSLog(@"交易中");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"恢復(fù)購買");
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.將收據(jù)發(fā)給本地服務(wù)器
將交易完成后的收據(jù)信息(receipt)發(fā)送給自己的服務(wù)器,并存儲。同時本地服務(wù)器須再次校驗訂單信息,確保準(zhǔn)確,并根據(jù)校驗結(jié)果做對應(yīng)處理(下發(fā)對應(yīng)的商品,或者給出失敗原因)
說明:服務(wù)器請求蘋果的訂單校驗接口時的請求時間較長,未報錯就耐心等待??
4.注意事項:
4.1.監(jiān)聽到支付結(jié)果后,務(wù)必要將交易置為完成狀態(tài),防止無效監(jiān)聽。
//將交易置為完成狀態(tài)
[[SKPaymentQueue defaultQueue] finishTransaction:payment];
4.2.用沙箱進(jìn)行調(diào)試的過程中及其不穩(wěn)定,例如:某些機型調(diào)不通、循環(huán)彈出驗證或ID的登錄頁面、每次的步驟不一樣、二次驗證巨慢等一系列問題。
不要慌!,這些基本是蘋果服務(wù)器的問題,和本地代碼關(guān)系不大。
如果不放心可以選擇給蘋果的技術(shù)支持反饋一下(反饋周期巨長??)。
4.3.首次上線內(nèi)購項,記得將已經(jīng)通過批準(zhǔn)的內(nèi)購項目添加到app的提交審頁面里面,一起提交審核。
4.4.如果需要做消費類型為“自動續(xù)訂型”的業(yè)務(wù),需要單獨處理,本篇文章未涉及。
4.5.開始調(diào)起支付的時候,需提前檢測一下訂單,將已完成的訂單結(jié)束交易。
//檢查訂單,若有已完成未結(jié)束的交易,須首先結(jié)束交易。直到符合條件后再開始新的交易。
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 的使用,要適時返回??。
②注意當(dāng)前代碼的使用位置,要放在請求內(nèi)購詳情之前??
5.如有需要,歡迎討論
支付完整上線思路,脫坑指南

@end