当前位置 博文首页 > xixi:iOS苹果IAP 充值

    xixi:iOS苹果IAP 充值

    作者:[db:作者] 时间:2021-08-07 15:33

    这次遇到的问题主要有两点

    1.税收那一块没有填好一些东西,这样会导致 在代码里面调用SDK 没有办法返回 预先创建好的商品类。

    2.进行付款时候 将记录进行本地存储。服务端也做这样的处理。 (毕竟这个是涉及到钱,谨慎一点好)



    假设 我选择的product_id : com.mytest.xixi

    这个id 是在 itunesconnect 设置好





    首先要 假如通知,通知是一对的


    -(void)dealloc
    {
        //解除监听的通知
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        //假如监听的通知
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        //假如这里是选择了product_id = @"com.mytest.xixi";
        selectProductID = @"com.mytest.xixi";
        [self doIAPAction:selectProductID];
    }


    首先要判断是否能够可以使用IAP, 发起请求向苹果询问是否有哪些商品可售

    - (void)doIAPAction:(NSString *)selectArg
    {
        if([SKPaymentQueue canMakePayments])
        {
            [self requestProductData:selectArg];
        }
        else
        {
            NSLog(@"不允许程序内付费");
        }
    }
    
    //请求商品
    - (void)requestProductData:(NSString *)selectArg
    {
        NSLog(@"-------------请求对应的产品信息----------------");
        NSArray *product = [[NSArray alloc] initWithObjects:selectArg,
                                                            nil];
        
        NSSet *nsset = [NSSet setWithArray:product];
        self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
        self.request.delegate = self;
        [self.request start];
        
    }

    有网络请求 那么肯定会有成功或者失败,下面这几个都是代理里面可以找到


    //收到产品返回信息
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
        
        NSLog(@"--------------收到产品反馈消息---------------------");
        NSArray *product = response.products;
        if([product count] == 0)
        {
            NSLog(@"--------------没有商品------------------");
            return;
        }
        
        NSLog(@"productID:%@", response.invalidProductIdentifiers);
        NSLog(@"产品付费数量:%ld",(long)[product count]);
        
        SKProduct *p = nil;
        for (SKProduct *pro in product)
        {
            NSLog(@"%@", [pro description]);
            NSLog(@"%@", [pro localizedTitle]);
            NSLog(@"%@", [pro localizedDescription]);
            NSLog(@"%@", [pro price]);
            NSLog(@"%@", [pro productIdentifier]);
            
            if([pro.productIdentifier isEqualToString:selectProductID])
            {
                p = pro;
            }
        }
        
        SKPayment *payment = [SKPayment paymentWithProduct:p];
        
        NSLog(@"发送购买请求");
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
    

    //请求失败
    - (void)request:(SKRequest *)request didFailWithError:(NSError *)error
    {
        NSLog(@"------------------错误-----------------:%@", error);
    }
    
    - (void)requestDidFinish:(SKRequest *)request
    {
        NSLog(@"------------反馈信息结束-----------------");
    }


    //监听购买结果
    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
    {
        for(SKPaymentTransaction *tran in transaction)
        {
            
            switch (tran.transactionState)
            {
                case SKPaymentTransactionStatePurchased:
                    NSLog(@"交易完成");
                    [self completeTransaction:tran];
                    
                    break;
                case SKPaymentTransactionStatePurchasing:
                    NSLog(@"商品添加进列表");
                    
                    break;
                case SKPaymentTransactionStateRestored:
                    NSLog(@"已经购买过商品");
                    
                    break;
                case SKPaymentTransactionStateFailed:
                    NSLog(@"交易失败");
                    NSLog(@"%@",tran);
                    [self failedTransaction:tran];
                    
                    break;
                default:
                    break;
            }
        }
    }
    
    //交易结束
    - (void)completeTransaction:(SKPaymentTransaction *)transaction
    {
        NSLog(@"交易结束");
        
        
        // Your application should implement these two methods.
        NSString * productIdentifier = transaction.payment.productIdentifier;
        if ([productIdentifier length] > 0)
        {
            // 向自己的服务器验证购买凭证
            [self verifyPruchase:transaction];
        }
        // Remove the transaction from the payment queue.
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    }
    
    
    
    
    - (void)failedTransaction:(SKPaymentTransaction *)transaction
    {
        HIDE_PROGRESS(self.view);
        if(transaction.error.code != SKErrorPaymentCancelled)
        {
            NSLog(@"购买失败");
        }
        else
        {
            NSLog(@"用户取消交易");
        }
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    }

    #pragma mark 验证购买凭据
    - (void)verifyPruchase:(SKPaymentTransaction *)transaction
    {
        // 验证凭据,获取到苹果返回的交易凭据
        // appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
        NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
        // 从沙盒中获取到购买凭据
        NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
        
        NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        
        
        NSString *transId = transaction.transactionIdentifier;
        NSString *productId = transaction.payment.productIdentifier;
        
        if (!encodeStr)
        {
            return;
        }
        
        //下面开始描述处理的逻辑
        /*
         * 1.首先将这些数据(encodeStr,productId,transId,...)进行加密什么的 存储在本地数据库
         * 2.然后将 这些数据 传到服务端 让服务端 跟apple 进行一次验证(也有人放在客户端代码里面进行验证),服务端接收到这些数据最好也是存储一下
         * 3.服务端和apple验证成功之后返回告诉客户端通过之后,客户端这边就把本地数据库存储的相关数据给删掉,服务端也删。(两边都做处理保证一下,毕竟涉及到金钱)
         * 4.这就完成一个正常的流程。(我自己个人认为)
         *
         * 3.1 也会出现这种情况 可能服务端和apple 验证的时候 时间太久了导致超时,那么在客户端要做点处理,可以选择在打开app的时候把数据库的存储的数据找出来重新进行一下验证,或者做一个定时器什么的 多久就扫一下数据库 是否有数据要重新验证。
         */
    }





    cs
    上一篇:没有了
    下一篇:没有了