React-native-iap: Ошибка при обновлении / понижении подписки на Android с ОТЛОЖЕННЫМ режимом

Созданный на 28 дек. 2019  ·  31Комментарии  ·  Источник: dooboolab/react-native-iap

Версия react-native-iap

4.3.3

Версия react-native

0,59,10

Платформы, на которых вы столкнулись с ошибкой (IOS или Android или оба?)

Android

Ожидаемое поведение

При обновлении / понижении подписки в режиме ОТЛОЖЕННЫЙ необходимо вызвать слушателя обновления покупки с квитанцией о новой транзакции.

Фактическое поведение

Слушатель ошибок покупки вызывается со следующей ошибкой:

{сообщение: "покупки недействительны.",
код: 'ОК',
debugMessage: '',
responseCode: 0}

Протестированная среда (Эмулятор? Настоящее устройство?)

Настоящее устройство - песочница

Шаги по воспроизведению поведения

1. Приобретите подписку с помощью RNIap.requestSubscription (sku), это работает правильно.

2. Обновите или понизьте подписку с помощью RNIap.requestSubscription (newSku, false, sku, 4). (4 - ОТЛОЖЕННЫЙ режим пропорционального распределения) В диалоговом окне выставления счетов Google Play будет показано, что план подписки был успешно изменен, и вы получите уведомление по электронной почте от Google Play об этом. Однако прослушиватель ошибок вызывается с указанной выше ошибкой.

3.Если вы снова вызовете RNIap.requestSubscription (newSku, false, sku, 4), диалоговое окно выставления счетов Google Play сообщит, что они не могут изменить план подписки, и вызывается прослушиватель ошибок со следующей ошибкой:

{message: "Google сообщает, что у нас возникли проблемы с подключением к платежу.",
код: 'E_DEVELOPER_ERROR',
debugMessage: '',
responseCode: 5}

Но иногда в диалоговом окне выставления счетов Google Play сообщается, что ваш заказ обрабатывается и ваш продукт должен быть доставлен в ближайшее время, и вызывается прослушиватель ошибок со следующей ошибкой:

{message: 'У вас уже есть этот товар.',
код: 'E_ALREADY_OWNED',
debugMessage: '',
responseCode: 7}

Я предполагаю, что это связано с тем, что транзакция на шаге 2 ожидает подтверждения. Однако, поскольку шаг 2 не возвращает квитанцию, мы не можем его подтвердить.

🕵️‍♂️ need more investigation 🙏 help wanted 🤖 android

Самый полезный комментарий

Есть планы решить эту проблему?

Все 31 Комментарий

Попробуйте позвонить в getAvailablePurchases после обновления / понижения подписки.
См. Документ The list of Purchase objects in onPurchasesUpdated() does not contain paused subscriptions. .

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

Я попробовал getAvailablePurchases () после обновления / понижения подписки, но, к сожалению, в возвращаемом массиве есть только квитанция о транзакции исходной покупки.

RNIap v2.3.19 и v2.5.5 работает правильно, buySubscription () вернет новую квитанцию ​​при обновлении / понижении подписки. Но я хотел бы перейти на v3 или v4, которые имеют лучшую модель на основе событий, если это возможно.

Вот справочный документ, в котором объясняется, как работает обновление / понижение подписки Android, и почему нам нужна новая квитанция после обновления / перехода на более раннюю версию.

@ howg0924 Спасибо за подтверждение. Я хотел бы сравнить различия с v2 и нашей текущей версией и посмотреть, как я могу исправить эту проблему.

Я искал для вас код на выходных в № 893
Новое обновление появится через 4.4.0 .

Не могли бы вы протестировать [email protected] версию?

@hyochan Я только что попробовал 4.4.0-rc.1, но ситуация все та же.

После вызова RNIap.requestSubscription (oldSku, false, newSku 4) и завершения обновления / понижения версии прослушиватель ошибок вызывается со следующей ошибкой:

{сообщение: "покупки недействительны.",
код: 'ОК',
debugMessage: '',
responseCode: 0}

А getAvailablePurchases () содержит только старую квитанцию.

