1、發送請求,注意請求ID
NSString *productID = @"這是建立内購項目填寫的ID";
NSArray *product = [[NSArray alloc] initWithObjects: productID,nil];
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
request.delegate = self;
2、 在監聽購買結果後,一定要調用[[SKPaymentQueue defaultQueue] finishTransaction:tran];來允許你從支付隊列中移除交易。
//監聽購買結果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
for(SKPaymentTransaction *tran in transaction){
switch (tran.transactionState) {
case SKPaymentTransactionStatePurchased:{
NSLog(@"交易完成");
// 發送到蘋果伺服器驗證憑證,進行二次驗證
[self verifyPurchaseWithProductionEnvironment];
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
}
break;
case SKPaymentTransactionStatePurchasing:
NSLog(@"商品添加進清單");
break;
case SKPaymentTransactionStateRestored:{
NSLog(@"已經購買過商品");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
}
break;
case SKPaymentTransactionStateFailed:{
NSLog(@"交易失敗");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
[SVProgressHUD showErrorWithStatus:@"購買失敗"];
}
break;
default:
break;
}
}
}
3、 沙盒環境測試appStore内購流程的時候,請使用沒越獄的裝置。
請務必使用真機來測試,一切以真機為準。
4、 項目的Bundle identifier需要與您申請AppID時填寫的bundleID一緻,不然會無法請求到商品資訊。
5、真機測試的時候,一定要退出原來的賬号,才能用沙盒測試賬号
6、二次驗證,請注意區分宏, 測試用沙盒驗證,App Store稽核的時候也使用的是沙盒購買,是以驗證購買憑證的時候需要判斷傳回Status Code決定是否去沙盒進行二次驗證,為了線上使用者的使用,驗證的順序肯定是先驗證正式環境,此時若傳回值為21007,就需要去沙盒二次驗證,因為此購買的是在沙盒進行的。
//沙盒測試環境驗證
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式環境驗證
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
/**
* 驗證購買,避免越獄軟體模拟蘋果請求達到非法購買問題
*
*/
-(void)verifyPurchaseWithProductionEnvironment{
//從沙盒中擷取交易憑證并且拼接成請求體資料
NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];
NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//轉化為base64字元串
NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];//拼接請求資料
NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
/*
注意:
自己測試的時候使用的是沙盒購買(測試環境)
App Store稽核的時候也使用的是沙盒購買(測試環境)
上線以後就不是用的沙盒購買了(正式環境)
是以此時應該先驗證正式環境,在驗證測試環境
正式環境驗證成功,說明是線上使用者在使用
正式環境驗證不成功傳回21007,說明是自己測試或者稽核人員在測試
*/
//第一步,驗證正式環境
//建立請求到蘋果官方進行購買驗證(正式環境)
NSURL *url=[NSURL URLWithString: AppStore];
NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url];
requestM.HTTPBody=bodyData;
[email protected]"POST";
//建立連接配接并發送同步請求
NSError *error=nil;
NSData *responseData=[NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
if (error) {
NSLog(@"驗證購買過程中發生錯誤,錯誤資訊:%@",error.localizedDescription);
return;
}
NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"%@",dic);
if([dic[@"status"] intValue]==0){
//正式環境驗證通過(說明是上線以後的使用者購買)
NSLog(@"購買成功!");
//在此處對購買記錄進行存儲,可以存儲到開發商的伺服器端
}else if([dic[@"status"] intValue]== 21007){
//This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
//購買憑證來自于測試環境,但是卻發送到了正式環境,請改成測試環境(這種情況下可能是自己測試的,也可能是稽核人員測試的)
//第二步,驗證測試環境
[self verifyPurchaseWithTestEnvironment];
}
}
//建立請求到蘋果官方進行購買驗證(測試環境)
- (void)verifyPurchaseWithTestEnvironment {
NSURL *url=[NSURL URLWithString:SANDBOX];
NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url];
requestM.HTTPBody=bodyData;
[email protected]"POST";
//建立連接配接并發送同步請求
NSError *error=nil;
NSData *responseData=[NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
if (error) {
NSLog(@"驗證購買過程中發生錯誤,錯誤資訊:%@",error.localizedDescription);
return;
}
NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"%@",dic);
if([dic[@"status"] intValue]==0){
NSLog(@"購買成功!");
//在此處對購買記錄進行存儲,可以存儲到開發商的伺服器端
}else{
NSLog(@"購買失敗,未通過驗證!");
}
}