Как проверить наличие покупки в приложении "Авто возобновляемая подписка"
Я ищу внедрить новые подписки на Auto Renewable, используя In App Purchase, но я не уверен, как и когда нужно проверить, подписан ли пользователь в настоящее время. Я понимаю, что, когда пользователь изначально подписывается, приложение может использовать дату покупки вместе с датой подписки, чтобы рассчитать, как долго будет длиться их подписка. Что произойдет после этой даты? Как проверить, обновлен или отменен пользователь?
Если я использую restoreCompletedTransactions
для получения транзакции и квитанции для каждого продления, пользователю будет предложено ввести свой пароль iTunes. Означает ли это, что, если они купили 7-дневную подписку, им придется вводить свой пароль каждые 7 дней, когда приложение проверяет, сохраняет ли подписка?
Ответы
Ответ 1
См. это для документов:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html#//apple_ref/doc/uid/TP40008267-CH104-SW1
Если вы хотите проверить его с веб-сервера, вы выполните ping их API и он возвращает статус автоматической возобновляемой подписки и информацию о последнем платеже.
Если вы находитесь на устройстве, вам, вероятно, придется вызвать restoreCompletedTransactions, который, как мне кажется, запрашивает пароль.
Я не вижу другого метода. Я полагаю, что с устройства вы можете проверить подписку, связавшись с тем же веб-сервисом, который используется на стороне сервера? Я не знаю, как за и против этого.
Ответ 2
Сегодня у меня проблемы с этой проблемой.
Следуйте 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;
}
}
Надеюсь на эту помощь.
Ответ 3
Лучше использовать локальное решение, прежде чем делать какие-либо вызовы Apple api. Каждый раз, когда приложение работает хорошо, проверьте правильность локальной квитанции, и если вам нужно проверить, имеет ли пользователь активную подписку, вы можете сначала получить покупки из местной квитанции и узнать, что покупка по-прежнему активна на сегодня,
Я реализовал небольшую библиотеку, написанную в Swift
, чтобы упростить работу с приложением In-App Purchase. Вы можете легко получить объект, который представляет квитанцию (InAppReceipt
), и получить активную покупку/все покупки.
Не стесняйтесь использовать. ссылка Github
Вот пример решения вашей проблемы:
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)
}
Ответ 4
Я начинаю кампанию вокруг этой проблемы. Вот мое наблюдение и кампания:
При автоматическом обновлении App Store вызывает paymentQueue
и отправляет транзакцию. Транзакция отправляется с помощью transaction.transactionState==SKPaymentTransactionStateRestored
.
Проблема в том, что, к сожалению, это отправляется только на одно устройство. Второе устройство не получает проводку. Таким образом, чтобы обнаружить автоматическое обновление или, скорее, обнаружить отсутствие автообмена и запретить устройству постоянную подписку, вам нужно сделать restoreCompletedTransaction
или "http post 64-bit encoded JSON, содержащий последнюю транзакцию". Если первый, пользователь должен указать свой пароль; это навязчивое - как вы указали выше. Если последнее, требуется много дополнительного кодирования. Итак, мой вопрос: почему у StoreKit
нет команды:
(не существует) - [[SKPaymentQueue defaultQueue] restoreAttachedTransactions:(NSArray *)transactions];
Эта команда будет течь точно так же, как и restoreCompletedTransactions
, но она только восстановит присоединенные транзакции и, самое главное, не потребует входа пользователя. Он обладает той же защитой безопасности, что и "HTTP-пост с 64-битным кодированным JSON, содержащим последнюю транзакцию", и позволяет полностью обрабатывать процесс покупки в приложении StoreKit
, а не требовать код веб-публикации.
Если это имеет смысл для вас, пожалуйста, предложите, как получить это в Apple.... спасибо.