@ howg0924 Если вы знаете, как отлаживать android , я надеюсь, что вы протестируете добавление некоторых Log.d и посмотрите, проходят ли они условия if в buyItemByType . Возможно ли это для вас? Я хочу посмотреть, как они исполняются.

@ howg0924 Ой, подождите ~! Я думаю, что обнаружил проблему, позвольте мне скоро вернуться к вам!

@ howg0924 Не могли бы вы попробовать 4.4.0-rc.2 ? Думаю, на этот раз сработает.

Сборка @hyochan 4.4.0-rc.2 не удалась:

RNIapModule.java:436: error: incompatible types: SkuDetails cannot be converted to String:
   builder.setOldSku(selectedOldSku);
                     ^

@hyochan Я отслеживал buyItemByType () из 4.4.0-rc.1. При обновлении / понижении версии выполнялось:

builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);

а также выполнены:

BillingResult billingResult = billingClient.launchBillingFlow(activity, flowParams);

Вы хотите, чтобы я отслеживал / сбрасывал поток / данные?

(удалено по недоразумению)

@ howg0924 Извините, что сделал ошибку, потому что у меня не было хорошей отладки env . Я вернул это в 4.4.0-rc.3 . Похоже, ваш код не выполняет builder.setOldSku(oldSku) что является наиболее важным.

После сравнения с 2.5.5 обнаружил, что 2.5.5 не звонит

builder.setReplaceSkusProrationMode (BillingFlowParams.ProrationMode.DEFERRED);

при использовании ОТЛОЖЕННОГО режима.

Поэтому я пытаюсь удалить эту строку на 4.4.0-rc.1, и она работает! Но я не знаю:

1. над каким режимом пропорциональности сейчас работает.
2. почему он не работает в режиме ОТЛОЖЕННЫЙ с помощью setReplaceSkusProrationMode ()

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

В настоящее время мы передаем ProrationMode как указано выше. Значит ли это, что вы можете auto renew subscription когда удалили DEFERRED ?

Я имею в виду, если я изменю код на:

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            // comment following line
            // builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

тогда я могу использовать RNIap.requestSubscription (newSku, false, sku, 4 / * ОТЛОЖЕННЫЙ режим * /) для обновления / понижения подписки. Хотя я не уверен, в каком режиме пропорциональности он действительно работает, поскольку builder.setReplaceSkusProrationMode () не выполняется, как это было в v2.5.5.

Следующий код взят из v2.5.5:

        if (type.equals(BillingClient.SkuType.SUBS) && oldSku != null && !oldSku.isEmpty()) {
          // Subscription upgrade/downgrade
          if (prorationMode != null && prorationMode != 0) {
            builder.setOldSku(oldSku);
            if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
            } else {
              builder.addOldSku(oldSku);
            }
          } else {
            builder.addOldSku(oldSku);
          }
        }

@ howg0924 Что ж, это очень странно, поскольку мы даже не установили DEFFERED в нашей текущей главной ветке, которая равна 4.3.4 . Я добавил этот код в 4.4.0+ .

Думаю, причина может быть в другом. Я надеюсь, ты сможешь вернуться, если появятся другие новости.

Связанные # 391 # 555

Хорошо, я попробую еще и доложу.

Похожие # 707

@hyochan После дальнейшего тестирования на 4.4.0-rc.1:

IMMEDIATE_WITH_TIME_PRORATION => работает
IMMEDIATE_AND_CHARGE_PRORATED_PRICE => работает
IMMEDIATE_WITHOUT_PRORATION => работает
ОТЛОЖЕННЫЙ => НЕ РАБОТАЕТ (не знаю почему)

Что ж, это очень странно, поскольку мы даже не установили DEFFERED в нашей текущей основной ветке, которая является 4.3.4. Я добавил этот код в 4.4.0+.

Я считаю, что это из-за того, что следующий код в 4.3.0 все еще установлен в режим ОТЛОЖЕННЫЙ:

  if (prorationMode != 0 && prorationMode != -1) {
    builder.setReplaceSkusProrationMode(prorationMode);
  }

