Back to the RevenueCat homepage
Google Play Billing

Appendix A: Complete RTDN Reference Table

This appendix provides a complete reference for all Real Time Developer Notification (RTDN) types. Use this as a quick lookup when building your notification handler.

RTDN Message Structure

Every RTDN message arrives as a Cloud Pub/Sub message with a base64 encoded JSON payload in the data field. The decoded JSON has this structure:

kotlin
// Top-level DeveloperNotification
{
  "version": "1.0",
  "packageName": "com.example.app",
  "eventTimeMillis": "1234567890123",
  // One of the following (mutually exclusive):
  "subscriptionNotification": { ... },
  "oneTimeProductNotification": { ... },
  "voidedPurchaseNotification": { ... },
  "testNotification": { ... }
}

Only one notification field is present per message.

Subscription Notification Types

Code

Type

Trigger

Subscription State After

Required Action

1

SUBSCRIPTION_RECOVERED

Payment recovered from grace period, account hold, or pause resumes

ACTIVE

Grant access. Call subscriptionsv2.get to confirm state.

2

SUBSCRIPTION_RENEWED

Active subscription successfully renewed

ACTIVE

Extend entitlement. Update expiryTime in your database.

3

SUBSCRIPTION_CANCELED

Subscription canceled (user, developer, or system)

CANCELED

Check canceledStateContext for reason. User retains access until expiryTime.

4

SUBSCRIPTION_PURCHASED

New subscription purchased

ACTIVE

Verify purchase. Grant access. Acknowledge within 3 days.

5

SUBSCRIPTION_ON_HOLD

Grace period expired, entered account hold

ON_HOLD

Revoke access. Notify user to fix payment method.

6

SUBSCRIPTION_IN_GRACE_PERIOD

Renewal payment failed, entered grace period

IN_GRACE_PERIOD

Retain access. Notify user about payment issue. Show in app message.

7

SUBSCRIPTION_RESTARTED

User restored canceled subscription from Play Store before expiration

ACTIVE

Grant access. Same purchase token.

8

SUBSCRIPTION_PRICE_CHANGE_CONFIRMED

(Deprecated) User confirmed a price change

No state change

Deprecated. Use type 19 instead.

9

SUBSCRIPTION_DEFERRED

Subscription billing date extended via subscriptionsv2.defer

ACTIVE

Update expiryTime in your database. Extend access.

10

SUBSCRIPTION_PAUSED

Subscription paused (effective at end of current period)

PAUSED

Revoke access when pause begins.

11

SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED

Pause schedule modified (pause set, changed, or removed)

Varies

Call API to check current pause schedule.

12

SUBSCRIPTION_REVOKED

Subscription revoked (refund, developer revocation)

EXPIRED

Immediately revoke access.

13

SUBSCRIPTION_EXPIRED

Subscription expired after cancellation or account hold failure

EXPIRED

Revoke access. Clean up entitlement records.

17

SUBSCRIPTION_ITEMS_CHANGED

Items in subscription bundle changed (add ons)

Varies

Call API to get updated line items.

18

SUBSCRIPTION_CANCELLATION_SCHEDULED

Installment subscription cancellation scheduled at end of commitment

ACTIVE (until commitment ends)

Note the scheduled cancellation. User retains access through commitment period.

19

SUBSCRIPTION_PRICE_CHANGE_UPDATED

Price change details updated for existing subscribers

Varies

Call API to get updated price change information.

20

SUBSCRIPTION_PENDING_PURCHASE_CANCELED

Pending subscription purchase was canceled

EXPIRED

Do not grant access. Clean up any pending records.

22

SUBSCRIPTION_PRICE_STEP_UP_CONSENT_UPDATED

Price step up consent period begun or user provided consent (South Korea)

Varies

Call API to check consent status.

Note: Notification type codes 14, 15, 16, and 21 are not assigned. Do not expect to receive these values.

Subscription Notification Payload

kotlin
{
  "version": "1.0",
  "notificationType": 4,
  "purchaseToken": "purchase-token-string",
  "subscriptionId": "premium_monthly"
}

One Time Product Notification Types

Code

Type

Trigger

Required Action

1

ONE_TIME_PRODUCT_PURCHASED

One time product purchase completed

Verify purchase. Grant access. Acknowledge or consume.

2

ONE_TIME_PRODUCT_CANCELED

Pending one time product purchase was canceled

Do not grant access. Clean up pending records.

One Time Product Notification Payload

kotlin
{
  "version": "1.0",
  "notificationType": 1,
  "purchaseToken": "purchase-token-string",
  "sku": "remove_ads"
}

Note that one time product notifications include the sku field (the product ID), while subscription notifications include subscriptionId.

Voided Purchase Notification

Voided purchase notifications are sent when a purchase is voided due to a refund, chargeback, or revocation.

kotlin
{
  "purchaseToken": "purchase-token-string",
  "orderId": "GPA.1234-5678-9012-34567",
  "productType": 1,
  "refundType": 1
}

Field

Values

productType

1 = Subscription, 2 = One time product

refundType

1 = Full refund, 2 = Quantity based refund

When you receive a voided purchase notification, revoke access immediately and call the Voided Purchases API for full details.

Test Notification

kotlin
{
  "version": "1.0"
}

Test notifications have only a version field inside the testNotification object. Your handler should acknowledge these without processing them as real events.

Handler Pattern

Every RTDN handler should follow this pattern:

  1. Receive the Pub/Sub message
  2. Decode the base64 data field
  3. Parse the JSON DeveloperNotification
  4. Identify the notification type (subscription, one time, voided, or test)
  5. Extract the purchaseToken
  6. Call the Google Play Developer API to get the full, current state
  7. Update your database based on the API response (not the notification alone)
  8. Acknowledge the Pub/Sub message

Never rely solely on the RTDN payload for business logic. RTDNs signal that something changed. The API tells you what the current state is. Always call the API.

Want a simpler approach?

The RevenueCat SDK Handbook covers the same topics — with less code and a managed backend.

Related chapters

  • Chapter 10: Real Time Developer Notifications (RTDN)

    Cloud Pub/Sub setup, all 16+ notification types, idempotent handlers, and the "always call the API" rule.

    Learn more
  • Chapter 11: The Subscription State Machine

    Seven states (ACTIVE through PENDING), every transition, which states grant access, and queryPurchasesAsync() behavior.

    Learn more
  • Chapter 9: Backend Architecture for Billing

    The 7-step server verification flow: receive token, call the API, check signatures, grant entitlements, acknowledge.

    Learn more
Complete RTDN Reference Table | RevenueCat