Android In-App Billing: состояние покупки остается "купленным" после отмены заказа
В настоящее время я тестирую свой биллинговый механизм InApp (используя API-интерфейс InApp Billing версии 3, поэтому в качестве примера ссылаюсь на пример TrivialDrive).
У меня есть один управляемый элемент, который относится к версии с улучшенной версией.
Теперь покупка элемента с моей тестовой учетной записью работает, но после того, как я отменил весь заказ в Google checkout после этого, мой код все еще говорит мне, что этот предмет приобретен, и поэтому предоставляет премиальные функции.
Вот как я проверяю покупку в моей MainActivity. Я не сохраняю состояние покупки локально где-то, так как я понял, что с API-интерфейсом биллинга v3 вы можете запросить покупки ad hoc по мере необходимости.
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
iabHelper = new IabHelper(this, Helper.getPKey());
iabHelper.enableDebugLogging(true);
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
Log.d("IAB", "SETUP FINISHED");
if(!result.isSuccess())
{
Log.d("IAB", "SETUP NOT OK");
return;
}
else
Log.d("IAB", "SETUP OK");
iabHelper.queryInventoryAsync(
new QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
Log.d("IAB", "Query inventory finished.");
if (result.isFailure()) {
Log.d("IAB","Failed to query inventory: " + result);
return;
}
Log.d("IAB", "Query inventory was successful.");
// Do we have the premium upgrade?
boolean mIsPremium = inv.hasPurchase(Helper.premiumSku);
Purchase p = inv.getPurchase(Helper.premiumSku);
if(p != null)
Log.d("IAB PURCHASE STATE", IabHelper.getResponseDesc(p.getPurchaseState()));
else
Log.d("IAB PURCHASE STATE", "Purchase is null");
Log.d("IAB", "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
}
}
);
}
});
}
Я продолжаю получать getPurchaseState = 0, что означает, что Покупается, даже через час после того, как я отменил заказ. Почему?
Ответы
Ответ 1
Я знаю, что это год, но ни один из ответов/советов не помог мне, поэтому я решил добавить свое решение.
Во-первых, я столкнулся с той же проблемой. А именно, совершил пробную покупку, отменил ее, все еще получил состояние покупки, указывающее действительную покупку.
Что я забыл, так это то, что недавно я переключил поле "Ответ на тест лицензии" на панели настроек консоли разработчика Google Play с "RESPOND_NORMALLY" на "LICENSED"
После переключения на "RESPOND_NORMALLY" состояние покупки отмененной покупки было правильно возвращено как таковое.
Итак, вы можете проверить, что перед тем, как вы попытаетесь подождать дни
Ответ 2
Шаг 1. Подождите примерно 10 минут; Пока вы не увидите "отмененный заказ". в вашем кошельке Google.
Сен 15 11:28 утра Отменено Заказ был доставлен.
Сен 15 11:18 утра Отменено Вы отменили этот заказ. Причина: Запрос клиента на отмену.
Шаг 2. Выйдите из вашей тестовой учетной записи google на устройстве и затем повторно войдите в систему.
По крайней мере, это решило мою проблему.
Ответ 3
Эта проблема также возникает при использовании приложения на другом устройстве с той же учетной записью. Элемент не принимается, как приобретено, до тех пор, пока устройство не будет перезапущено даже через часы. Если вы попытаетесь снова купить, в диалоге google goallet будет указано, что элемент уже принадлежит. Код возврата из iabHelper по-прежнему "отменен пользователем", потому что реальный ответ от активности покупки не возвращается, только что записанный в журнале отладки.
else if (resultCode == Activity.RESULT_CANCELED) {
logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
}
Таким образом, невозможно реагировать на это диалоговое окно Google для выставления счетов, потому что мы всегда получаем тот же результат IABHELPER_USER_CANCELED, даже если в диалоговом окне сказано, что элемент уже принадлежит.
Edit:
Я исправляю это следующим образом:
else if (resultCode == Activity.RESULT_CANCELED) {
logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
if(responseCode == 7)
result = new IabResult(BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED, "Item already owned.");
else
result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
}
Итак, если ответ из диалогового окна биллинга равен 7, как "Элемент, уже принадлежащий", я сообщаю его моему слушателю.
Ответ 4
После того, как вы ждали около 12 часов и, попробовав все предлагаемое здесь, я все еще сталкивался с той же проблемой. Для меня это была следующая команда adb:
adb shell pm clear com.android.vending
Ответ 5
Его уже хорошо ответили в официальных документах Google. Копирование слов здесь.
Когда пользователь отменяет подписку, Google Play не предлагает возмещение за текущий расчетный цикл. Вместо этого он позволяет пользователю иметь доступ к отмененной подписке до конца текущего платежного цикла, после чего он прекращает подписку. Например, если пользователь покупает ежемесячную подписку и отменяет ее на 15-й день цикла, Google Play будет считать подписку действительной до конца 30-го дня (или другого дня, в зависимости от месяца).
Это должно объяснить все это. getPurchase()
все равно вернет данные о покупке до конца текущего цикла подписки.
Ответ 6
То, что вы можете использовать, - это поле autoRenewing
данных о покупке. В соответствии с документация:
autoRenewing: указывает, будет ли подписка обновляться автоматически. Если значение true, подписка активна и будет автоматически обновляться в следующую дату фактурирования. Если false, указывает, что пользователь отменил подписку.
И это поле обновляется сразу после отмены.
Ответ 7
Если я правильно вижу ссылочный код в trivialdrivesample, это неправильно, что было бы позором для официального справочного проекта для биллинга приложений.
Если покупка == null, это означает, что она никогда не была приобретена. Чтобы получить реальную информацию, вы должны позвонить
purchase.getPurchaseState()
в соответствии с здесь
purchaseState Состояние покупки заказа. Возможные значения: 0 (приобретается), 1 (отменено), 2 (возвращено) или 3 (истек, только для покупки подписки).
Ответ 8
Я нашел следующий раздел в документации (IAB API v2), но я не уверен, что это можно использовать для IAB API v3. Передача может по-прежнему отправляться.
"... ваше приложение может получать намерение трансляции IN_APP_NOTIFY, когда Google Play получает уведомление о возврате из Google Кошелька. В этом случае Google Play отправляет вашему приложению сообщение IN_APP_NOTIFY. Ваше приложение может обрабатывать это сообщение так же, как оно обрабатывает ответы от инициированного приложением сообщения REQUEST_PURCHASE, чтобы в конечном итоге ваше приложение получало сообщение PURCHASE_STATE_CHANGED, которое включает информацию об элементе, который был возвращен. Информация о возврате включена в строку JSON, которая сопровождает намерение трансляции PURCHASE_STATE_CHANGED. Кроме того, поле purchaseState в строке JSON установлено значение 2."
from: http://developer.android.com/google/play/billing/v2/api.html#billing-action-notify
Ответ 9
Просто перезагрузитесь.
Работал для меня. Android 5.1.1 на Nexus 4