1.自动订阅验证失败(21004)
自动订阅必须采用密码的方式才能进行验证;如果苹果验证返回21004的话,就加上password字段去验证。
NSMutableDictionary *parameters_M = [NSMutableDictionary dictionary];
[parameters_M setObject:encodeStr forKey:@"receipt-data"];
[parameters_M setObject:AppPurchasePwd forKey:@"password"];
然后将字典转化为json后再转化为NSData 放在请求HTTPBody里面,关于AppPurchasePwd 内购密钥的申请方式,这篇文章已经解释的很清楚,推荐大家去看一下 https://www.jianshu.com/p/abd2ba4deb54
2.内购验证返回数据 - 说明
以下是通过沙盒验证地址返回的数据
{
environment = Sandbox; //沙盒环境
"latest_receipt" = "---一大串base64数据---";
"latest_receipt_info" = ( //最新收据
{
"expires_date" = "2019-11-21 06:21:20 Etc/GMT";
"expires_date_ms" = 1574317280000;
"expires_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:16:20 Etc/GMT";
"purchase_date_ms" = 1574316980000;
"purchase_date_pst" = "2019-11-20 22:16:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595277992;
"web_order_line_item_id" = 1000000048412170;
}
);
"pending_renewal_info" = (
{
"auto_renew_product_id" = "内购产品ID";
"auto_renew_status" = 1;
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
}
);
receipt = { //收据
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = 104;
"bundle_id" = "内购产品ID";
"download_id" = 0;
"in_app" = (
{
"expires_date" = "2019-11-21 06:21:20 Etc/GMT";
"expires_date_ms" = 1574317280000;
"expires_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:16:20 Etc/GMT";
"purchase_date_ms" = 1574316980000;
"purchase_date_pst" = "2019-11-20 22:16:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595277992;
"web_order_line_item_id" = 1000000048412170;
}
);
"original_application_version" = "1.0";
"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
"original_purchase_date_ms" = 1375340400000;
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
"receipt_creation_date" = "2019-11-21 06:16:21 Etc/GMT";
"receipt_creation_date_ms" = 1574316981000;
"receipt_creation_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2019-11-21 06:16:26 Etc/GMT";
"request_date_ms" = 1574316986159;
"request_date_pst" = "2019-11-20 22:16:26 America/Los_Angeles";
"version_external_identifier" = 0;
};
status = 0;
}
验证返回字段中,“ status”字段数值为0 代表验证成功,因为自动订阅可能重视的就是到期时间,所以应该关注的是“ expires_date”、“ expires_date_ms”、“ expires_date_pst”这三个字段,expires_date表示过期时间,expires_date_ms 表示过期时间毫秒数值,expires_date_pst表示的是太平洋时间。如果英语足够好的话,这些字段也应该一目了然,英语差一点的话,也可以通过翻译清楚每一个字段代表的意思。
由于 expires_date 表示的是美国时间,所以一般都采用expires_date_ms数值来进行验证有效期,验证方法为
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[expiresDate longLongValue]/1000];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSString *the_date_str = [formatter stringFromDate:date];
- expiresDate是expires_date_ms的具体数值,值得注意的是这里dateWithTimeIntervalSince1970 方法后的参数不是直接将expiresDate转化为双精度浮点型[expiresDate doubleValue],而是 [expiresDate longLongValue]/1000],不然你得到的时间将超乎你的想象!
你以为这样就结束了,其实不然,当用户进行多次购买或者续订的时候,验证返回的数据将发生改变,其通过沙盒验证地址返回的数据如下:
{
environment = Sandbox;
"latest_receipt" = "---一大串base64数据---";
"latest_receipt_info" = (
{
"expires_date" = "2019-11-21 06:21:20 Etc/GMT";
"expires_date_ms" = 1574317280000;
"expires_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:16:20 Etc/GMT";
"purchase_date_ms" = 1574316980000;
"purchase_date_pst" = "2019-11-20 22:16:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595277992;
"web_order_line_item_id" = 1000000048412170;
},
{
"expires_date" = "2019-11-21 06:26:20 Etc/GMT";
"expires_date_ms" = 1574317580000;
"expires_date_pst" = "2019-11-20 22:26:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:21:20 Etc/GMT";
"purchase_date_ms" = 1574317280000;
"purchase_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595280033;
"web_order_line_item_id" = 1000000048412171;
},
{
"expires_date" = "2019-11-21 06:31:20 Etc/GMT";
"expires_date_ms" = 1574317880000;
"expires_date_pst" = "2019-11-20 22:31:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:26:20 Etc/GMT";
"purchase_date_ms" = 1574317580000;
"purchase_date_pst" = "2019-11-20 22:26:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595283022;
"web_order_line_item_id" = 1000000048412281;
},
{
"expires_date" = "2019-11-21 06:36:20 Etc/GMT";
"expires_date_ms" = 1574318180000;
"expires_date_pst" = "2019-11-20 22:36:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:31:20 Etc/GMT";
"purchase_date_ms" = 1574317880000;
"purchase_date_pst" = "2019-11-20 22:31:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595285412;
"web_order_line_item_id" = 1000000048412441;
},
{
"expires_date" = "2019-11-21 06:41:20 Etc/GMT";
"expires_date_ms" = 1574318480000;
"expires_date_pst" = "2019-11-20 22:41:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:36:20 Etc/GMT";
"purchase_date_ms" = 1574318180000;
"purchase_date_pst" = "2019-11-20 22:36:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595289391;
"web_order_line_item_id" = 1000000048412586;
},
{
"expires_date" = "2019-11-21 06:46:20 Etc/GMT";
"expires_date_ms" = 1574318780000;
"expires_date_pst" = "2019-11-20 22:46:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:41:20 Etc/GMT";
"purchase_date_ms" = 1574318480000;
"purchase_date_pst" = "2019-11-20 22:41:20 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595292096;
"web_order_line_item_id" = 1000000048412737;
},
{
"expires_date" = "2019-11-21 08:21:13 Etc/GMT";
"expires_date_ms" = 1574324473000;
"expires_date_pst" = "2019-11-21 00:21:13 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 07:21:13 Etc/GMT";
"purchase_date_ms" = 1574320873000;
"purchase_date_pst" = "2019-11-20 23:21:13 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20569938;
"transaction_id" = 1000000595319377;
"web_order_line_item_id" = 1000000048412870;
}
);
"pending_renewal_info" = (
{
"auto_renew_product_id" = "内购产品ID";
"auto_renew_status" = 1;
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
}
);
receipt = {
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = 104;
"bundle_id" = "内购产品ID";
"download_id" = 0;
"in_app" = (
{
"expires_date" = "2019-11-21 06:21:20 Etc/GMT";
"expires_date_ms" = 1574317280000;
"expires_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:16:20 Etc/GMT";
"purchase_date_ms" = 1574316980000;
"purchase_date_pst" = "2019-11-20 22:16:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595277992;
"web_order_line_item_id" = 1000000048412170;
},
{
"expires_date" = "2019-11-21 06:26:20 Etc/GMT";
"expires_date_ms" = 1574317580000;
"expires_date_pst" = "2019-11-20 22:26:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:21:20 Etc/GMT";
"purchase_date_ms" = 1574317280000;
"purchase_date_pst" = "2019-11-20 22:21:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595280033;
"web_order_line_item_id" = 1000000048412171;
},
{
"expires_date" = "2019-11-21 06:31:20 Etc/GMT";
"expires_date_ms" = 1574317880000;
"expires_date_pst" = "2019-11-20 22:31:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:26:20 Etc/GMT";
"purchase_date_ms" = 1574317580000;
"purchase_date_pst" = "2019-11-20 22:26:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595283022;
"web_order_line_item_id" = 1000000048412281;
},
{
"expires_date" = "2019-11-21 06:36:20 Etc/GMT";
"expires_date_ms" = 1574318180000;
"expires_date_pst" = "2019-11-20 22:36:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:31:20 Etc/GMT";
"purchase_date_ms" = 1574317880000;
"purchase_date_pst" = "2019-11-20 22:31:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595285412;
"web_order_line_item_id" = 1000000048412441;
},
{
"expires_date" = "2019-11-21 06:41:20 Etc/GMT";
"expires_date_ms" = 1574318480000;
"expires_date_pst" = "2019-11-20 22:41:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:36:20 Etc/GMT";
"purchase_date_ms" = 1574318180000;
"purchase_date_pst" = "2019-11-20 22:36:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595289391;
"web_order_line_item_id" = 1000000048412586;
},
{
"expires_date" = "2019-11-21 06:46:20 Etc/GMT";
"expires_date_ms" = 1574318780000;
"expires_date_pst" = "2019-11-20 22:46:20 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 06:41:20 Etc/GMT";
"purchase_date_ms" = 1574318480000;
"purchase_date_pst" = "2019-11-20 22:41:20 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595292096;
"web_order_line_item_id" = 1000000048412737;
},
{
"expires_date" = "2019-11-21 08:21:13 Etc/GMT";
"expires_date_ms" = 1574324473000;
"expires_date_pst" = "2019-11-21 00:21:13 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-21 06:16:21 Etc/GMT";
"original_purchase_date_ms" = 1574316981000;
"original_purchase_date_pst" = "2019-11-20 22:16:21 America/Los_Angeles";
"original_transaction_id" = 1000000595277992;
"product_id" = "内购产品ID";
"purchase_date" = "2019-11-21 07:21:13 Etc/GMT";
"purchase_date_ms" = 1574320873000;
"purchase_date_pst" = "2019-11-20 23:21:13 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000595319377;
"web_order_line_item_id" = 1000000048412870;
}
);
"original_application_version" = "1.0";
"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
"original_purchase_date_ms" = 1375340400000;
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
"receipt_creation_date" = "2019-11-21 07:21:14 Etc/GMT";
"receipt_creation_date_ms" = 1574320874000;
"receipt_creation_date_pst" = "2019-11-20 23:21:14 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2019-11-21 07:21:16 Etc/GMT";
"request_date_ms" = 1574320876419;
"request_date_pst" = "2019-11-20 23:21:16 America/Los_Angeles";
"version_external_identifier" = 0;
};
status = 0;
}
看到这些数据其实我内心是拒绝的!当latest_receipt_info集合存在多个数值的时候,如果你只拿latest_receipt_info 集合里面的第一个字典进行验证的话,你得到的会员将永远是过期的,这坑不大不小,还是的踩啊!通过时间排查,你会发现其实只有最后一个字典是有效的,也就是说最后一个字典的expires_date_ms 大于当前时间,而且苹果内购订阅自带拦截,会员没到期是不能进行再次购买!所以取数字的时候记得 取NSArray 的lastObject(最后一个字典)
-
当然这里还有一个坑是在沙盒环境下时间缩短
所以当自己看见过期时间很短时,请不要认为是自己代码下的有问题
3.订阅有效期和过期时间验证
即使拿到最后一个数据,也是需要进行过期时间验证,因为内购还有一个功能叫恢复购买,验证方法也简单,就将两个时间进行对比即可
NSDate *new = [NSDate date];
NSTimeInterval timeBetween = [date timeIntervalSinceDate:new];
date 代表过期时间
4.总结
当然如果有服务器支持的话,我们只需要把base64数据传给服务器,让服务器来帮忙验证,并不需要客服端计算过期时间。但内购自动订阅本身就不需要App进行用户登陆来购买,也不支持跨 Apple ID 进行消费,所以我们采用了本地验证的方式!
感谢下列网站提供的帮助: