iOS内购小总结(代码块)

一:内购逻辑流程图


pay1.png
pay2.png

二:代码部分

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"购买页面";
      self.navigationItem.rightBarButtonItem = [self rightBarButtonWithName:NSLocalizedString(@"07-restore", nil) target:self action:@selector(restonreProduct)];
    [self BuildUI];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
#pragma mark -- 购买按钮事件
-(void)buycommodity {

        if ([SKPaymentQueue canMakePayments]) {
            [self RequestProductData];
            //        NSLog(@"允许程序内付费购买");
        }
        else
        {
            //        NSLog(@"不允许程序内付费购买");
            [self MarkToViewString:NSLocalizedString(@"09-noOpenApplications", nil)];
        }
}
-(void)RequestProductData
{
//    NSLog(@"---------请求对应的产品信息------------");
    NSArray *product = nil;
    product=[[NSArray alloc] initWithObjects:ProductID,nil];
    NSSet *nsset = [NSSet setWithArray:product];
    SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
    request.delegate=self;
    [request start];
}
//<SKProductsRequestDelegate> 请求协议
//收到的产品信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
//    NSLog(@"-----------收到产品反馈信息--------------");
    NSArray *myProduct = response.products;
    if([myProduct count] == 0){
        [SVProgressHUD dismiss];
//        NSLog(@"--------------没有商品------------------");
        return;
    }
    SKProduct *P = nil;
    for(SKProduct *product in myProduct){
//        NSLog(@"product info");
//        NSLog(@"SKProduct 描述信息%@", [product description]);
//        NSLog(@"产品标题 %@" , product.localizedTitle);
//        NSLog(@"产品描述信息: %@" , product.localizedDescription);
//        NSLog(@"价格: %@" , product.price);
//        NSLog(@"Product id: %@" , product.productIdentifier);
        if ([product.productIdentifier isEqualToString:ProductID]) {
            P = product;
        }
    }
    SKPayment *payment = nil;
    payment = [SKPayment paymentWithProduct:P];
//    NSLog(@"---------发送购买请求------------");
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}
//监听购买结果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
    
    for(SKPaymentTransaction *tran in transaction){
        
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased:{
//         NSLog(@"交易完成");
              [self checkTransaction:tran];//去验证
            }
                break;
            case SKPaymentTransactionStatePurchasing:
              //  NSLog(@"商品添加进列表");
                break;
            case SKPaymentTransactionStateRestored:{
              //  NSLog(@"已经购买过商品");
                [self restoreTransaction:tran];
            }
                break;
            case SKPaymentTransactionStateFailed:{
             //  NSLog(@"交易失败");
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                [SVProgressHUD showErrorWithStatus:@"购买失败"];
            }
                break;
            default:
                break;
        }
    }
}

验证前检查看看是否有未完成订单

#pragma mark --检查本次支付信息,并与本地缓存信息对比,查看是否是未完成订单
- (void)checkTransaction:(SKPaymentTransaction *)transaction{

    NSDictionary *saveDic = [[NSDictionary alloc]init];
    saveDic = [DDKeychain keyChainLoad];
    if (saveDic != nil) {
       //取自支付队列未完成的商品ID去缓存中拿对应的信息.有就去验证
        [self connetServerWithTransactionandPayInfo:transaction];
        return;
    }else{
        //全新的支付
        NSDictionary *newPayInfoDic = @{@"product_id":ProductID,
                                        @"apple_orderid":transaction.transactionIdentifier};
        /** 已Keychain将数据存起来 */
        [self setOrderData:newPayInfoDic key:ProductID];
        /** 服务器验证 */
        [self connetServerWithTransactionandPayInfo:transaction];
    }
}
#pragma mark -- server验证
- (void)connetServerWithTransactionandPayInfo:(SKPaymentTransaction *)transaction{
    //从沙盒中获取交易凭证并且拼接成请求体数据
    NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];
    NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//交易凭证转化为base64字符串
//    /** 商品id 订单号 苹果的订单号 传给 后台(看你们后台要求)*/

    /*
     1.调用服务器接口验证成功一定要删除keyChain存储的数据
     2. [[SKPaymentQueue defaultQueue]finishTransaction:transaction];

     */
}

非消耗商品苹果需要提供恢复购买按钮,在已经购买过商品调用恢复购买处理

#pragma mark -- 恢复购买
- (void)restonreProduct{

    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@" 交易恢复处理");
    [self checkTransaction:transaction];//去验证

}

内购基本完成,我项目审核已通过!

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

推荐阅读更多精彩内容

  • 最近开发一个项目涉及到内购, 也遇到过一些问题. 这里拿出来分享一下, 避免一些人走弯路.开头先聊一聊最近苹果关于...
    东方_未明阅读 6,155评论 16 56
  • iOS内购流程: iOS内购 什么时候用到呢? 虚拟产品就需要用到iOS内购;购买的商品,是在本app中...
    会跳舞的狮子阅读 2,707评论 5 24
  • iOS应用如果涉及到支付功能,分为两类:第三方支付和苹果内购。那么什么情况下选择使用第三方支付,又在什么情况下选择...
    ZfRee阅读 38,675评论 36 66
  • 这几天在开发unity游戏的时候想接入ios的内购系统,所以网上查了一些有关的资料和教程。里面的东西比较全面,但也...
    蜜桃邂逅阅读 6,127评论 29 20
  • 这两天不知是不是天热的原因,不想动,也没有往外跑,在家舒舒服服的喝茶,买东西,看攻略,睡觉,最有成就是调理自己的膝...
    misang阅读 187评论 0 6