iOS IAP票据验证.md

作者: 儒徒 | 来源:发表于2020-09-04 11:09 被阅读0次

    一、iOS & MacOS票据

    MacOS相关
    • App的沙盒目录:~/Libraray/Containers/xxx(xxx=bundleID)

    • 票据为空原因 :Mac App开发过程中打包为AppStore包,形成dmg.
      一定要拖到/Application中。放在其他目录打开dmg做IAP支付,苹果支付成功后,获取receipt是获取不到的。

    • MacOS票据的位置:/Application/xxx.app/Contents中,应用程序的bundle里中

      efdb6399-1efd-4a16-8af3-46efad265604.png
    • ❗️❗️❗️ 苹果支付能力跨平台的一些处理兼容iOS、MacOS、TvOS

    iOS 相关

    票据的位置:沙盒数据文件中。StoreKit文件夹下

    8780b1aa-8bb7-4bb2-a15d-46fc38240f0e.png

    二、验证方式

    两种方式:本地验证和服务端验证,推荐服务端验证

    • 采用服务端验证,涉及苹果服务稳定性和超时的问题。对于验证接口超时,实际开发过程中,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;
    }
    
    

    参考资料

    相关文章

      网友评论

        本文标题:iOS IAP票据验证.md

        本文链接:https://www.haomeiwen.com/subject/ukhzsktx.html