iOS内购之二次验证

开篇:关于iOS内购整体流程网上能找到很多。我抽丝剥茧,着重说一下二次验证及收据回传的数据问题。

二次验证

关于二次验证,其实有两种做法,第一种是在app端验证,第二种也是安全防盗的一种,在服务端进行验证。
具体区别不一一表述,可以查看下面的链接。
iOS二次验证两种做法的区别
我要着重说的是二次验证的实际做法和收到的数据是什么。

一、二次验证具体如何验证

在这分为测试地址和实际上线地址
测试:https://sandbox.itunes.apple.com/verifyReceipt
已上线Appstore:https://buy.itunes.apple.com/verifyReceipt
在沙箱测试时,我们使用测试地址。

// 从沙盒中获取交易凭证(收据)
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    
// 转化为base64字符串
NSString *receiptString = [receiptData base64EncodedStringWithOptions:0];

为了方便拿到数据,我们在app端上进行验证,注意⚠️实际开发中都是在服务端进行验证的。

// 拼接请求数据
NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];
NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];

// 创建请求到苹果官方进行购买验证
NSURL *url = [NSURL URLWithString:verifyReceipt_url];
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
requestM.HTTPBody = bodyData;
requestM.HTTPMethod = @"POST";

// 创建连接并发送同步请求
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];

if (error) {
    NSLog(@"验证购买过程中发生错误,错误信息:%@",error.localizedDescription);
    return;
}

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];

二、收据回传得到的数据分析

上文得到的dic就是我们通过收据得到的所有数据
在这里有个坑,我相信有很多同学都踩过。
就是你支付成功了,但是在这个数组里却找不到你想要的数据。
我们可以看下面一张图,然后再分析分析。


iOS内购之二次验证_第1张图片
内购类型.png

可以看到有四种类型,但是具体到我们项目中我们该如何选择和操作呢。

1.消耗型:比如我们游戏里的金币,6元600个金币,你使用完了就失效了。比如现在各大视频app推出的电影购买,6元买完一张影片之后,你如果想买下一张影片就必须再次购买。
2.非消耗型:比如某app推出永久会员,购买一次终身使用,就是非消耗型。再比如游戏过关时app的某关,你一直过不去,花钱购买过去了,等你下次再打开app时,他这关默认是已经通过的。
3.自动续订型:具体可以看爱奇艺视频开通会员(腾讯app也类似),里面就有一个自动续订会员。也就是到期了,它会自动从你的苹果账号上扣钱。这个慎点慎点,他们这样搞很坑钱。
4.非自动续订型:这个就是1个月优酷会员啦,或者3个月季度会员啥的。有期限,到期时也不会自动扣钱。一般的都是选择这个,不然像爱奇艺的自动续订,用户不知情时,会被骂死,哈哈

说了这么多,来看看订单数据长啥样

{
    product_id = "lalalalahahaha",//商品的标识,和产品定,随便写但是不能重复
    quantity = "1",//购买商品的数量
    transaction_id = "1000000357637984",//交易的标识
    purchase_date_ms = "1512613065000",//购买时间毫秒
    original_purchase_date_pst = "2017-12-06 18:17:45 America/Los_Angeles",//购买时间,太平洋标准时间
    purchase_date_pst = "2017-12-06 18:17:45 America/Los_Angeles",//太平洋标准时间
    original_purchase_date_ms = "1512613065000",//毫秒
    is_trial_period = "false",
    original_purchase_date = "2017-12-07 02:17:45 Etc/GMT",//原始购买时间
    original_transaction_id = "1000000357637984",//原始交易ID
    purchase_date = "2017-12-07 02:17:45 Etc/GMT"//购买时间
},

我们得到的字典里如果有多条数据,就会有一个数组in_app。
如果只有一条数据,或者没有数据,就没有in_app。
in_app里的数据格式就如上文代码所书。

所有的订单信息都在in_app里。所以我们要找到最新成功的那条数据,就需要在这里面去找。

注:
1.消耗性的和其他的有区别,消耗性的下一次购买的,会覆盖上一次购买的,所以只有一条消耗性的订单信息,当然也是最新的。
2.其他三种每次购买,都会生成新的订单信息,不会覆盖原来的,所以你购买多少次,上面就会显示多少条。

三、内购二次验证实际开发中具体做法

1.我们把收据信息传给服务器
2.服务器自行处理所有的订单信息,返回一个成功与失败的状态给我们。所有的操作,后台都已经记录在案了,我们不再需要管。我们只需要知道,此次购买是否成功就行了。

结语:内购其实很简单,只是有时候不经意就会入坑,在此特意记录下困惑的地方,帮助自己深刻记忆,也希望帮助到其他遇到该问题的童鞋。

你可能感兴趣的:(iOS内购之二次验证)