Поток сбоя подтверждения получения RMStore
Я использую RMStore для проверки чеков. Как примечание, я не использую RMStore для фактической части покупки. Процесс успешно справляется с успехом и неудачей с точки зрения выдачи ошибок и не доставки контента, если квитанция недействительна. Я целенаправленно изменил пакет, чтобы вызвать сбой в качестве теста. Однако мой вопрос связан с процессом сбоя и подтверждением, которое отправляет Apple.
Проблема заключается в том, что, хотя этот процесс обнаруживает сбой проверки и, следовательно, предотвращает отправку содержимого пользователю, Apple все равно после этого возвращает диалоговое окно об успешной покупке. Хорошей новостью является то, что покупка не удалась, а контент не доставлен, но я бы предпочел, чтобы это диалоговое окно от Apple не отображалось, так как это создаст путаницу.
Вот моя реализация проверки. Сейчас я просто тестирую сценарий сбоя, прежде чем делать больше в блоке сбоя.
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");
RMStoreAppReceiptVerificator *verifyReceipt = [[RMStoreAppReceiptVerificator alloc]init];
[verifyReceipt verifyTransaction:transaction success:^{
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}failure:^(NSError *error){
NSLog(@"failure to verify: %@",error.description);
}];
}
Есть ли способ в блоке сбоя остановить процесс в Apple, который создает их диалоговое окно успеха, или мне нужно выполнить эту проверку на более ранней стадии?
Обновить:
Рассматривая далее этот метод, вызываемый государством SKPaymentTransactionStatePurchased
Определение этого состояния для Apple:
"В App Store успешно обработан платеж. Ваше приложение должно предоставлять контент, приобретенный пользователем".
Это говорит мне, что, вероятно, слишком поздно, чтобы предотвратить диалог. Существует более раннее состояние, однако, я думаю, что подтверждение получения должно прийти после покупки, но до доставки контента (в противном случае покупка не была бы подтверждена). Так что это просто вопрос борьбы с конфликтующим сообщением или я что-то упустил?
Обновление 2: добавление еще нескольких методов для запроса в комментариях
@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end
@implementation IAPHelper
{
SKProductsRequest * _productsRequest;
RequestProductsCompletionHandler _completionHandler;
NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
NSDictionary *_mappingDict;
}
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers andMappings:(NSDictionary *)mappingDict
{
if ((self = [super init])) {
// Store product identifiers & mappings
_productIdentifiers = productIdentifiers;
_mappingDict = mappingDict;
// Add self as transaction observer
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
// 1
_completionHandler = [completionHandler copy];
// 2
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
- (BOOL)productPurchased:(NSString *)productIdentifier {
return [_purchasedProductIdentifiers containsObject:productIdentifier];
}
- (void)buyProduct:(SKProduct *)product {
NSLog(@"Buying %@...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
if (_completionHandler)
{
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
_productsRequest = nil;
if (_completionHandler)
{
_completionHandler(NO, nil);
_completionHandler = nil;
}
}
Вот конкретный метод, который вызывает completeTransaction
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
};
}
1 ответ
В комментариях мы установили, что этот вопрос не имеет ничего общего с RMStore.
Вы не тестируете сценарий реального мошенничества, поэтому не имеет значения, показывает ли Apple предупреждение.
Это может включать либо использование поддельной квитанции, либо отправку поддельных звонков наблюдателю транзакции Store Kit. Ни в одном из этих случаев вы не получите предупреждение.
При использовании действительной транзакции для имитации сценария сбоя нельзя ожидать, что Apple также сочтет транзакцию недействительной. Нет никакого API, чтобы сообщить Apple, что транзакция является мошеннической. Вы можете только завершить транзакцию, или нет.