当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS-内购的那些事(漏单的问题)

iOS-内购的那些事(漏单的问题)

2018年09月05日  | 移动技术网IT编程  | 我要评论

丹泽尔华盛顿电影,96135商旅网,沙漏3饶雪漫

前言

说起内购,其实挺令开发者厌烦的,原因呢,先不说漏单的问题,首先苹果要扣除30%的销售额哦,可恨不?(我觉得可恨),有些想办法先隐藏掉第三方支付(支付宝、微信等),等项目上线了,再跳过内购使用第三方支付,emmmm.......这个方法确实不错,但是如果被苹果发现了,app内虚拟产品调用第三方支付,那好吧,直接下架吧(或许没这么惨,但会惨不忍睹),不要说发现不了,会有人举报哦(别问我怎么知道的);其次就是漏单问题的处理,这一直是个问题,我的项目里虽然做了处理,但是还是会避免不了漏单的,只是把漏单的几率降到了很小,以确保我们维护,给大家分享下内购及漏单的处理。

 

内购集成

内购集成并不难,这里我用了一个git上封装好的(iaphelper),自己封装也简单(不想造那么多轮子了),封装的话,建议结合单例封装,充值验证都在单例里面进行;当然也可以不封装直接就用的,这里不多说了。

支付逻辑

1.临时单号

首先根据内购商品id(此商品id是在苹果后台建好的内购商品)、用户信息(后台要求),传给服务器获取一个临时单号,然后先将该临时单号保存到一个变量里。 

///获取充值临时单号
- (void)iapgettemorderidwithproductid:(nsstring *)productid{
    self.productid = productid;
    [svprogresshud showwithstatus:@"请稍后..." ];
    nsstring *urlstring = @"";
    [httptools gethttprequesturl:urlstring requestsuccess:^(id repoes, nsurlsessiondatatask *task) {
        [svprogresshud dismiss];
        nsdictionary *dictem = [httptools respoestodic:repoes];
        if ([dictem[@"code"] integervalue] == 1) {
            ///保存临时单号
             self.temporaryorderid = dictem[@"data"];
             ///发起内购支付
             [self iapstartrecharge];
            
        }
        else{
            [svprogresshud showerrorwithstatus:dictem[@"errmsg"]];
            [self errorpost:nil];
        }
        
    } requestfaile:^(nserror *error) {
        [svprogresshud showerrorwithstatus:[httptools error:error]];
        [self errorpost:nil];
    }];
}

 

2.苹果充值

通过商品id调取苹果内购支付,苹果充值成功后,在返回成功的方法里,首先将上一步中的临时单号、用户信息(这里我取userid)、苹果充值成功返回的data,三个参数一起存入本地(我采用数据库存储)后,然后验证服务器充值(如果苹果充值验证失败,不必做任何操作)。

///发起内购支付
- (void)iapstartrecharge{
    [svprogresshud showwithstatus:@"请稍后..."];
    nsset* dataset = [[nsset alloc] initwithobjects:self.productid, nil];
    [iapshare sharedhelper].iap = [[iaphelper alloc] initwithproductidentifiers:dataset];
    // 请求商品信息
    [[iapshare sharedhelper].iap requestproductswithcompletion:^(skproductsrequest* request,skproductsresponse* response){
        
        if(response.products.count > 0 ) {
            skproduct *product = response.products[0];
            [[iapshare sharedhelper].iap buyproduct:product oncompletion:^(skpaymenttransaction* trans){
                if(trans.error){
                    [svprogresshud showerrorwithstatus:trans.error.userinfo.allvalues[0]];
                    [self errorpost:nil];
                }
                else if(trans.transactionstate == skpaymenttransactionstatepurchased) {
                    nslog(@"*********内部支付成功*********");
                    
                    ///将临时单号存在本地【此处做返回信息保存(临时单号、用户信息、返回的data)】
                    
                    ///去服务器验证充值
                }
                else if(trans.transactionstate == skpaymenttransactionstatefailed) {
                    nslog(@"*********支付失败*********");
                    if (trans.error.code == skerrorpaymentcancelled) {
                    }
                    else if (trans.error.code == skerrorclientinvalid) {
                    }
                    else if (trans.error.code == skerrorpaymentinvalid) {
                    }
                    else if (trans.error.code == skerrorpaymentnotallowed) {
                    }
                    else if (trans.error.code == skerrorstoreproductnotavailable) {
                    }
                    else{
                    }
                    [svprogresshud showerrorwithstatus:trans.error.userinfo.allvalues[0]];
                    [self errorpost:nil];
                }
            }];
        }else{
            //  ..未获取到商品
            [svprogresshud showerrorwithstatus:@"暂未获取到商品"];
            [self errorpost:nil];
        }
    }];
}

 

3.服务器验证充值(上一步成功后验证)

在苹果充值成功后,根据充值成功返回的数据data、临时单号、用户信息(后台要求)去服务器验证充值,如果验证成功,将上一步存在本地数据库的数据(临时单号、用户信息(这里我取userid)、苹果充值成功返回的data)删除;如果充值失败,即为漏单,但是已经将验证服务器充值的数据存在了本地数据库,可再次尝试,或者稍候尝试,根据自己的提示操作而定。

///向服务器验证进行充值
- (void)iappayovaliddata:(nsstring *)strreceipt temorder:(nsstring *)temorder{
    ///验证充值
    [svprogresshud showwithstatus:@"正在为您充值..."];
    nsstring *urlsting = @"";
    ///post data【验证参数】
    nsmutabledictionary *dicpost = [nsmutabledictionary dictionary];
    [httptools posthttprequesturl:urlsting requestpram:dicpost requestsuccess:^(id respoes) {
        [svprogresshud dismiss];
        nsdictionary *dicvalid = [httptools respoestodic:respoes];
        if ([dicvalid[@"code"] integervalue] == 1) {
///删除本地存的验证信息【临时单号、用户信息、苹果支付成功返回的data】 } else{ [self errorpost:dicvalid[@"errmsg"]]; } } requestfaile:^(nserror *erro) { [svprogresshud dismiss]; [self errorpost:[httptools error:erro]]; }]; }

 

结束

至此,整个内购充值流程已完毕,以上传递的参数、存储的参数,是根据服务器后台要求,可根据自己服务器后台商量,怎么做更好,如果大家有更好的方案,希望能借鉴!谢谢!

最后还是要说说,不管怎么做漏单处理,总会有几个漏单的,但是几率很小,而且还想说,什么时候可以有办法躲过这30%的抽成.......

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网