首页 文章

如何检查应用程序内购买自动可续订订阅有效

提问于
浏览
24

我正在寻求使用In App购买实施新的Auto Renewable订阅,但我不确定如何或何时检查用户当前是否已订阅 . 我的理解是,当用户最初订阅该应用时,可以使用购买日期和订阅日期来计算他们的订阅将持续多长时间 . 这个日期过后会发生什么?我们如何检查用户是否已自动续订或取消?

如果我使用 restoreCompletedTransactions 获取每次续订的交易和收据,系统将提示用户输入其iTunes密码 . 这是否意味着如果他们购买了7天的订阅,那么当应用程序检查订阅是否仍然有效时,他们必须每7天输入一次密码?

4 回答

  • 15

    请参阅此文档:

    http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html#//apple_ref/doc/uid/TP40008267-CH104-SW1

    如果您想从Web服务器检查它,您可以ping它们的API,它会返回自动续订的状态以及有关上次付款的信息 .

    如果您在设备上,那么您可能必须调用restoreCompletedTransactions,我想要求输入密码 .

    我没有看到任何其他方法 . 我想从设备上你可以通过联系服务器端使用的相同Web服务来验证订阅?我不知道那是多少的利弊 .

  • 3

    今天,我遇到了这个问题 .

    按照Apple doc这里,我用这种方式检查订阅是否已过期 . 我的想法:用户APPLE REST API响应:(请求时间到期时间)检查是否过期

    + (BOOL)checkInAppPurchaseStatus
    {
        // Load the receipt from the app bundle.
        NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
        NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
        if (receipt) {
            BOOL sandbox = [[receiptURL lastPathComponent] isEqualToString:@"sandboxReceipt"];
            // Create the JSON object that describes the request
            NSError *error;
            NSDictionary *requestContents = @{
                                              @"receipt-data": [receipt base64EncodedStringWithOptions:0],@"password":@"SHARE_SECRET_CODE"
                                              };
            NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                                  options:0
                                                                    error:&error];
    
            if (requestData) {
                // Create a POST request with the receipt data.
                NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
                if (sandbox) {
                    storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
                }
                NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
                [storeRequest setHTTPMethod:@"POST"];
                [storeRequest setHTTPBody:requestData];
    
                BOOL rs = NO;
                //Can use sendAsynchronousRequest to request to Apple API, here I use sendSynchronousRequest
                NSError *error;
                NSURLResponse *response;
                NSData *resData = [NSURLConnection sendSynchronousRequest:storeRequest returningResponse:&response error:&error];
                if (error) {
                    rs = NO;
                }
                else
                {
                    NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:resData options:0 error:&error];
                    if (!jsonResponse) {
                        rs = NO;
                    }
                    else
                    {
                        NSLog(@"jsonResponse:%@", jsonResponse);
    
                        NSDictionary *dictLatestReceiptsInfo = jsonResponse[@"latest_receipt_info"];
                        long long int expirationDateMs = [[dictLatestReceiptsInfo valueForKeyPath:@"@max.expires_date_ms"] longLongValue];
                        long long requestDateMs = [jsonResponse[@"receipt"][@"request_date_ms"] longLongValue];
                        NSLog(@"%lld--%lld", expirationDateMs, requestDateMs);
                        rs = [[jsonResponse objectForKey:@"status"] integerValue] == 0 && (expirationDateMs > requestDateMs);
                    }
                }
                return rs;
            }
            else
            {
                return NO;
            }
        }
        else
        {
            return NO;
        }
    }
    

    希望这有帮助 .

  • 5

    最好在拨打Apple api之前使用本地解决方案 . 每次应用程序运行时,最好验证本地收据,如果您需要检查用户是否具有有效订阅,您可以先从本地收据中检索购买,然后查明今天的购买是否仍然有效 .

    我已经实现了一个用 Swift 编写的小型库,以简化在本地使用应用内收据 . 您可以轻松获取代表收据的对象( InAppReceipt )并检索有效购买/所有购买 .

    随意使用 . Github link

    以下是解决问题的示例:

    import TPInAppReceipt
    
    do {
        let receipt = try InAppReceiptManager.shared.receipt()
    
        //retrive active auto renewable subscription for a specific product and date
        let purchase = receipt.activeAutoRenewableSubscriptionPurchases(ofProductIdentifier: "ProductName", forDate: Date())
    
        //retrive all auto renewable subscription purchases for a specific product
        let allAutoRenewableSubscriptionPurchases = receipt.purchases(ofProductIdentifier: "productName").filter({ return $0.isRenewableSubscription })
    } catch {
        print(error)
    }
    
  • 9

    我正在围绕这个问题开始一场竞选活动 . 以下是我的观察和活动:

    在自动续订时,App Store会调用 paymentQueue 并发布一个事务 . 该交易以 transaction.transactionState==SKPaymentTransactionStateRestored 过帐 .

    问题是,不幸的是,这只会发布到一个设备上 . 第二个设备无法发布 . 因此,要检测自动续订,或者更确切地说检测缺少自动续订并拒绝设备继续订阅,您必须执行 restoreCompletedTransaction 或"http post a 64-bit encoded JSON containing the last transaction" . 如果是前者,用户需要提供密码; 's intrusive - as you have pointed out above. If the latter, lots of additional coding is required. So, my question is...why doesn' t StoreKit 有一个命令:

    (不存在) - [[SKPaymentQueue defaultQueue] restoreAttachedTransactions:(NSArray *)transactions];

    此命令将像 restoreCompletedTransactions 一样流动,但它只会恢复附加的事务,最重要的是,它不需要用户登录 . 它具有与"http post a 64-bit encoded JSON containing the last transaction"相同的安全保护,它允许整个In App Purchase过程在 StoreKit 中完成,而不是要求Web发布代码 .

    如果这对你有意义,请建议如何把它送到Apple ....谢谢 .

相关问题