iOS 自动订阅的一些问题 升级套餐 || 降级套餐

2020-03-26  本文已影响0人  traxes

交易流程的处理

主要是自动订阅开发是内购中比较麻烦的,细节问题比较多,很多问题需要确定。
例如要保证凭证的上传,漏单问题处理,后台如何判断订单的有效期,和订单的类型等等。

客户端调试

客户端配合服务器端就比较麻烦了。客户端可以通过凭证向想苹果服务器获取信息验证收据。

文档上有指导:

- (void)query:(NSString *)receipt {
# ifdef DEBUG
//    NSData *receipt; // Sent to the server by the device
    // Create the JSON object that describes the request
    NSError *error;
    NSDictionary *requestContents = @{
    @"receipt-data": receipt,
    @"password" : @"xxxxxxxxxxxxxxxxxxxxxx",//内购的秘钥
    @"exclude-old-transactions":@(YES)
    };
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
    options:0
    error:&error];
    if (!requestData) { /* ... Handle error ... */ }
    // Create a POST request with the receipt data.
    NSURL *storeURL = [NSURL
    URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
    [storeRequest setHTTPMethod:@"POST"];
    [storeRequest setHTTPBody:requestData];
    // Make a connection to the iTunes Store on a background queue.
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    ///NSURLConnection 已不推荐使用,如果在线上使用要切换到新的api
    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
                           completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        if (connectionError) {
            
        } else {
            NSError *error;
            NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
            options:0 error:&error];
            if (!jsonResponse) { /* ... Handle error ...*/ } else {
                
            }
            /* ... Send a response back to the device ... */
            }
    }];
# endif
}

如果仅仅在测试中使用,那么上线前记得要屏蔽代码。

同一个订阅组中更换订阅 xxx_2 升级到 xxx_3

这个更换订阅,目前发现两种情况,两种情况有一个共同点,就是都会出现
pending_renewal_info字段,此字段记录了自动续期的待处理信息,例如订阅的变更等。

参考:https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info

 "pending_renewal_info" =     (
                {
            "auto_renew_product_id" = "xxxx_3";//变更的目标订阅
            "auto_renew_status" = 1;
            "original_transaction_id" = 1000000xxxxxx;
            "product_id" = "xxx_2";//原订阅
        }
    );

由便宜的订阅升级到贵的订阅,因为下个订阅会在当前订阅结束才会具体执行变更。所以如果这个时候获取最后一条交易信息,对应的product_id 依然是当前的,如"product_id" = "xxx_2";
此时最后一条记录为

"latest_receipt_info" =     (
                {
            "expires_date" = "2020-03-26 03:43:20 Etc/GMT";
            "expires_date_ms" = 1585194200000;
            "expires_date_pst" = "2020-03-25 20:43:20 America/Los_Angeles";
            "is_in_intro_offer_period" = false;
            "is_trial_period" = false;
            "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
            "original_purchase_date_ms" = 1585191247000;
            "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
            "original_transaction_id" = 1000000643447076;
            "product_id" = "xxx_2";
            "purchase_date" = "2020-03-26 03:28:20 Etc/GMT";
            "purchase_date_ms" = 1585193300000;
            "purchase_date_pst" = "2020-03-25 20:28:20 America/Los_Angeles";
            quantity = 1;
        ....省略
        }
    );

如果仅仅判断当前的产品是否生效,判断latest_receipt_info -> expires_date_ms 即可。

............然后有一天到期了,就会变更到目标订阅,此时会收到自动续订,再去获取信息,latest_receipt_info 和 pending_renewal_info 会变化如下:

/// auto_renew_product_id 和  product_id 一致 订阅已经切换过去了。
 "pending_renewal_info" =     (
                {
            "auto_renew_product_id" = "xxx_3";
            "auto_renew_status" = 1;
            "original_transaction_id" = 1000000643xxxx;
            "product_id" = "xxx_3";
        }
    );
    
    //此为变更后的第一次续订,同时这个续订是真正把订阅切换过去
      "latest_receipt_info" =     (
                {
            "expires_date" = "2020-03-26 04:43:20 Etc/GMT";
            "expires_date_ms" = 1585197800000;
            "expires_date_pst" = "2020-03-25 21:43:20 America/Los_Angeles";
            "is_in_intro_offer_period" = false;
            "is_trial_period" = false;
            "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
            "original_purchase_date_ms" = 1585191247000;
            "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
            "original_transaction_id" = 1000000643447076;
            "product_id" = "xxx_3";
            "purchase_date" = "2020-03-26 03:43:20 Etc/GMT";
            "purchase_date_ms" = 1585194200000;
            "purchase_date_pst" = "2020-03-25 20:43:20 America/Los_Angeles";
            quantity = 1;
          ....省略
        }
    );

这样的一个方式,根据苹果的内购提示都是很一致的 “当前xxx订阅到期时,将支付新订阅的费用。”。意思不是立刻补钱,也不是立刻切换,而是下次变更订阅的同时,变更收费。

"latest_receipt_info" =     (
                {
            "expires_date" = "2020-03-26 04:23:23 Etc/GMT";
            "expires_date_ms" = 1585196603000;
            "expires_date_pst" = "2020-03-25 21:23:23 America/Los_Angeles";
            "is_in_intro_offer_period" = false;
            "is_trial_period" = false;
            "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
            "original_purchase_date_ms" = 1585191247000;
            "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
            "original_transaction_id" = 1000000643447076;
            "product_id" = "xxx_2";
            "purchase_date" = "2020-03-26 04:08:23 Etc/GMT";
            "purchase_date_ms" = 1585195703000;
            "purchase_date_pst" = "2020-03-25 21:08:23 America/Los_Angeles";
            quantity = 1;
         ......省略
        }
    );
    "pending_renewal_info" =     (
                {
            "auto_renew_product_id" = "xxx_2";
            "auto_renew_status" = 1;
            "original_transaction_id" = 100000064344xxxx;
            "product_id" = "xxxx_2";
        }
    );

因为在这个过程中可能存在这样的疑惑,升级订阅,怎么不产生新的记录?而latest_receipt_info的记录还是老的production_id,让人费解,实际上变化的过程如上面那样。而这个记录是准确的,同时如果记录依然生效读取这个expires_date_ms过期时间也是准确的。

所以在确定订阅生效的情况下,以latest_receipt_info的数据来计算是否过期即可。

以上说明,仅仅测试开发中的分析分享,仅供参考,不一定准确!!!!

参考链接:
官方字段说明
中文文档参考

上一篇下一篇

猜你喜欢

热点阅读