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

问题描述 投票:28回答:4

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

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

iphone objective-c ios in-app-purchase subscription
4个回答
9
投票

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

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

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


16
投票

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

在这里关注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编写的小型库,以简化在本地使用In-App Receipt。您可以轻松获取代表收据的对象(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)
}

3
投票

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

在自动续订时,App Store会调用paymentQueue并发布交易。该交易与transaction.transactionState==SKPaymentTransactionStateRestored一起发布。

问题是,不幸的是,这只会发布到一个设备上。第二个设备无法发布。因此,要检测自动续订,或者更确切地说检测缺少自动更新并拒绝设备继续订阅,您必须执行restoreCompletedTransaction或“http发布包含最后一次事务的64位编码JSON”。如果是前者,用户需要提供密码;这是侵入性的 - 正如你上面所指出的那样。如果是后者,则需要许多额外的编码。所以,我的问题是......为什么StoreKit没有命令:

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

此命令将像restoreCompletedTransactions一样流动,但它只会恢复附加的事务,最重要的是,它不需要用户登录。它具有与“http发布包含最后一个事务的64位编码JSON”相同的安全保护,并且它允许整个In App Purchase过程在StoreKit中完成,而不是需要Web发布代码。

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

© www.soinside.com 2019 - 2024. All rights reserved.