iOS内购你看我就够了(一)

内购坑多,
开始(建议先去看些入门的)

@import StoreKit;

#import "IAPManager.h"

@implementation IAPManager
+ (instancetype)sharedInstance
{
    static id sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[IAPManager alloc] init]; 
    });
    return sharedInstance;
}
单利的入口,传进来一个后台得到的商品ID(在苹果网站注册的)
- (void)payBtnPressed:(NSString *)product_id {//这传进来个商品id,lzc
    if ([SKPaymentQueue canMakePayments])//是否允许应用内付费
    {
        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:product_id]];
        request.delegate = self;
        [request start];
    }else
        DLog(@"用户不允许内购");//提示框
}

// 查询成功后的回调
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    //这里菊花消失
    DLog(@"菊花消失");
    NSArray *products = response.products;
    if (products.count != 0) {
        
        self.product = products[0];
        SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:self.product];//lzc 改
        payment.applicationUsername = @(1000000).stringValue;//充值用户的id,也就是uid.
        [[SKPaymentQueue defaultQueue] addPayment:payment];//发起购买
当然还有监听,这个东西写在程序入口比较好,至于为何下次讲
    }
    if (products.count == 0){
        DLog(@"无法获取商品");
    }
}
//查询失败后的回调
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    //菊花消失
    DLog(@"请求苹果服务器失败%@",[error localizedDescription]);
}

下边就是监听结果了

//监听购买结果,每个状态下都要结束订单,否则就坑爹了
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {//当用户购买的操作有结果时,就会触发下面的回调函数,
    //菊花消失
    DLog(@"来监听购买结果吧");
    for (SKPaymentTransaction *transaction in transactions) {
       
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased://交易成功
            
                [self completeTransaction:transaction];//验证
                //如果用户在这中间退出,咋办??不知道的看下一篇,坑坑坑都是坑
                DLog(@"结束订单了");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];//验证成功与否,咱们都注销交易,否则会出现虚假凭证信息一直验证不通过..每次进程序都得输入苹果账号的情况
                break;
                
            case SKPaymentTransactionStateFailed:
             
               
                [self failedTransaction:transaction];//交易失败方法
                break;
                
            case SKPaymentTransactionStateRestored://已经购买过该商品

                DLog(@"已经购买过");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];//消耗型不支持恢复,所以我就不写了

                break;
            case SKPaymentTransactionStatePurchasing:
                DLog(@"已经在商品列表中");//菊花
                break;
            case SKPaymentTransactionStateDeferred:
                DLog(@"最终状态未确定 ");
                break;
            default:
                break;
        }
    }
}

- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
    if(transaction.error.code != SKErrorPaymentCancelled) {
        NSLog(@"购买失败");
    } else {
        NSLog(@"用户取消交易");
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

下边就是和服务器验证凭证了,重点坑在这里

- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    if (self.cash != nil) { //self.cash这玩意我是点击商品后传进来的,所以通过它判断是不是漏单的,有他的话就走正常流程
        DLog(@"购买成功验证订单");
        NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
        NSString *a = [data base64EncodedStringWithOptions:0];
        NSLog(@"base64JSONString =---%@---",a);//得到凭证
      
        NSDictionary * dic = @{@"uid":用户id,
                               @"receipt":a,
                               还有后台要的其他东西,起码凭证和用户id是必须的吧};
        DLog(@"验证信息%@",dic);
        //存起来
        [self addDicToPayAry:dic];//先把这个信息存起到本地,这是你埋坑的第一步,有空再解释
        [self testForServer:dic];//和后台去二次验证,这个很必要
    }
else
    {
        DLog(@"漏单流程从本地取凭证去验证");
        [self checkUnTestReceipt];//从本地取凭证验证去,下篇分解
    }//不是点击cell 进来的,也就是说上次订单没结束,日狗去吧
}

服务器交互,只要服务器有反应咱就把本地的信息移除,因为验证成功删了正常,验证不成功说明凭证有假(当然也可能苹果出问题,这咱管不了了)删,咱这边服务器出毛病(我们后台说这个状态是后台验证过了但是没有发商品,用户找客服),删.
只有没和自己后台交互上的时候,我们就在本地找村过的凭证,有的话说明有没验证过的,咱继续验证.没的话(第一次也不会没,因为存过一次但是就没删过)说明都验证过了.总之这个过程不管怎么样都要结束订单.


- (void)testForServer:(NSDictionary *)dic
{
     WEAKSELF;
    [[NetWorkManager sharedInstance]postJsonData:dic url:url successBlock:^(id responseBody) {
        DLog(@"支付成功%@",responseBody);
        if ([responseBody[@"code"]isEqualToNumber:@(200)]) {
            DLog(@"1验证成功完成交易OKOKOKOK");
            if (weakSelf.paySuccessBlock){
                weakSelf.paySuccessBlock();//告诉外边UI做处理
            }
            [weakSelf removeDicFromPayAry:dic];//从本地移除凭证等信息dic
        }
        if (验证receipt-data失败) {
            DLog(@"1验证receipt-data失败");
            [weakSelf removeDicFromPayAry:dic];//移除
        }
        if (我们服务器有毛病) {
            [weakSelf removeDicFromPayAry:dic];
            DLog(@"1你去找客服吧我们服务器有毛病");
        }
        //        DLog(@"我结束订单了-----");
        
    } failureBlock:^(NSString *error) {
        DLog(@"%@和自己服务器交互失败11",error);
        [weakSelf checkUnTestReceipt];//和自己后台没联系上,所以要检查本地有没有存过的凭证,有的话继续验证.下篇详聊
    }];
}

篇幅问题,存凭证删凭证和再次验证凭证下次说.
还有订单没结束的坑(用户买成功了苹果服务器不给力,用户急脾气关应用了,订单还没结束)等等,下回分解.

8.25更,来埋坑了,点进来↓
iOS内购第二篇

感觉还是不太完美啊,先这样吧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容