Guide · Chapter 4 of 4

Refunds, revocation, and voided purchases

A cancellation stops the next charge. A refund takes back a charge already made. The entitlement has to tell those apart, because one keeps access until the period ends and the other usually does not.

Two Google Play signals

Refunds are issued by Google or from Play Console; Tierux reacts to the notification Play sends afterwards. There are two shapes:

Both write the same effect: status cancelled, access off immediately, and a refund event on the billing timeline and, if you have configured one, your outbound webhook. Neither waits for expiresAt. That is the difference from a plain cancellation, which writes cancelled but leaves access on — see the table in chapter 1.

// src/services/rtdnProcessor.ts
case 12: // SUBSCRIPTION_REVOKED — immediate revoke (refund/chargeback)
  return { status: 'cancelled', active: false };

Partial refunds and one-time products

A voided purchase revokes access the same way regardless of its product type or refund type. A QUANTITY_BASED_PARTIAL_REFUND is treated like a full refund. The refund type is kept on the record as the raw store status, so you can see which kind it was when investigating.

The voided-purchase path is also how a refunded one-time product loses its entitlement. Play's one-time product notifications (purchased, canceled) do not change entitlements in Tierux; a one-time entitlement is granted at verify time, and a voided-purchase notification revokes it.

If your business rules call for something softer than "access off" on a partial refund — keeping a consumable balance, say — implement it on your side from the refund webhook event and the entitlement you read back.

Guards that still apply

The win-back flag is not cleared on a Google Play refund

On Google Play, the revoke and voided-purchase effects set status and access but do not touch winbackPending. If a subscriber cancelled — which arms the flag when the product has a cancellation offer — and was then refunded, the entitlement can read active: false with winbackPending: true until a later event clears it (an expiry notification does). The Android SDK's showWinback decides eligibility from winbackPending alone, so check active yourself before calling it from your cancel action. How the flag is armed is covered in the cancellation win-back chapter; win-back is implemented for Google Play and not yet for the App Store.

A dashboard revoke is not a refund

For support cases, a developer can revoke a subscriber's entitlement from the Tierux dashboard. That writes cancelled with access off and adds a cancellation_pending entry to the timeline. It does not refund the subscriber and does not cancel their store subscription — the response says so explicitly, and directs you to Play Console or App Store Connect for the billing side. Use it to stop access; use the store to move money.

On the App Store

Apple's REFUND and REVOKE notifications map to the same effect — cancelled, access off, a refund event — and additionally clear winbackPending. Apple can also reverse a refund: REFUND_REVERSED restores active with access on, with no timeline event of its own. The App Store notification path is implemented with limitations — see the platform support matrix.

Related reading

Glossary: Refund

Refund versus cancellation, and why the access result depends on the product.

Glossary: Entitlement

The access record a verified reversal changes.

Docs: Webhooks

Receiving the refund event on your own backend.

Feature: RTDN webhooks

Lifecycle events, refunds included, applied without polling.

Guide: Cancellation win-back with RTDN

The save-sheet flag this chapter warns about.

← Back to the subscription lifecycle guide

Refunds that revoke access on time

Free tier — unlimited apps, 1 paywall. No credit card, no revenue share.

Start free