All articles
Playbook8 min read

Each renewal gets its own Google Play order ID, and that's the number to check before you refund anyone

A Google Play order ID like GPA.1234-5678-9012-34567..2 names one exact charge. Here's how to read the renewal suffix, look an order up in Play Console or the Orders API, and refund the charge the customer means without paying for the wrong one.

A developer at a desk comparing an emailed receipt on an Android phone with an order list on a laptop, matching a Google Play order ID to the right charge

Key takeaways

  • A Google Play order ID looks like GPA.1234-5678-9012-34567, and subscription renewals add a suffix, so GPA.1234-5678-9012-34567..0 is the first renewal of that subscription.
  • The Play Billing Library's getOrderId() returns the order ID of the initial order for subscription renewals, not the renewal's own ID, and returns null while a purchase is in the PENDING state.
  • Google added get and batchGet to the Play Developer API's Orders resource on May 21, 2025. batchGet accepts 1 to 1,000 distinct order IDs and fails the whole request if any one of them isn't found.
  • An Order from the Orders API carries a state of PENDING, PROCESSED, CANCELED, PENDING_REFUND, PARTIALLY_REFUNDED or REFUNDED, plus developerRevenueInBuyerCurrency, which is net of partial refunds, taxes and fees.
  • Google Play's orders.refund method can't refund orders older than 3 years, and passing revoke=true ends the customer's access to the subscription or item immediately.
  • In Play Console, Refund and revoke applies to the most recent order in a subscription, while Refund only applies to an older order and leaves the subscription active.
  • Google Play handles refund requests within 48 hours of purchase itself. After 48 hours it sends customers to the developer, which is when an order ID usually lands in a support inbox.

Look at the end of the order number before you refund a Google Play customer. GPA.1234-5678-9012-34567 is the first charge on a subscription. GPA.1234-5678-9012-34567..2 is the third. They share a base, they're different payments, and Play Console treats them differently when you refund. The Google Play order ID is the only identifier your customer can see, so it's the one that ends up in your support inbox. Read it right and you refund the charge they're actually upset about, once.

What a Google Play order ID tells you

Google's Play Billing Library documentation gives the format by example. An order ID starts with GPA, then groups of digits. For subscriptions, each renewal gets the base order ID plus two dots and a counter that starts at zero. So the original purchase has no suffix, the first renewal is ..0, the second is ..1, and so on.

That makes the suffix a quick read on how long someone has paid. A customer writing in about GPA.3333-4137-0319-36762..11 has been renewed twelve times. A customer quoting the bare base ID either bought something once or is pointing at their very first payment.

Order IDWhat it is
GPA.1234-5678-9012-34567A one-time purchase, or the first charge on a subscription
GPA.1234-5678-9012-34567..0The first renewal of that subscription
GPA.1234-5678-9012-34567..1The second renewal
null in the Billing LibraryA purchase still in the PENDING state, before Google processes the payment

Where the order ID shows up, and which version you get

This is where teams trip. Different surfaces hand you different forms of the same ID.

  • The customer's Google Play receipt shows the order ID of the charge it's for, renewals included.
  • In your app, Purchase.getOrderId() from the Play Billing Library returns the order ID of the initial order for subscription renewals. Google's own example: instead of GPA.1234-5678-9012-34567..0, you get GPA.1234-5678-9012-34567.
  • On your server, purchases.subscriptionsv2 gives each line item a latestSuccessfulOrderId, the ID of the latest successful order for that item. Google added the field on May 21, 2025.
  • In the Voided Purchases API, orderId uniquely identifies a one-time purchase, a subscription purchase or a subscription renewal. Google's docs say to use orderId, not the purchase token, to tell renewals apart.

What the purchase token is for instead

The purchase token identifies the purchase as a whole. For a subscription, one token covers the original charge and every renewal after it. That's why it's the right key for entitlement and the wrong key for a refund. Refunds and chargebacks happen to a single charge, and only the order ID names a single charge.

How to look up a Google Play order

In Play Console

Order management accepts either an order ID or the customer's full email address in its search box. Each order shows one of these statuses: Processed, Cancelled, Pending, Pending refund, Refunded, Pending partial refund or Partially refunded. If the customer gives you an email instead of a receipt, search by email and pick the charge by date, then confirm the suffix before you act.

With the Orders API

Since May 21, 2025, the Orders resource in the Google Play Developer API has orders.get for one order and orders.batchget for a list. A few limits matter in practice:

  • batchget takes between 1 and 1,000 order IDs per request, and they must be distinct.
  • If any one order ID isn't found or doesn't belong to the package, the whole batchget request fails.
  • Orders API calls count against your Play Developer API quota, which defaults to 200,000 calls a day.

The Order you get back is the useful part. It has the order's state, its purchaseToken, createTime and lastEventTime, the total and the tax, a salesChannel such as IN_APP or PLAY_STORE, and an orderHistory with the processed, cancellation, refund and partial refund events. It also has developerRevenueInBuyerCurrency, which Google defines as your revenue in the buyer's currency, net of partial refunds, taxes and fees. When Google is the merchant of record, the buyer address carries only the country.

Order stateWhat Google's reference says
PENDINGCreated and waiting to be processed
PROCESSEDSuccessfully processed
CANCELEDCanceled before being processed
PENDING_REFUNDA requested refund is waiting to be processed
PARTIALLY_REFUNDEDPart of the order amount was refunded
REFUNDEDThe full order amount was refunded

