iOSアプリ内購入(IAP)

6891 ワード

一、どのような場合に内販を使う必要がありますか?
あなたのアプリケーションには、購読、会員、または購入する必要があるサービス、オープン機能の使用などの機能が含まれている場合は、購入を考慮する必要があります.
二、アプリケーション内の購入にはどのような準備が必要ですか?
1.Paid Applications agreement(「有料アプリケーション契約」)に署名する2、iTunes ConnectでApp内購入項目を構成する3、XcodeでApp内購入項目を有効にする4、App内購入項目の詳細を設計して作成するApp内購入項目構成プロセスを参照する
三、内部購入API購入プロセス
1、SKPaymentQueueのcanMakePayments方法により支払可能か否かを判断する2、SKPaymentQueueのaddTransactionObserver:により取引対象観察者を追加する3、SKProductsRequestにより支払要求を開始し、エージェントSKProductsRequestDelegate 4を追加し、要求応答が-(void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response;メソッドコールバック5、上記エージェントメソッドでSKPaymentオブジェクトを作成してSKPaymentQueueに追加し、6、取引が終了すると-(void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray*)transaction;メソッドコールバックは、取引が成功した後、取引証明書の検証、サーバとのインタラクティブな受注取引状態などの情報が必要です.
四、コード実装
#import "ApplePayOperation.m"
#import 

#define VerifyReceipt @"https://sandbox.itunes.apple.com/verifyReceipt"
//#define VerifyReceipt @"https://buy.itunes.apple.com/verifyReceipt"

@interface ApplePayOperation () 
{
    /**        */
    SKPaymentTransaction *_currentTransaction;
}
@end

@implementation ApplePayOperation

#pragma mark - Life Cycle
+ (instancetype)payOperation
{
    return [ApplePayOperation new];
}

- (instancetype)init
{
    if (self = [super init])
    {
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    
    return self;
}

- (void)dealloc
{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

#pragma mark - Public Method
- (void)payWithProductID:(NSString *)productID
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        if ([SKPaymentQueue canMakePayments])
        {
            [self _payWithProductID:productID];
        }
    });
}

- (void)payEnd
{
    if (_currentTransaction)
    {
        [[SKPaymentQueue defaultQueue] finishTransaction:_currentTransaction];
    }
}

#pragma mark - Private Method
- (void)_payWithProductID:(NSString *)productID
{
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:[NSArray arrayWithObject:productID]]];
    request.delegate = self;
    [request start];
}

- (void)_payFailed
{
    if ([_delegate respondsToSelector:@selector(applePayOperationFailed)])
    {
        [_delegate applePayOperationFailed];
    }
}

- (void)_verifyPurchaseWithPaymentTransaction:(SKPaymentTransaction *)transaction
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        //                     
        NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
        NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
        
        //    base64   
        NSString *receiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        
        //       
        NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];
        NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
        
        //                
        NSURL *url = [NSURL URLWithString:VerifyReceipt];
        NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
        requestM.HTTPBody = bodyData;
        requestM.HTTPMethod = @"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);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSDictionary *dicReceipt = dic[@"receipt"];
            NSDictionary *dicInApp = [dicReceipt[@"in_app"] firstObject];
            NSString *payID = dicInApp[@"product_id"];
           
            //     
            if ([dic[@"status"] intValue] == 0)
            {
                //              
            }
            else
            {
                NSLog(@"    ,     !");
                
                [self _payFailed];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
        });
    });
}

#pragma mark - Delegate
#pragma mark -SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    if (response.products.count > 0)
    {
        SKPayment *payment = [SKPayment paymentWithProduct:response.products[0]];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
    else
    {
        [self _payFailed];
    }
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"    ");
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

#pragma mark -SKPaymentTransactionObserver
#pragma mark -    
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
{
    for (SKPaymentTransaction *tran in transaction)
    {
        _currentTransaction = tran;
        
        switch (tran.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
            {
                NSLog(@"    ");
                //     
                [self _verifyPurchaseWithPaymentTransaction:tran];
            }
                break;
                
            case SKPaymentTransactionStatePurchasing:
            {
                NSLog(@"       ");
            }
                break;
                
            case SKPaymentTransactionStateRestored:
            {
                NSLog(@"       ");
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
            }
                break;
                
            case SKPaymentTransactionStateFailed:
            {
                NSLog(@"    ");
                
                [self _payFailed];
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
            }
                break;
                
            default:
                break;
        }
    }
}

@end
五、国内購入のよくある問題
1、サーバーの応答が失効する問題のため、いつも注文を失う現象が現れて、この現象を避けるために取引証明書を記録して取引証明書を検証することによってこの問題を解決することができます2、アップルの購入収入アップルの振り替え時間は一般的に取引が完了した(150ドル取引後)当月の最終日の45日以内に、応答を得るためには、銀行に相応の資料を準備してから送金を受け取る必要があります.資料には、a、製品の業務プロトコル(インターネットメールの会話コピー画面)が含まれています.b、アップルのインターフェースには会社の製品が株を持っている.c、アップルとの清算協議