Skip to content
47 changes: 47 additions & 0 deletions rapt/prototype/renpyiap/src/main/java/org/renpy/iap/PlayStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class PlayStore extends Store {
/* A map from sku to ProductDetails object. */
private HashMap<String, ProductDetails> productDetailsMap = new HashMap<>();


public PlayStore(Activity activity) {
this.activity = activity;

Expand Down Expand Up @@ -212,4 +213,50 @@ public boolean requestReview() {

return true;
}

@Override
public boolean consumePurchase(String sku) {
try {
Log.i("iap", "consumePurchase " + sku);
finished = false;

billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
new PurchasesResponseListener() {
@Override
public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (Purchase p : purchases) {
if (p.getProducts().contains(sku) && p.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(p.getPurchaseToken())
.build();
billingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
@Override
public void onConsumeResponse(@NonNull BillingResult billingResult, @NonNull String purchaseToken) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i("iap", "Successfully consumed " + sku);
purchased.remove(sku);
} else {
Log.e("iap", "Failed to consume " + sku);
Copy link

Copilot AI Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the error case is hit (line 244), the error is logged but the finished flag is not set until after the sleep. Additionally, if the query fails but no matching purchase is found, finished is set to true at line 259, but if a matching purchase is found and consumption begins, the early return at line 255 means the line 259 will never execute. This is correct, but the error logging at line 244 should include more details about the failure (e.g., billingResult.getDebugMessage()).

Suggested change
Log.e("iap", "Failed to consume " + sku);
Log.e("iap", "Failed to consume " + sku + ": " + billingResult.getDebugMessage());

Copilot uses AI. Check for mistakes.
}
finished = true;
}
});
return;
}
}
}
finished = true;
}
}
);

return true;
} catch (Exception e) {
finished = true;
Log.e("iap", "consumePurchase failed.", e);
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,11 @@ public boolean requestReview() {
return false;
}

public void addConsumableSKU(String sku) {
skus.add(sku);
}

public boolean consumePurchase(String sku) {
return false;
}
}