Refunding the right order

Once you know which charge the customer means, Play Console gives you a choice that depends on where that order sits in the subscription.

OptionApplies toWhat happens
Refund and revokeThe most recent order in a subscriptionRefund issued, subscription removed immediately, future renewals canceled
Refund onlyAn older order in a subscriptionRefund issued, subscription stays active
Partial refundIn-app purchases and subscriptions ordered after March 2018, not paid appsAny percentage under 100%, or a pre-tax amount under the order total
Cancel subscriptionAn active subscriptionNo refund, access lasts until the current billing period ends

Through the API, orders.refund takes the package name and the order ID. Orders older than 3 years can't be refunded. The optional revoke parameter, set to true, ends access to the subscription or in-app item immediately. Google's help also notes that refunds can't be reversed once issued, so the order ID you pass is final.

Why does a $0.00 order show up for a subscriber?

Google's subscription lifecycle docs explain it. When a user signs up again from your app for the same base plan before their subscription expires, Google Play creates a $0.00 order. They aren't charged, because they already paid for the current period, and normal billing resumes on the original renewal date. It isn't a free trial or a promotion. There's nothing to refund on that order. If the customer wants money back, find the paid order before it.

What a wrong-order refund costs you

A refund returns the price. Partial refunds work the same way in proportion. Google's example: a 50% partial refund also takes back 50% of your payout and 50% of the service fee. What doesn't come back is everything you spent serving that customer, the compute, the third-party API calls, the storage, any affiliate payout. Refund the wrong order and you pay that twice.

Here's how that happens. A customer on a monthly plan writes in about the ..4 charge, the one from last week. Someone on your team searches by email, sees the first order at the top, and clicks Refund only on the base order from months ago. The customer now has money back for a period they used. The charge they complained about is untouched, and their subscription still renews. They can still ask their bank to reverse last week's charge.

Hands holding an Android phone over a printed bank statement and a pen, the moment a customer matches a charge to their Google Play order ID

That bank route is the expensive one now. For orders placed after August 3, 2026, Google says that when a chargeback goes through, the developer is responsible for the purchase price, less Play's service fee, plus the chargeback fees the bank charges. Chargebacks are final at the bank. One misread suffix can end as two refunds' worth of money gone, plus fees.

Which refunds never reach your inbox

Most Google Play refunds don't need you or the order ID at all. Google's refund policy says a customer may get a refund within 48 hours of purchase through Google Play, and after 48 hours should contact the developer. Google also refunds and revokes subscriptions you don't acknowledge within three days. You find out about those afterward through the Voided Purchases API, which reports the voidedSource (0 for User, 1 for Developer, 2 for Google) and a voidedReason such as Remorse, Chargeback or Unacknowledged_purchase.

Only one Google Play refund flow asks for your side. When a chargeback needs developer review, you have 24 hours to answer through orders.reviewrefund with a refund preference of APPROVE, DECLINE or NEUTRAL and purchase usage evidence. RefundHalt answers that review inside the window for you, using the usage data you already have, so a disputed order gets your evidence instead of silence.

A short checklist for order ID support tickets

  • Ask for the full order ID from the Google Play receipt, suffix included.
  • Look it up in Play Console or with orders.get and check its state first.
  • Confirm the charge date matches what the customer describes.
  • Use Refund and revoke only on the most recent order, and Refund only on older ones.
  • Record the order ID you refunded, so a later chargeback on another order is easy to spot.

Frequently asked questions

What does ..0 at the end of a Google Play order ID mean?
It marks the first renewal of a subscription. Google Play gives each renewal the subscription's base order ID plus two dots and a counter that starts at zero, so GPA.1234-5678-9012-34567..0 is the first renewal and ..1 is the second. The base ID with no suffix is the original charge.
Why does getOrderId() in my app return a different order ID than the customer's receipt?
Because the Play Billing Library returns the initial order's ID for subscription renewals. Google's example is that instead of GPA.1234-5678-9012-34567..0 for the first renewal, getOrderId() returns GPA.1234-5678-9012-34567. Use latestSuccessfulOrderId from purchases.subscriptionsv2 on your server to get the renewal's own ID.
How do I look up a Google Play order by order ID?
Search for it in Play Console's Order management, which accepts an order ID or the customer's full email address, or call orders.get in the Google Play Developer API. orders.batchget looks up 1 to 1,000 distinct order IDs at once, and the whole request fails if any one of them isn't found.
Can I refund a Google Play order that's more than a year old?
Yes, up to 3 years. Google's orders.refund reference says orders older than 3 years can't be refunded. For an older order in a subscription, Play Console's Refund only option returns the money and leaves the subscription active.
Why is there a $0.00 Google Play order for a subscriber?
It appears when a user signs up again from your app for the same base plan before their subscription expires. The user isn't charged because they already paid for the current period, and regular billing resumes on the original renewal date. Google says it doesn't mean a free trial or promotional discount was given.

Sources and further reading

RefundHalt

The refund autopilot for the App Store and Google Play

Keep reading

The next refund request is already on its way.

Set up RefundHalt in the time it takes to read another support email about a refund you didn't get to contest.