Подтвердить что ты не робот

Поддерживает ли Google Play In-App Billing Version 3 возврат средств?

Я получил IAB v3, и я смог совершить покупку для управляемого элемента. Тем не менее, чтобы продолжить разработку и тестирование, я хотел вернуть покупку, чтобы повторить попытку повторной покупки. Я зашел в аккаунт Google Checkout Merchant и успешно возвратил покупку. Тем не менее, приложение по-прежнему считает, что пользователь приобрел купленный товар. Прошло уже несколько недель с тех пор, как я сделал возмещение, так что это не проблема с задержкой.

В основном, в моей реализации QueryInventoryFinishedListener, inventory.hasPurchase(SKU_REMOVE_ADS) всегда возвращает true, даже после возврата (SKU_REMOVE_ADS является SKU для элемента, который я продаю). Я ожидал, что он вернет false после того, как возврат был обработан.

Если вы посмотрите раздел "Обработка возвратов" в ссылке IAB, в нем говорится, что ваше приложение должно прослушивать сообщения IN_APP_NOTIFY. Однако документация для IN_APP_NOTIFY специфична для v2 биллинга в приложении. Кажется, это не то, что доступно в v3, поскольку оно не упоминается нигде в ссылке на v3, и я не могу найти в нем ссылку в примере TrivialDrive app, который они используются для демонстрации IAB v3.

Так что v3 поддержки IAB возмещает/отменяет покупки? Кто-нибудь пробовал это и заработал?

4b9b3361

Ответ 1

На самом деле нет разницы между расходным материалом и непотребимым товаром в отношении Google Play; это различие полностью зависит от того, что вы реализуете в своем приложении. Поэтому, несмотря на то, что тестируемый вами SKU предназначен для нерасходуемого (например, постоянного повышения премиум-класса), для тестирования вы можете рассматривать его как расходное и потреблять, чтобы его можно было купить снова.

Удобный подход состоит в том, чтобы настроить временное тестовое меню в вашем приложении (например, добавив элемент меню во время тестирования в основное меню параметров вашего приложения), а затем, чтобы обработчик этого элемента вызывал метод consumeAsync() вашего Пример IabHelper для SKU, который вы хотите снова проверить. Это будет потреблять этот элемент и, таким образом, сделать его немедленно доступным для выкупа с вашего устройства.

Вы, конечно, по-прежнему хотите возместить покупку у Google Checkout, чтобы вы не тратили свои деньги, просто чтобы проверить свое приложение.

Я бы добавил, что consumeAsync() также отлично работает для сброса теста SKU android.test.purchased, если вы тестируете с использованием таких статических значений.

Что касается обновления состояния покупки, чтобы отразить возмещение, я лично испытал (и есть много подобных отчетов, опубликованных другими разработчиками), которые вручную инициируют возврат через Checkout (например, для пробной покупки из приложения TrivialDrive) дней, чтобы привести к изменению состояния покупки продукта (до INAPP_PURCHASE_STATE_REFUNDED).

(Зная, что страдание любит компанию, некоторые из этих дополнительных отчетов можно найти в этой дискуссии: https://plus.google.com/+AndroidDevelopers/posts/R8DKwZDsz5m)

По крайней мере, частично это связано с кэшированием Google Play данных о покупке на устройстве.

По моему опыту, перезагрузка устройства иногда может заставлять Google Play обновлять свой кеш с серверов GP. Возможно, что после перезагрузки также могут быть обнаружены изменения из-за отмены или возврата заказа через Checkout.

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

Конечно, помните, что это понятие, что кеш будет обновляться при перезагрузке, недокументирован и анекдотичен (например, довольно много поведения IAB3 и TrivialDrive, пока). Фольклор, они это называют.

Еще одна вещь, которая запускает обновление, - это когда пользователь пытается приобрести продукт. Как только покупка будет запущена, система должна быть уверена, что продукт еще не принадлежит, и поэтому он обновляет кеш Google Play. В моем личном опыте это всегда происходило. Но опять же, это не очень практичный способ проверить возврат средств, поскольку это связано с тем, что диалог покупки невозможен, а также сообщение об ошибке, которое сообщает пользователю, что "вы уже владеете этим" (если они действительно владеют им).

Если это пригодится, это когда пользователь платит за элемент IAB на одном из своих устройств, а затем пытается получить доступ к этому элементу на другом устройстве, принадлежащем той же учетной записи, что и для его покупки. Информация о покупке в этом случае очень часто не кэшируется. Но вы можете просто добавить небольшую заметку в свой диалог о покупке, что, если товар уже куплен, попытка повторной покупки должна сделать его доступной на настоящем устройстве без дополнительной оплаты. Иногда для получения ответа IabHelper.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED требуется две попытки (инициированные пользователем) попытки покупки. Да, немного klugy, но я думаю, что в человеческих терминах он будет работать с соответствующей подсветкой сообщения и апологетической формулировкой диалогового окна подтверждения, сообщающего им, что у них есть элемент и т.д.:-)).