Однако приведенный выше код не существует в 2.3.19 и 2.5.5. Поэтому, когда я вызвал RNIap.requestSubscription (newSku, false, sku, 4 / * DEFERRED * /) в 2.3.19 и 2.5.5, я думал, что это работает раньше, но теперь я понял, что он действительно работал в режиме IMMEDIATE_WITH_TIME_PRORATION по умолчанию .

Итак, мы должны знать, почему Deffered не работает. Я пока не мог найти причину.

У меня такая же проблема, но поведение другое.

Когда я вызываю requestSubscription(newSku, false, oldSku, 4) , он выдает ошибку с кодом ошибки OK и пустым сообщением об ошибке. Оплата на стороне Google Play происходит должным образом (отложена). Когда происходит следующая плата за подписку, я получаю событие purchaseUpdatedListener при запуске приложения, но не могу подтвердить покупку (через вызов finishTransaction() ). finishTransaction() выдает ошибку DEVELOPER_ERROR .

Случается как в версии 4.4.0 и в версии 4.3.4 .

Привет @hyochan , я видел, что в https://github.com/dooboolab/react-native-iap/pull/893 вы отметили это как решенное , но я обновил response-native-iap до последней версии, но этот все еще не работает фиксированный. Я по-прежнему получаю ошибку в слушателе error {"code": "OK", "debugMessage": "", "message": "purchases are null.", "responseCode": 0} и обычно получаю электронное письмо You updated your subscription purchase . Итак, мой вопрос: какое правильное решение для режима ОТЛОЖЕННЫЙ?

В прошлый раз я тоже обнаружил эту проблему. Как ни странно, не работает только в режиме deferred . Нам нужно это исследовать.

Привет @ howg0924 , у тебя уже есть решение этой проблемы?

@ nenjamin2405 Нет, я все еще использую режим IMMEDIATE_WITH_TIME_PRORATION по умолчанию и очень надеюсь, что это можно исправить.

Привет @hyochan , есть поводу ? Новая функция моего приложения застряла в этой проблеме. Очень признателен за ваши усилия по расследованию этого вопроса, спасибо

Еще нет. У меня не было времени обсуждать этот вопрос.
Я надеюсь, что кто-нибудь также найдет полезную информацию для решения этой проблемы.
Спросить Google или StackOverflow и поделиться этим в этой беседе может быть действительно полезно.

Привет, похоже, в последнее время по этой проблеме не было никакой активности. Проблема устранена или все еще требует внимания сообщества? Эта проблема может быть закрыта, если больше не будет активности. Вы также можете пометить этот вопрос как «Для обсуждения» или «Хороший первый выпуск», и я оставлю его открытым. Спасибо за ваш вклад.

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

Проблема связана с тем, что обновленный прослушиватель покупки вызывается с пустым списком покупок при замене отложенной подписки, как работает Android (см. Здесь здесь «Режим отложенной замены ...»)

Мы добавили поддержку замены отложенной подписки Android на response-native-iaphub , выполнив исправление, которое ищет, когда вызывается прослушиватель ошибок с ошибкой purchases are null при замене подписки. ( См. Коммит )

Конечно, вам придется внести некоторые изменения на стороне сервера для проверки ваших квитанций, обновления квитанции недостаточно при работе с отложенными подписками.
Вам нужно будет реализовать уведомления Android в реальном времени, чтобы определять, когда происходит замена подписки, и обрабатывать новый токен.

Или вы можете просто использовать IAPHUB, который делает все это за вас 🙂

Есть планы решить эту проблему?

Как упоминает @iaphub , проблема в том, что onPurchasesUpdated вызывается с аргументом purchases как null когда используется режим DEFERRED.

Из документов Google :

Для режима отложенной замены ваше приложение получает вызов вашего PurchasesUpdatedListener с пустым списком покупок и статусом того, было ли обновление или понижение версии успешным.

Так что это просто вопрос обработки этого случая внутри этого слушателя.

Но я не уверен, как правильно справиться с этой ситуацией:

  • Выполнение обещания с помощью предыдущей информации о подписке
  • Выполнение обещания с помощью undefined
  • Отклонение обещания с кодом PURCHASE_DEFERRED

Что вы думаете?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги