一、iOS & MacOS票据
MacOS相关
-
App的沙盒目录:
~/Libraray/Containers/xxx(xxx=bundleID)
。 -
票据为空原因
:Mac App开发过程中打包为AppStore包,形成dmg.
一定要拖到/Application中
。放在其他目录打开dmg做IAP支付,苹果支付成功后,获取receipt是获取不到的。 -
MacOS票据的位置:
efdb6399-1efd-4a16-8af3-46efad265604.png/Application/xxx.app/Contents中
,应用程序的bundle里中
iOS 相关
票据的位置:沙盒数据文件中。StoreKit文件夹下
二、验证方式
两种方式:本地验证和服务端验证,推荐服务端验证
。
-
采用
服务端验证
,涉及苹果服务稳定性和超时的问题
。对于验证接口超时,实际开发过程中,10s
也是常见的,3s~6s
不可取。 -
本地验证(一般使用
OpenSSL
),比如RMStore。- 实际过程中发现,
本地验证解析出的票据字段
没有服务端验证
全,但足以够用。 - ❗️❗️❗️:本地验证的安全性的问题不得而知,若有同学知道,可讨论一下;
- 实际过程中发现,
三、服务端验证
这里仅模拟请求,复杂业务逻辑不涉及.
- 从iOS 7开始,苹果的收据不是每笔交易一个收据,而是将所有的交易数据组成一个集合放在沙盒中,然后我们在沙盒中取到的数据是当前所有收据的集合,而且我们也不知道当前收据里都有哪些订单,我们的后台也不知道,只有IAP服务器知道。所以,我们不用管收据里的数据,只要拿出来怼给后台,后台再怼给苹果就可以了。
- 二次验证:先请求正式环境,返回21007,再去沙盒环境验证.
原因:
1.App Store审核时使用沙盒购买,此时应该去沙盒环境验证,
但是区分不了App是否审核过
2.为了线上用户的使用.
(三.一)验证代码
#pragma mark - 苹果票据验证
//沙盒测试环境验证
#define IAPVerifyReceiptSandboxAPI @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式环境验证
#define IAPVerifyReceiptProxAPI @"https://buy.itunes.apple.com/verifyReceipt"
-(void)verifyPurchaseWithProductionEnvironment{
//从沙盒中获取交易凭证并且拼接成请求体数据
NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];
NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//转化为base64字符串
//自动续费需要password:@"{\"receipt-data\" : \"%@\" , \"password\":\"5b5c3dxxww4fxxxxxxxxxxxxx\"}"
NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];//拼接请求数据
NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
/*
注意:
自己测试的时候使用的是沙盒购买(测试环境)
App Store审核的时候也使用的是沙盒购买(测试环境)
上线以后就不是用的沙盒购买了(正式环境)
所以此时应该先验证正式环境,在验证测试环境
正式环境验证成功,说明是线上用户在使用
正式环境验证不成功返回21007,说明是自己测试或者审核人员在测试
*/
//第一步,验证正式环境
//创建请求到苹果官方进行购买验证(正式环境)
NSURL *url=[NSURL URLWithString: IAPVerifyReceiptProxAPI];
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];
NSLog(@"%@",dic);
if([dic[@"status"] intValue]==0){
//正式环境验证通过(说明是上线以后的用户购买)
NSLog(@"购买成功!");
//在此处对购买记录进行存储,可以存储到开发商的服务器端
}else if([dic[@"status"] intValue]== 21007){
//This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
//购买凭证来自于测试环境,但是却发送到了正式环境,请改成测试环境(这种情况下可能是自己测试的,也可能是审核人员测试的)
//第二步,验证测试环境
[self verifyPurchaseWithTestEnvironment:bodyData];
}
}
//创建请求到苹果官方进行购买验证(测试环境)
- (void)verifyPurchaseWithTestEnvironment:(NSData *)bodyData {
NSURL *url=[NSURL URLWithString:IAPVerifyReceiptSandboxAPI];
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];
NSLog(@"%@",dic);
if([dic[@"status"] intValue]==0){
NSLog(@"购买成功!");
//在此处对购买记录进行存储,可以存储到开发商的服务器端
}else{
NSLog(@"购买失败,未通过验证!");
}
}
(三.二) 返回结果
包含的字段:
status
receipt
latest_receipt:只有包含自动续费订阅时才返回该字段。
latest_receipt_info:只有包含自动续费订阅时才返回该字段。
latest_expired_receipt_info:只有包含自动续费订阅时才返回该字段。
pending_renewal_info:只有包含自动续费订阅时才返回该字段。
is-retryable
environment:内购环境。
bundle_id:APP包名。
application_version:版本。
in_app: 支付成功返回的数据,未支付成功也会返回JSON,但一定没有这个参数。
示例
{
environment = Sandbox;
"latest_receipt" = "GUrzAfew6QnuSUoqUyMdiwqT+IVi3BYFaIqsRjQ==";
"latest_receipt_info" = (
{
"expires_date" = "2019-11-12 12:57:16 Etc/GMT";
"expires_date_ms" = 1573563436000;
"expires_date_pst" = "2019-11-12 04:57:16 America/Los_Angeles";
"is_in_intro_offer_period" = true;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 12:52:16 Etc/GMT";
"purchase_date_ms" = 1573563136000;
"purchase_date_pst" = "2019-11-12 04:52:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000222230013;
"web_order_line_item_id" = 1000000012345688;
},
{
"expires_date" = "2019-11-12 13:02:16 Etc/GMT";
"expires_date_ms" = 1573563736000;
"expires_date_pst" = "2019-11-12 05:02:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 12:57:16 Etc/GMT";
"purchase_date_ms" = 1573563436000;
"purchase_date_pst" = "2019-11-12 04:57:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 1000000222230013;
"transaction_id" = 1000000222233337;
"web_order_line_item_id" = 1000000012345678;
},
{
"expires_date" = "2019-11-12 13:07:16 Etc/GMT";
"expires_date_ms" = 1573564036000;
"expires_date_pst" = "2019-11-12 05:07:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:02:16 Etc/GMT";
"purchase_date_ms" = 1573563736000;
"purchase_date_pst" = "2019-11-12 05:02:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000222233338;
"web_order_line_item_id" = 1000000012345677;
},
{
"expires_date" = "2019-11-12 13:12:16 Etc/GMT";
"expires_date_ms" = 1573564336000;
"expires_date_pst" = "2019-11-12 05:12:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:07:16 Etc/GMT";
"purchase_date_ms" = 1573564036000;
"purchase_date_pst" = "2019-11-12 05:07:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000222233330;
"web_order_line_item_id" = 1000000012345676;
},
{
"expires_date" = "2019-11-12 13:17:16 Etc/GMT";
"expires_date_ms" = 1573564636000;
"expires_date_pst" = "2019-11-12 05:17:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:12:16 Etc/GMT";
"purchase_date_ms" = 1573564336000;
"purchase_date_pst" = "2019-11-12 05:12:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000222233332;
"web_order_line_item_id" = 1000000012345674;
},
{
"expires_date" = "2019-11-12 13:22:16 Etc/GMT";
"expires_date_ms" = 1573564936000;
"expires_date_pst" = "2019-11-12 05:22:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:17:16 Etc/GMT";
"purchase_date_ms" = 1573564636000;
"purchase_date_pst" = "2019-11-12 05:17:16 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000222233331;
"web_order_line_item_id" = 1000000012345673;
},
{
"expires_date" = "2019-11-12 13:30:18 Etc/GMT";
"expires_date_ms" = 1573565418000;
"expires_date_pst" = "2019-11-12 05:30:18 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:25:18 Etc/GMT";
"purchase_date_ms" = 1573565118000;
"purchase_date_pst" = "2019-11-12 05:25:18 America/Los_Angeles";
quantity = 1;
"subscription_group_identifier" = 20332211;
"transaction_id" = 1000000888899991;
"web_order_line_item_id" = 1000000012345671;
},
{
"is_trial_period" = false;
"original_purchase_date" = "2019-11-13 03:04:45 Etc/GMT";
"original_purchase_date_ms" = 1573614285000;
"original_purchase_date_pst" = "2019-11-12 19:04:45 America/Los_Angeles";
"original_transaction_id" = 1000000222233327;
"product_id" = "mac_3m";
"purchase_date" = "2019-11-13 03:04:45 Etc/GMT";
"purchase_date_ms" = 1573614285000;
"purchase_date_pst" = "2019-11-12 19:04:45 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233327;
}
);
"pending_renewal_info" = (
{
"auto_renew_product_id" = "autorenew_1m";
"auto_renew_status" = 0;
"expiration_intent" = 1;
"is_in_billing_retry_period" = 0;
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
}
);
receipt = {
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = "1.0";
"bundle_id" = "com.TYStore.cn";
"download_id" = 0;
"in_app" = (
{
"is_trial_period" = false;
"original_purchase_date" = "2019-11-13 03:04:45 Etc/GMT";
"original_purchase_date_ms" = 1573614285000;
"original_purchase_date_pst" = "2019-11-12 19:04:45 America/Los_Angeles";
"original_transaction_id" = 1000000222233327;
"product_id" = "mac_3m";
"purchase_date" = "2019-11-13 03:04:45 Etc/GMT";
"purchase_date_ms" = 1573614285000;
"purchase_date_pst" = "2019-11-12 19:04:45 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233327;
},
{
"expires_date" = "2019-11-12 13:02:16 Etc/GMT";
"expires_date_ms" = 1573563736000;
"expires_date_pst" = "2019-11-12 05:02:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 12:57:16 Etc/GMT";
"purchase_date_ms" = 1573563436000;
"purchase_date_pst" = "2019-11-12 04:57:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233337;
"web_order_line_item_id" = 1000000012345600;
},
{
"expires_date" = "2019-11-12 13:07:16 Etc/GMT";
"expires_date_ms" = 1573564036000;
"expires_date_pst" = "2019-11-12 05:07:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:02:16 Etc/GMT";
"purchase_date_ms" = 1573563736000;
"purchase_date_pst" = "2019-11-12 05:02:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233338;
"web_order_line_item_id" = 100000001234599;
},
{
"expires_date" = "2019-11-12 13:12:16 Etc/GMT";
"expires_date_ms" = 1573564336000;
"expires_date_pst" = "2019-11-12 05:12:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:07:16 Etc/GMT";
"purchase_date_ms" = 1573564036000;
"purchase_date_pst" = "2019-11-12 05:07:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233330;
"web_order_line_item_id" = 1000000012345622;
},
{
"expires_date" = "2019-11-12 13:17:16 Etc/GMT";
"expires_date_ms" = 1573564636000;
"expires_date_pst" = "2019-11-12 05:17:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:12:16 Etc/GMT";
"purchase_date_ms" = 1573564336000;
"purchase_date_pst" = "2019-11-12 05:12:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233332;
"web_order_line_item_id" = 1000000012345622;
},
{
"expires_date" = "2019-11-12 13:22:16 Etc/GMT";
"expires_date_ms" = 1573564936000;
"expires_date_pst" = "2019-11-12 05:22:16 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:17:16 Etc/GMT";
"purchase_date_ms" = 1573564636000;
"purchase_date_pst" = "2019-11-12 05:17:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222233331;
"web_order_line_item_id" = 1000000012345621;
},
{
"expires_date" = "2019-11-12 13:30:18 Etc/GMT";
"expires_date_ms" = 1573565418000;
"expires_date_pst" = "2019-11-12 05:30:18 America/Los_Angeles";
"is_in_intro_offer_period" = false;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 13:25:18 Etc/GMT";
"purchase_date_ms" = 1573565118000;
"purchase_date_pst" = "2019-11-12 05:25:18 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000888899991;
"web_order_line_item_id" = 1000000012345692;
},
{
"expires_date" = "2019-11-12 12:57:16 Etc/GMT";
"expires_date_ms" = 1573563436000;
"expires_date_pst" = "2019-11-12 04:57:16 America/Los_Angeles";
"is_in_intro_offer_period" = true;
"is_trial_period" = false;
"original_purchase_date" = "2019-11-12 12:52:17 Etc/GMT";
"original_purchase_date_ms" = 1573563137000;
"original_purchase_date_pst" = "2019-11-12 04:52:17 America/Los_Angeles";
"original_transaction_id" = 1000000222230013;
"product_id" = "autorenew_1m";
"purchase_date" = "2019-11-12 12:52:16 Etc/GMT";
"purchase_date_ms" = 1573563136000;
"purchase_date_pst" = "2019-11-12 04:52:16 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000222230013;
"web_order_line_item_id" = 1000000012345689;
}
);
"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-13 03:04:45 Etc/GMT";
"receipt_creation_date_ms" = 1573614285000;
"receipt_creation_date_pst" = "2019-11-12 19:04:45 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2019-11-13 03:22:41 Etc/GMT";
"request_date_ms" = 1573615361543;
"request_date_pst" = "2019-11-12 19:22:41 America/Los_Angeles";
"version_external_identifier" = 0;
};
status = 0;
}
网友评论