美文网首页
支付篇——内购(IAP)详解

支付篇——内购(IAP)详解

作者: iOS祎 | 来源:发表于2018-10-31 10:06 被阅读15次

    流程

    1.注册app,填写协议、税务和银行业务

    注册app,需要唯一设置Bundle identifier,然后详细填写协议、税务和银行业务,此个步骤这里就不在写了

    (【官方地址】(https://developer.apple.com/library/archive/technotes/tn2259/_index.html#//apple_ref/doc/uid/DTS40009578))。

    2.内购商品的添加

    我的App—>准提交的项目—>功能—>App内购买项目:添加内购商品信息

    3.添加沙盒测试账号

    iTunes Connect —>用户和职能 —>沙盒测试技术员:添加沙盒测试账号

    4.代码实现过程

    写了一个购买的单例

    @protocol VistaInAppPurchaseManagerDelegate <NSObject>
    //接收到商品信息
    -(void)receiveProductInfo:(SKProduct *)product;
    //购买成功反馈
    -(void)successfulPurchaseOfId:(NSString *)productID andReceipt:(NSData *)transactionReceipt;
    //购买失败反馈
    -(void)failedPurchaseWithError:(NSString *)errorDescripiton;
    @end
    
    @interface VistaInAppPurchaseManager : NSObject
    @property (nonatomic, weak)id delegate;
    //单例
    +(instancetype)sharedInstance;
    /*
     *  请求商品信息,productID 商品ID
    */
    -(void)requestProductWithID:(NSString *)productID;
    /*
     * 购买商品
     */
    -(BOOL)purchaseProudct:(SKProduct *)skProduct;
    @end
    //
    //  VistaInAppPurchaseManager.m
    //  vista.homework
    //
    //  Created by htkj on 2018/9/17.
    //  Copyright © 2018年 vista. All rights reserved.
    //
    
    #import "VistaInAppPurchaseManager.h"
    
    @interface VistaInAppPurchaseManager ()<SKProductsRequestDelegate, SKPaymentTransactionObserver>
    
    
    @end
    
    @implementation VistaInAppPurchaseManager
    {
        SKProduct *myProduct;
    
    }
    
    
    static VistaInAppPurchaseManager *manager = nil;
    
    +(instancetype)sharedInstance{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (manager == nil) {
                manager = [[VistaInAppPurchaseManager alloc]init];
            }
    
        });
        return manager;
    }
    
    #pragma mark ------  public Methods
    -(void)requestProductWithID:(NSString *)productID{
        if (productID.length > 0) {
            SKProductsRequest *productRequest = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithObject:productID]];
            productRequest.delegate = self;
            [productRequest start];
    
        }else{
    
            NSLog(@"productID为空");
        }
    
    
    }
    
    -(BOOL)purchaseProudct:(SKProduct *)skProduct{
    
        if (skProduct != nil) {
            if ([SKPaymentQueue canMakePayments]) {
                SKPayment *payment = [SKPayment paymentWithProduct:skProduct];
                [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
                [[SKPaymentQueue defaultQueue] addPayment:payment];
                return YES;
            }else{
                NSLog(@"失败,用户禁止应用内付费购买.");
            }
        }
        return NO;
    }
    
    #pragma mark ------  SKProductsRequestDelegate
    
    -(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
        NSArray *productArr = response.products;
        if (productArr.count > 0) {
            myProduct = [productArr objectAtIndex:0];
            [_delegate receiveProductInfo:myProduct];
        }else{
            NSLog(@"无法购买商品信息,购买失败");
            [_delegate receiveProductInfo:myProduct];
        }
    }
    
    #pragma mark ------  SKPaymentTransactionObserver
    
    -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
        for (SKPaymentTransaction *transaction in transactions) {
            switch (transaction.transactionState) {
                case SKPaymentTransactionStatePurchasing://商品添加进列表
                    NSLog(@"商品:%@被添加进购买列表",myProduct.localizedTitle);
                    break;
                case SKPaymentTransactionStatePurchased://交易成功
                    [self completeTransaction:transaction];
                    break;
                case SKPaymentTransactionStateFailed://交易失败
                    [self failedTransaction:transaction];
                    NSLog(@"交易失败");
                    //发送通知
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"failNotification" object:self userInfo:nil];
                    break;
                case SKPaymentTransactionStateRestored://已购买过该商品
                    break;
    
                    case SKPaymentTransactionStateDeferred://交易延迟
                default:
                    break;
            }
        }
    }
    
    
    #pragma mark ---- private Methods
    
    -(void)completeTransaction:(SKPaymentTransaction *)transaction{
        NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
        NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
        [_delegate successfulPurchaseOfId:transaction.payment.productIdentifier andReceipt:receiptData];
    //   [[NSUserDefaults standardUserDefaults] setObject:receiptData forKey:@"receiptData"];
    //    [[NSUserDefaults standardUserDefaults] synchronize];
        [[SKPaymentQueue defaultQueue]finishTransaction:transaction];
    }
    
    - (void)failedTransaction:(SKPaymentTransaction *)transaction{
        if (transaction.error.code != SKErrorPaymentCancelled && transaction.error.code != SKErrorUnknown) {
            [_delegate failedPurchaseWithError:transaction.error.localizedDescription];
        }
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
    
    -(void)dealloc{
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }
    
    @end
    

    导入单例
    import “VistaInAppPurchaseManager.h”
    设置代理
    VistaInAppPurchaseManagerDelegate
    点击充值按钮事件

    -(void)commitBtnClick{
        [self createhui];
        [MBProgressHUD showLoadToView:self.view title:@"支付中,请勿关闭App"];
        NSString *productID = nil;
        switch (purchaseType) {
            case 0:
                productID = @"Vista_coin_1";
                break;
            case 1:
                productID = @"Vista_coin_6";
                break;
            case 2:
                productID = @"Vista_coin_18";
                break;
            case 3:
                productID = @"Vista_coin_30";
                break;
            case 4:
                productID = @"Vista_coin_68";
                break;
            case 5:
                productID = @"Vista_coin_108";
                break;
            case 6:
                productID = @"Vista_coin_208";
                break;
            case 7:
                productID = @"Vista_coin_388";
                break;
            case 8:
                productID = @"Vista_coin_698";
                break;
            default:
                break;
        }
        if (productID == nil) {
            Hidden
            return;
        }
        [self.payManager requestProductWithID:productID];
    }
    

    代理方法

    #pragma mark -----   VistaInAppPurchaseManagerDelegate
    //购买商品回调
    -(void)receiveProductInfo:(SKProduct *)product{
        Hidden
        if (product != nil) {
            if (![self.payManager purchaseProudct:product]) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"失败" message:@"您禁止了应用内购买权限,请到设置中开启" delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:nil, nil];
                [alert show];
            }
            NSLog(@"SKProduct 描述信息%@", [product description]);
            NSLog(@"产品标题 %@" , product.localizedTitle);
            NSLog(@"产品描述信息: %@" , product.localizedDescription);
            NSLog(@"价格: %@" , product.price);
            NSLog(@"Product id: %@" , product.productIdentifier);
        }else{
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"失败" message:@"无法连接App store!" delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:nil, nil];
            [alert show];
        }
         [self hidden];
    }
    #pragma mark-VistaInAppPurchaseManagerDelegate
    //成功回调
    //附加:官方文档:向苹果校验支付结果https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
    -(void)successfulPurchaseOfId:(NSString *)productID andReceipt:(NSData *)transactionReceipt{
        NSString *transactionReceiptString = [transactionReceipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        NSDictionary *dict = @{@"receipt-data":transactionReceiptString};
        NSString *str=[self conData11:dict];
        //上传支付凭证到后台
            NSDictionary *json = @{@"receipt":str};
            NSDictionary *Json=@{@"code":@"5077",@"payload":[HHCommon convertToJsonData:json],@"token":personalToken};
            [HTTPRequestManager postNetworkRequestWithUrlString:Com parameters:Json succeed:^(id data) {
                if ([data[@"code"] integerValue]==0&&[data[@"payload"][@"status"] integerValue]==0) {
                     [PHAlertView showTitle:@"充值成功!" message:@"" surnBtnTitle:@"确定" result:nil];
                    [self loadmoney];
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"receiptData"];
                }else{
                    NSLog(@"%@",data[@"message"]);
                }
            } fail:^(NSError *error) {
    
            }];
    }
    //失败回调
    - (void)failedPurchaseWithError:(NSString *)errorDescripiton {
        NSLog(@"购买失败");
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"失败" message:errorDescripiton delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:nil, nil];
        [alert show];
    
    }
    

    相关文章

      网友评论

          本文标题:支付篇——内购(IAP)详解

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