Обработка отмененных транзакций IAP

#iphone #in-app-purchase #storekit

#iPhone #покупка в приложении #storekit

Вопрос:

Я использую StoreKit для покупок в приложении. Я обнаружил, что API отличается необычным поведением, когда пользователь нажимает кнопку «Отмена».

Например, если я нажимаю «Отмена» на экране «Подтвердить покупку в приложении», я получаю SKPaymentTransactionStateFailed транзакцию с error.code == SKErrorPaymentCancelled , как и следовало ожидать.

Но если я нажимаю кнопку Buy, а затем нажимаю Cancel, я получаю Failed транзакцию с error.code == 0 . error.localizedDescription Это «Не удается подключиться к iTunes Store», что явно является ложью.

Заманчиво рассматривать все Failed транзакции как игнорируемые отмены, но я также ясно вижу, что если устройство отключено в режиме полета, я получаю Failed транзакцию без всплывающего окна с предупреждением; В этом случае мне действительно следует уведомить пользователя, чтобы он объяснил проблему.

Я отмечаю, что MKStoreKit предполагает, что все сбои являются отменами. MKStoreManager failedTransaction метод никогда не вызывается; MKStoreObserver всегда вызывает transactionCanceled для всех Failed транзакций. В MKStoreManager.h комментариях не рекомендуется использовать сообщение об ошибке для transactionCanceled , что имеет смысл, но тогда кто будет уведомлять пользователя о Failed не отмененных транзакциях?

Какова наилучшая практика для обработки этих сбоев? Должен ли я проглатывать ошибки? Всегда показывать ошибку, даже если она избыточна?

Ответ №1:

У нас довольно значительная база пользователей, которые покупают товары через мобильные соединения, и мы показываем оповещения только для

 code != SKErrorPaymentCancelled amp;amp; code != SKErrorPaymentNotAllowed
  

По-видимому, это лучшее, что вы можете сделать. Я также видел странное поведение при отмене, о котором вы упоминаете, что, насколько я могу судить, является ошибкой фреймворка.

Ответ №2:

Предыдущий ответ довольно близок. MKStoreKit может автоматически отображать сообщения об ошибках для допустимых условий ошибки, таких как включенный родительский контроль и тому подобное.

Несмотря на это, для обработки отмен покупок я также предоставил делегат (начиная с версии v3.5) под названием transactionCanceled в MKStoreKitDelegate.

Обработайте это и остановите любые индикаторы активности или индикатор прогресса на контроллере просмотра, который выполняет вызов покупки…

Комментарии:

1. MKStoreKit 3.5 не проводит различий между сбоями и отменами. Я зарегистрировал проблему на github github.com/MugunthKumar/MKStoreKit/issues/3 и я исправил это в своем форке.

2. Спасибо! Я объединил ваш запрос на извлечение

3. Теперь, когда мой запрос на извлечение объединен, последний MKStoreKit автоматически отображает ошибку при сбое, а затем вызывает transactionCanceled для делегата, чтобы пользователи могли скрыть счетчик.

4. @Mugunth Почему вы нигде не описываете невозобновляемые подписки, я видел, что так много вопросов, касающихся этого, остались без ответа, почему?

5. невозобновляемые подписки не отличаются от нерасходуемых с точки зрения программиста. Если вы используете MKStoreKit, вам следует добавить свои невозобновляемые подписки в качестве непотребляемых и включить проверку на стороне сервера.

Ответ №3:

Я просто хотел добавить, что ошибки из-за отсутствия подключения к Интернету в основном должны быть обнаружены до любой транзакции с использованием класса достижимости Apple IMO. Таким образом, вам не нужно полагаться на API Apple для получения прямой и распространенной ошибки.

Ответ №4:

Я думаю, что это ваша ответственность и решение о том, показывать предупреждение об отмененной транзакции или нет. Но вы обязательно должны завершить это, иначе все время будет сброшено на сбой. Итак, должно быть что-то вроде этого:

 if (transaction.error.code == SKErrorPaymentCancelled) {
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
} else {
    [self notifyError:transaction.error];
}
  

Обновить:
Из-за бизнеса по разработке приложений для iPhone: создание и маркетинг приложений, которые успешно работают, мы должны завершать транзакцию после любого обновления до состояния Failed. Было бы интересно узнать, существуют ли ситуации, когда мы не должны этого делать.

Ответ №5:

Все еще есть одна проблема… После нажатия на кнопку «Купить» отобразится другое оповещение и будет запрошена информация об учетной записи.

если я все-таки отменил там, то это перейдет в case SKErrorUnknown: тогда я не могу показать сообщение, подобное этому «Ваша покупка не может быть завершена. Пожалуйста, проверьте настройки вашей сети и повторите попытку позже.»

 - (void) failedTransaction: (SKPaymentTransaction *)transaction
{   
    switch (transaction.error.code) {
        case SKErrorUnknown:
            NSLog(@"SKErrorUnknown");
            break;
        case SKErrorClientInvalid:
            NSLog(@"SKErrorClientInvalid");
            break;
        case SKErrorPaymentCancelled:
            NSLog(@"SKErrorPaymentCancelled");
        break;
        case SKErrorPaymentInvalid:
            NSLog(@"SKErrorPaymentInvalid");
            break;
        case SKErrorPaymentNotAllowed:
            NSLog(@"SKErrorPaymentNotAllowed");
        break;
        default:
            NSLog(@"No Match Found for error");
            break;
    }
    NSLog(@"transaction.error.code %@",[transaction.error description]);
    if (transaction.error.code == SKErrorPaymentCancelled) {
        [[MKStoreManager sharedManager] transactionCanceled:transaction];
    } else {
        [[MKStoreManager sharedManager] failedTransaction:transaction];
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 
}