I am developing Android app with com.android.billingclient:billing:2.0.1
. My subscription has the following parameters.
Billing period: 3 months
Free trial period: 3 days
Introductory price: -
Grace period: 3 days
But all of them (>100) become refunded 3 days after successful purchase. I don't understand the reason.
Here is a screenshot of typical order history:
Users ask why it is happening. I don't think all of them choose to return money.
My BillingManager class:
public class BillingManager implements PurchasesUpdatedListener {
private BillingClient billingClient;
private final List<Purchase> purchases = new ArrayList<>();
public BillingManager(Context context) {
billingClient = BillingClient.newBuilder(context).enablePendingPurchases().setListener(this).build();
startConnection();
}
void startConnection() {
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
final int responseCode = billingResult.getResponseCode();
if (responseCode == BillingResponseCode.OK) {
queryPurchases();
}
}
@Override
public void onBillingServiceDisconnected() {
retry();
}
});
}
void queryPurchases() {
PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.SUBS);
List<Purchase> cachedPurchaseList = purchasesResult.getPurchasesList();
onPurchasesUpdated(cachedPurchaseList);
}
@Override
public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchasesList) {
final int responseCode = billingResult.getResponseCode();
if (responseCode == BillingResponseCode.OK) {
onPurchasesUpdated(purchasesList);
} else if (responseCode == BillingResponseCode.USER_CANCELED) {
handleCanceledPurchase();
} else {
handleUnknownResponse();
}
}
private void onPurchasesUpdated(@Nullable List<Purchase> purchasesList) {
purchases.clear();
if (purchasesList != null) {
for (Purchase purchase : purchasesList) {
processPurchase(purchase);
}
}
notifyListener();
}
private void processPurchase(Purchase purchase) {
if (purchase.getPurchaseState() != PurchaseState.PURCHASED) {
return;
}
if (!verify(purchase)) {
return;
}
purchases.add(purchase);
}
public boolean shouldDoStuff() {
if (purchases.isEmpty()) {
return false;
} else {
for (Purchase purchase : purchases) {
if (purchase.getPurchaseState() != PurchaseState.PURCHASED) {
continue;
}
return true;
}
return false;
}
}
}
PS: The app verifies purchase signature locally and statistics says that results are positive.
Thanks for upgrading to the Play Billing Library 2.+. With respect to acknowledgement, you are required to acknowledge both subscriptions and non-consumable in-app products. During acknowledgement, and only during acknowledgement, you may optionally set a payload. The payload that you set will subsequently be returned when you query Purchases.
An important note about consumable products. You are not required to acknowledge consumable products. But if you do choose to acknowledge them (for whatever reason) and if -- further -- you submit a payload at the time of acknowledgement: then you are required to submit that same payload when you call consumeAsync
on Android.
Also you may acknowledge either through Android or through the server api.