В практическом плане вы можете видеть, как Google не может каждый раз получать доступ к каждому серверу каждого приложения IAB в мире при каждом доступе к данным о покупке приложения, особенно учитывая, что они советуют разработчикам делать проверку за то, что было куплено при каждом запуске приложения. Это также проблема производительности для вашего приложения - это то, что такое кеширование. Поэтому вам нужно знать о триггерах для обновления кеша, и я не нашел ни одного места, где это официально документировано (за исключением, мы предполагаем, в коде). Так что будьте готовы выставить свои руки перед собой и начать чувствовать себя в темноте.

Дополнительную информацию о буферизации Google Play см. на этой странице:

В каких условиях возможны изменения в версии 3 для доменных приложений версии 3 на клиентских устройствах?

Я хотел бы отметить, что в вашем фрагменте кода публикации вы вызываете inventory.hasPurchase(SKU_REMOVE_ADS), но это только скажет вам, является ли покупка в списке покупок, возвращенных в объекте инвентаризации; он не скажет вам состояние покупки для этого SKU. Я знаю, что это подход, используемый приложением TrivialDrive, но это приложение не занимается возвратами и отменой. Чтобы обнаружить возврат и отмененные заказы, вам понадобится что-то вроде этого:

Purchase removeAdsPurchase = inventory.getPurchase(SKU_REMOVE_ADS);
if(removeAdsPurchase != null) {
  int purchaseStateForRemoveAds = removeAdsPurchase.getPurchaseState();
  if(purchaseStateForRemoveAds == 1) {
    //Do cancelled purchase stuff here
  }
  else if(purchaseStateForRemoveAds == 2) {
    //Do refunded purchase stuff here
  }
}

Хорошая новость о возмещении и отмененных заказах заключается в том, что оба они, AFAIK, полностью зависят от разработчика. Таким образом, если вы обнаружите, что пользователи, которые получают их, могут продолжать использовать ваше приложение в течение длительного промежутка времени, и если вы обнаружите, что многие пользователи пользуются этим преимуществом, то вы можете решить, хотите ли вы продолжать предоставлять возмещение в все случаи. Я думаю, что это не проблема. даже если некоторый пользователь, который получает возмещение, может использовать ваше приложение на некоторое время после этого, это не считается очень большой сделкой.

Для тестирования вам нужно очень быстро попробовать покупку, и использование consumeAsync() определенно работает для этой цели.

Ответ 2

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

Теперь убедитесь, что вы тестируете приложение с тем же идентификатором Gmail, для которого у вас есть возмещение? Чтобы проверить сценарий возврата, я думаю, вы можете использовать android.test.refunded как идентификатор продукта.

Если это не работает, вы можете сначала проверить общий приобретенный товар и Доступные элементы в Google Play при первом запуске приложения и если вы получаете одинаковый идентификатор продукта в обоих вызовах (что не должно быть, если это так, сообщите об этой ошибке в Google), затем сделайте api-вызов, чтобы сделать тот же элемент, что и потребляемый.

Ответ 3

После публикации этого вопроса мое внимание было обращено на то, что мне нужно позвонить getPurchase(...).getPurchaseState() и проверить его значение. Возможные значения: 0 (приобретается), 1 (отменено) или 2 (возвращено).

Тем не менее, в моем случае его по-прежнему перенастраивается 0 (purhcased), даже если элемент возвращается. Я размещаю эту информацию здесь, если это помогает кому-то другому.