---
title: "What does the Google Play notification SUBSCRIPTION_IN_GRACE_PERIOD mean?"
description: "SUBSCRIPTION_IN_GRACE_PERIOD (6) means a renewal payment failed and the subscription entered its grace period. Keep access and prompt the customer to fix payment."
url: https://revenuedot.app/docs/notifications/google-subscription-in-grace-period
---

# What does the Google Play notification SUBSCRIPTION_IN_GRACE_PERIOD mean?

The Google Play notification SUBSCRIPTION_IN_GRACE_PERIOD means a renewal payment failed, but the customer keeps access during the grace period.

## Quick facts

| | |
|---|---|
| Notification | `subscriptionNotification.notificationType` 6, `SUBSCRIPTION_IN_GRACE_PERIOD` |
| Where | Google Play real-time developer notifications (Pub/Sub, `DeveloperNotification`) |
| Sent by | Google Play, as a Cloud Pub/Sub push to your endpoint |
| What Google says | A subscription has entered the grace period, if the grace period is enabled. |

## What triggers it

- A renewal payment failed and the base plan has a grace period. Google enables it by default on auto-renewing base plans.
- Google waits at least one day before the notification even with a grace period of zero days, to leave time for payment retries.
- The subscription resource has state `SUBSCRIPTION_STATE_IN_GRACE_PERIOD` and `expiryTime` stays in the past until the grace period ends, but entitlement should last.

## What your server should do

1. Do not trust the message for the state. Google says a notification only tells you the purchase state changed; call the Google Play Developer API (`purchases.subscriptionsv2.get`) with the purchase token to get the full state.
2. Keep access while the grace period runs.
3. Encourage the customer to fix their payment method, with a message in your app.
4. Expect `SUBSCRIPTION_RECOVERED` or `SUBSCRIPTION_RENEWED` on success, or `SUBSCRIPTION_ON_HOLD` when the grace period ends.
5. Answer 2xx once you have handled the message, and skip a `messageId` you have seen: Google recommends checking the uniqueness of message IDs so a redelivery does not make a second API call.

## Example

```javascript
// A Pub/Sub push body: the notification is base64 JSON in message.data.
const body = { message: { messageId: "136969346945", data: Buffer.from(JSON.stringify({"version":"1.0","packageName":"com.example.app","eventTimeMillis":"1790800914000","subscriptionNotification":{"version":"1.0","notificationType":6,"purchaseToken":"PURCHASE_TOKEN"}})).toString("base64") } };

function decide(body) {
  const n = JSON.parse(Buffer.from(body.message.data, "base64").toString("utf8"));
  if (!(n.subscriptionNotification?.notificationType === 6)) return "ignore";
  return "keep access, show a fix-payment message";
}

console.log(decide(body));
```

*Run-checked: `npm run check:snippets` runs this snippet with Node and compares its output with `keep access` (checked 2026-10-03).*

## How RevenueDot handles it

RevenueDot answers every handled message with 2xx and every temporary failure with 5xx so Pub/Sub redelivers it. For subscription types it re-reads the subscription from Google with `purchases.subscriptionsv2.get` and applies that state, and it acknowledges a new purchase if the app has not. A purchase RevenueDot has not seen is applied only when the app's **Track new purchases from server-to-server notifications** setting is on. RevenueDot stores a billing issue with the grace period end set to the line item's expiry, so access continues. It sends `BILLING_ISSUE` with `grace_period_expiration_at_ms` and a `CANCELLATION` with `cancel_reason: BILLING_ERROR`. If access later ends, `EXPIRATION` follows.

## Related

- [What does the Google Play notification SUBSCRIPTION_ON_HOLD mean?](https://revenuedot.app/docs/notifications/google-subscription-on-hold.md)
- [What does the Google Play notification SUBSCRIPTION_RECOVERED mean?](https://revenuedot.app/docs/notifications/google-subscription-recovered.md)
- [What does the Google Play notification SUBSCRIPTION_RENEWED mean?](https://revenuedot.app/docs/notifications/google-subscription-renewed.md)
- [Which webhook events does RevenueDot send?](https://revenuedot.app/docs/api/webhook-events.md)
- [Set up Google Play notifications in RevenueDot](https://revenuedot.app/docs/guides/google-play.md)

## Source

- [Google: Real-time developer notifications reference guide](https://developer.android.com/google/play/billing/rtdn-reference)
- [Google: Subscription lifecycle](https://developer.android.com/google/play/billing/lifecycle/subscriptions)
- [RevenueDot server: stores/google/notifications.ts (how the message is received)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/stores/google/notifications.ts)
- [RevenueDot server: stores/google/sync.ts (how the purchase is re-read and applied)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/stores/google/sync.ts)
- [RevenueDot server: stores/google/map.ts (how Google's state becomes a stored purchase)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/stores/google/map.ts)
- [RevenueDot core: events.ts (how a change becomes a webhook event)](https://github.com/revenuedot/revenuedot/blob/main/packages/core/src/events.ts)
- [RevenueDot server: services/tick.ts (the scheduled EXPIRATION)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/services/tick.ts)

Checked: 2026-10-03
