iOS内购

作者: tikeyc | 来源:发表于2020-07-17 16:28 被阅读0次

    .h文件

    #import
    
    #define isServiceVerify  1//支付完成返回 校验方式
    
    typedef enum: NSUInteger {
    
        EPaymentTransactionStateNoPaymentPermission,//没有Payment权限
    
        EPaymentTransactionStateAddPaymentFailed,//addPayment失败
    
        EPaymentTransactionStatePurchasing,//正在购买
    
        EPaymentTransactionStatePurchased,//购买完成(销毁交易)
    
        EPaymentTransactionStateFailed,//购买失败(销毁交易)
    
        EPaymentTransactionStateCancel,//用户取消
    
        EPaymentTransactionStateRestored,//恢复购买(销毁交易)
    
        EPaymentTransactionStateDeferred,//最终状态未确定
    
    } EPaymentTransactionState;
    
    #define _InAppPurchasing [EInAppPurchasing sharedInstance]
    
    @class SKProduct;
    
    @class SKPaymentTransaction;
    
    @protocol EInAppPurchasingDelegate  <NSObject>
    
    @required
    
    - (BOOL)isProductIdentifierAvailable:(NSString*)productIdentifier;
    
    @optional
    
    - (void)updatedTransactions:(EPaymentTransactionState)state;
    
    //购买成功
    
    - (void)buySuccess:(SKPaymentTransaction*)transaction;
    
    //购买失败
    
    - (void)buyFailed:(NSError*)errorInfo;
    
    @end
    
    @interface EInAppPurchasing :NSObject
    
    + (instancetype)sharedInstance;
    
    @property (nonatomic, weak) id<EInAppPurchasingDelegate> delegate;
    
    //调用这个方法传入商品id
    
    - (void)identifyCanMakePayments:(NSArray*)requestArray;
    
    @end
    
    

    .m文件

    #import "EInAppPurchasing.h"
    
    #import  <StoreKit/StoreKit.h>
    
    #if TARGET_IPHONE_SIMULATOR
    
    // 开发时模拟器使用的验证服务器地址
    
    #define ITMS_VERIFY_RECEIPT_URL    @""
    
    #elif TARGET_OS_IPHONE
    
    //真机验证的服务器地址
    
    #define ITMS_VERIFY_RECEIPT_URL        @""
    
    #endif
    
    @interface EInAppPurchasing ()<SKProductsRequestDelegate,SKPaymentTransactionObserver,VerifyOrderCallBackDelegate>
    
    @property (nonatomic, strong) SKProductsRequest *request;
    
    @end
    
    @implementation EInAppPurchasing
    
    + (instancetype)sharedInstance
    
    {
    
        static EInAppPurchasing* instance =NULL;
    
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken, ^{
    
            instance = [EInAppPurchasing new];
    
        });
    
        return instance;
    
    }
    
    - (instancetype)init
    
    {
    
        self= [super init];
    
        if(self) {
    
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    
        }
    
        return self;
    
    }
    
    - (void)dealloc
    
    {
    
        [self releaseRequest];
    
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    
    }
    
    - (void)releaseRequest
    
    {
    
        if(_request) {
    
            [_request cancel];
    
            _request.delegate=nil;
    
            _request=nil;
    
        }
    
    }
    
    - (void)identifyCanMakePayments:(NSArray*)requestArray
    
    {
    
        if(requestArray.count==0) {
    
            if(self.delegate&& [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
    
                [self.delegate updatedTransactions:EPaymentTransactionStateAddPaymentFailed];
    
            }
    
            return;
    
        }
    
        if ([SKPaymentQueue canMakePayments]) {
    
            [self releaseRequest];
    
            self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:requestArray]];
    
            _request.delegate=self;
    
            [_request start];
    
        }
    
        else
    
        {
    
            if(self.delegate&& [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
    
                [self.delegate updatedTransactions:EPaymentTransactionStateNoPaymentPermission];
    
            }
    
        }
    
    }
    
    #pragma mark - SKProductsRequestDelegate
    
    - (void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response
    
    {
    
        NSLog(@"-----------收到产品反馈信息-------------- 产品ID:%@ 产品数量:%ld",response.invalidProductIdentifiers, response.products.count);
    
        NSArray * myProducts = response.products;
    
    
    
        for(SKProduct*product in myProducts){
    
            NSLog(@"SKProduct 描述信息%@", [product description]);
    
            NSLog(@"产品标题 %@", product.localizedTitle);
    
            NSLog(@"产品描述信息: %@" , product.localizedDescription);
    
            NSLog(@"价格: %@", product.price);
    
            NSLog(@"Product id: %@" , product.productIdentifier);
    
        }
    
    
    
        if(myProducts && myProducts.count>0) {
    
            SKProduct*product = [myProducts objectAtIndex:0];
    
            if(self.delegate&& [self.delegate respondsToSelector:@selector(isProductIdentifierAvailable:)]) {
    
                if ([self.delegate isProductIdentifierAvailable:product.productIdentifier]) {
    
                    SKPayment*payment = [SKPayment paymentWithProduct:product];
    
                    [[SKPaymentQueue defaultQueue] addPayment:payment];
    
                    return;
    
                }
    
            }
    
        }
    
    
    
        if(self.delegate&& [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
    
            [self.delegate updatedTransactions:EPaymentTransactionStateAddPaymentFailed];
    
        }
    
    }
    
    /** 请求失败 */
    
    - (void)request:(SKRequest*)request didFailWithError:(NSError*)error{
    
        NSLog(@"---购买失败");
    
    }
    
    #pragma mark - SKPaymentTransactionObserver
    
    /** 监听购买结果 */
    
    - (void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray *)transactions
    
    {
    
        for(SKPaymentTransaction *transaction in transactions)
    
        {
    
            EPaymentTransactionState state;
    
            switch(transaction.transactionState){
    
                case SKPaymentTransactionStatePurchasing:
    
                {
    
                    // 连接appStore
    
                    state =EPaymentTransactionStatePurchasing;
    
                }
    
                    break;
    
                case SKPaymentTransactionStatePurchased:
    
                {
    
                    state =EPaymentTransactionStatePurchased;
    
                    //交易完成
    
                    if(isServiceVerify) {
    
                        [self completeTransaction:transaction];
    
                    }
    
                    else
    
                    {
    
                        //本地作校验
    
                        [self verifyPurchase:transaction];
    
                    }
    
                }
    
                    break;
    
    
    
                case SKPaymentTransactionStateFailed:
    
                {
    
                    //交易失败
    
                    if(transaction.error.code!=SKErrorPaymentCancelled)
    
                    {
    
                        state =EPaymentTransactionStateFailed;
    
                    }else
    
                    {
    
                        state =EPaymentTransactionStateCancel;
    
                    }
    
                    [self finshTransaction:transaction];
    
                }
    
                    break;
    
    
    
                case SKPaymentTransactionStateRestored:
    
                {
    
                    state =EPaymentTransactionStateRestored;
    
                    //已经购买过该商品
    
    
    
                    [self finshTransaction:transaction];
    
                }
    
                    break;
    
                case SKPaymentTransactionStateDeferred:
    
                {
    
                    state =EPaymentTransactionStateDeferred;
    
                }
    
                    break;
    
                default:
    
                    break;
    
            }
    
            if(self.delegate&& [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
    
                [self.delegate updatedTransactions:state];
    
            }
    
        }
    
    }
    
    // Sent when transactions are removed from the queue (via finishTransaction:).
    
    - (void)paymentQueue:(SKPaymentQueue*)queue removedTransactions:(NSArray *)transactions
    
    {
    
        NSLog(@"---removedTransactions");
    
    }
    
    // Sent when an error is encountered while adding transactions from the user's purchase history back to the queue.
    
    - (void)paymentQueue:(SKPaymentQueue*)queue restoreCompletedTransactionsFailedWithError:(NSError*)error
    
    {
    
        NSLog(@"restoreCompletedTransactionsFailedWithError");
    
    }
    
    // Sent when all transactions from the user's purchase history have successfully been added back to the queue.
    
    - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue*)queue
    
    {
    
        NSLog(@"paymentQueueRestoreCompletedTransactionsFinished");
    
    }
    
    // Sent when the download state has changed.
    
    - (void)paymentQueue:(SKPaymentQueue*)queue updatedDownloads:(NSArray *)downloads
    
    {
    
        NSLog(@"updatedDownloads");
    
    }
    
    #pragma mark - Private
    
    #pragma mark 验证购买
    
    // 验证购买,在每一次购买完成之后,需要对购买的交易进行验证
    
    // 所谓验证,是将交易的凭证进行"加密",POST请求传递给苹果的服务器,苹果服务器对"加密"数据进行验证之后,
    
    // 会返回一个json数据,供开发者判断凭据是否有效
    
    // 有些“内购助手”同样会拦截验证凭据,返回一个伪造的验证结果
    
    // 所以在开发时,对凭据的检验要格外小心
    
    - (void)verifyPurchase:(SKPaymentTransaction*)transaction
    
    {
    
        //ios7开始支持
    
        NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    
        NSData*receiptData = [NSData dataWithContentsOfURL:receiptURL];
    
        NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    
        NSURL *url = [NSURL URLWithString:ITMS_VERIFY_RECEIPT_URL];
    
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
    
    
    
        NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
    
        NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
    
        [request setHTTPBody:payloadData];
    
        [request setHTTPMethod:@"POST"];
    
        NSURLResponse*response =nil;
    
        // 此请求返回的是一个json结果  将数据反序列化为数据字典
    
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    
        if(data ==nil) {
    
            return;
    
        }
    
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    
        if(jsonResponse !=nil) {
    
            if([[jsonResponse objectForKey:@"status"]intValue] ==0)
    
            {
    
                //通常需要校验:bid,product_id,purchase_date,status
    
    
    
            }
    
            else
    
            {
    
                //验证失败,检查你的机器是否越狱
    
            }
    
        }
    
    
    
        //结束交易
    
        [self finshTransaction:transaction];
    
    }
    
    - (void)completeTransaction:(SKPaymentTransaction*)transaction
    
    {
    
        //服务器校验
    
    }
    
    - (void)finshTransaction:(SKPaymentTransaction*)transaction
    
    {
    
        //结束交易
    
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:iOS内购

          本文链接:https://www.haomeiwen.com/subject/pooghktx.html