Skip to content

Handling Dynamic Pricing Structures in Google Play Subscriptions

Jean-Christophe Hoelt edited this page Sep 27, 2024 · 1 revision

Issue Overview

Changes in subscription details in Google Play Console (such as modifying the title) can unexpectedly alter the structure of product details returned by the Google Play Billing Library. This can lead to incorrect pricing display in your app, potentially showing subscriptions as "FREE" when they are not.

Symptoms

  • Subscriptions suddenly appearing with an unwanted price in your app
  • Inconsistent pricing display between test devices and production users
  • App submission rejections due to incorrect pricing display

Root Cause

Google Play caches product details on a per-account basis. When subscription details are changed in the Play Console, Google may update and recache the product details object, potentially changing its structure. This can affect the number and order of offers returned for a product.

Detection and Debugging

  1. Test with multiple Google accounts, including newly created ones.
  2. Use logcat or Google Chrome Inspector to observe the full structure of returned product details.
  3. Be aware that your regular test account may not reflect recent changes due to caching.

Code Example - Problematic Approach

let product = this.store.get(subscriptionKey, CdvPurchase.Platform.GOOGLE_PLAY);
let price = product.offers[0].pricingPhases[0].price;

This approach assumes a consistent structure and may fail if the structure changes.

Recommended Solution

Implement a more robust method. For example:

  • Display all available offers and detail the pricing phases ("FREE for 3 days, then X per week").
  • Allow your server to filter out some offers.
function renderOffersForProduct(product) {
    if (!product || !product.offers) {
        renderNoOfferAvailableForPurchase();
    }
    else {
        for (const offer of product.offers) {
            renderOffer(offer);
        }
    }
}

let product = this.store.get(subscriptionKey, CdvPurchase.Platform.GOOGLE_PLAY);
renderOffersForProduct(product);

Best Practices

  1. Robust Parsing: Don't assume a fixed structure for product offers. Implement flexible parsing logic.
  2. Comprehensive Testing: Test with multiple Google accounts, including fresh ones, to ensure you're seeing up-to-date data structures.
  3. Error Handling: Implement error handling and fallback mechanisms for pricing display.
  4. Regular Verification: Periodically verify that your app displays correct pricing in production environments.
  5. Logging: Make it possible to enable detailed logging in production to catch and analyze issues.

Additional Resources