Google Play Billing (Subscriptions) for Android

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Google Play Billing (Subscriptions) for Android
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Implementing Google Play Billing (Subscriptions) for Android

With Google Play Billing Library 5, the subscription model was completely restructured. Base plans and offers emerged — this is not just a marketing rename, but a new object hierarchy: one ProductDetails contains multiple SubscriptionOfferDetails, each with its own offerToken. Old code that passed skuDetails.sku directly to BillingFlowParams does not compile with Billing 5+.

How the new model works

Subscription Product
├── Base Plan (monthly)
│   ├── Offer: "free-trial-7days" (offerToken_1)
│   └── Offer: "default" (offerToken_2)
└── Base Plan (annual)
    └── Offer: "default" (offerToken_3)

When launching a purchase, select a specific offerToken:

val productDetails = // from queryProductDetailsAsync
val offerToken = productDetails.subscriptionOfferDetails
    ?.firstOrNull { it.offerTags.contains("default") }
    ?.offerToken ?: return

val productDetailsParams = BillingFlowParams.ProductDetailsParams.newBuilder()
    .setProductDetails(productDetails)
    .setOfferToken(offerToken)
    .build()

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(listOf(productDetailsParams))
    .build()

billingClient.launchBillingFlow(activity, billingFlowParams)

If you pass an offerToken from one base plan, and the user already has a subscription to another — this is an upgrade/downgrade, Google handles it automatically when specifying setSubscriptionUpdateParams.

Grace period and account hold

Unlike iOS, Google Play has two states after payment expires:

  • Grace period (1–3 days) — subscription is technically active, Google tries to charge
  • Account hold (up to 30 days) — after grace, subscription is paused, Google continues trying

Handle both correctly through purchases.subscriptions.get in Google Play Developer API. The paymentState field: 0 = payment pending, 1 = payment received, 2 = free trial, 3 = pending deferred upgrade.

On the client — through purchase.purchaseState and additionally through Real-Time Developer Notifications (Pub/Sub):

// Example RTDN payload for account hold
{
  "subscriptionNotification": {
    "notificationType": 5,  // SUBSCRIPTION_ON_HOLD
    "purchaseToken": "...",
    "subscriptionId": "premium_monthly"
  }
}

Notification types that must be handled: SUBSCRIPTION_RENEWED (1), SUBSCRIPTION_CANCELED (3), SUBSCRIPTION_ON_HOLD (5), SUBSCRIPTION_IN_GRACE_PERIOD (6), SUBSCRIPTION_RESTARTED (7), SUBSCRIPTION_REVOKED (12), SUBSCRIPTION_EXPIRED (13).

Proration on plan change

When switching between base plans — specify ProrationMode:

val updateParams = BillingFlowParams.SubscriptionUpdateParams.newBuilder()
    .setOldPurchaseToken(currentPurchaseToken)
    .setSubscriptionReplacementMode(
        BillingFlowParams.SubscriptionUpdateParams.ReplacementMode.WITH_TIME_PRORATION
    )
    .build()

WITH_TIME_PRORATION — most fair for the user: the remainder of the current period is recalculated into days of the new plan. IMMEDIATE_WITHOUT_PRORATION — instant transition without refund.

Workflow

Set up base plans and offers in Play Console → integrate Billing Library 6+ → handle all purchaseState on the client → configure RTDN through Google Cloud Pub/Sub → server-side status synchronization → testing through licensed testers with expiry simulation.

Estimated time — 3–5 days depending on the number of pricing plans and the presence of a server component for RTDN.