Voided Purchases API

The Google Play Voided Purchases API provides a list of orders that are associated with purchases that a user has voided. You can use information from this list to implement a revocation system that prevents the user from accessing products from those orders.

This API applies to one-time in-app orders and App Subscriptions.

A purchase can be voided in the following ways:

  • The user requests a refund for their order.
  • The user cancels their order.
  • An order is charged back.
  • Developer cancels or refunds order.

  • Google cancels or refunds order.

By using this API, you help create a more balanced and fair experience for all of your app's users, particularly if your app is a game.

Gaining Access

To work with the Voided Purchases API, you need to have permission to view financial information. You provide authorization using an OAuth client or a service account. If you're using a service account, enable the "View financial reports" permission within this account.

To learn more about gaining authorized access to Google Play Developer APIs, see the following guides:

Viewing Voided Purchases

Use the GET method to request a list of voided purchases. In your request, include the fully-qualified package name for your app—such as com.google.android.apps.maps—and the authorization token you received when gaining access to the API.

GET https://www.googleapis.com/androidpublisher/v3/applications/
your_package_name/purchases/voidedpurchases?access_token=your_auth_token

You can also include the following parameters in your request, each of which is optional:

startTime

The time, in milliseconds since the Unix epoch, of the oldest voided purchase that you want to see in the response. By default, startTime is set to 30 days ago.

The API can only show voided purchases that have occurred during the past 30 days. Older voided purchases are not included in the response, regardless of the value that you've provided for startTime.

endTime

The time, in milliseconds since the Unix epoch, of the newest voided purchase of that you want to see in the response. By default, endTime is set to the current time.

maxResults
The maximum number of voided purchases that appear in each response. By default, this value is 1000. Note that the maximum value for this parameter is also 1000.
token
A continuation token from a previous response, allowing you to view more results.
type

The type of voided purchases that appear in each response. If set to 0, only voided in-app purchases will be returned. If set to 1, both voided in-app purchases and voided subscription purchases will be returned. Default value is 0.

includeQuantityBasedPartialRefund

Whether to include voided purchases of quantity-based partial refunds, which are applicable only to multi-quantity purchases. If true, additional voided purchases may be returned with voidedQuantity that indicates the refund quantity of a quantity-based partial refund. The default value is false.

The response is a JSON string that contains a list of voided purchases. If there are more results than the number specified in the maxResults request parameter , the response includes a nextPageToken value, which you can pass into a subsequent request to view more results. The first result in the list shows the oldest voided purchase.

{
  "tokenPagination": {
    "nextPageToken": "next_page_token"
  },
  "voidedPurchases": [
    {
      "kind": "androidpublisher#voidedPurchase",
      "purchaseToken": "some_purchase_token",
      "purchaseTimeMillis": "1468825200000",
      "voidedTimeMillis": "1469430000000",
      "orderId": "some_order_id",
      "voidedSource": "0",
      "voidedReason": "4"
    },
    {
      "kind": "androidpublisher#voidedPurchase",
      "purchaseToken": "some_other_purchase_token",
      "purchaseTimeMillis": "1468825100000",
      "voidedTimeMillis": "1470034800000",
      "orderId": "some_other_order_id",
      "voidedSource": "2",
      "voidedReason": "5"
    },
  ]
}

Quotas

The Voided Purchases API sets the following quotas on a per-package basis:

  • 6000 queries per day. (The day begins and ends at midnight Pacific Time.)
  • 30 queries during any 30-second period.

Guidelines for initial requests

During your initial API request, you may want to fetch all available data for your app. Although unlikely, this process could exhaust your daily quota. To obtain voided purchases data in a safer, more consistent manner, follow these best practices:

  • Use the default value for the maxResults parameter. That way, if you use your entire query quota for a day, you can retrieve the details of 6,000,000 voided purchases.
  • If a response includes a value for nextPageToken, assign this value to the token parameter during your next request.

Best Practices

When using this API in your app, remember that there are many reasons to void a purchase and that there is no single solution that works in all cases. You should keep your users in mind when designing your revocation policies and strategies. To do so, you can apply these recommended practices:

  • Use this API as one of many elements in a comprehensive strategy to address undesired behavior. Revoking access to in-app products is usually more effective when combined with an app that has reasonable prices for in-app purchases, an app design that discourages undesirable behavior, a strong user base whose culture rejects such behavior, and responsive and efficient user support channels.
  • Administer your revocation policy uniformly to ensure fairness for all users.
  • Consider creating a staged policy when addressing undesired behavior. For example, start with in-app warnings for early offenses, then escalate your responses as a user's undesired behavior continues. As a last resort, you can prevent a user from interacting with your app at all.
  • When you introduce a revocation policy, and each time you update it, use your app's outreach channels to inform your users about the changes. Give your users time to clearly understand these changes before they take effect in your app.
  • Be transparent to your users and inform them whenever you take action, such as revoking their access to an in-app product. Ideally, users should be able to dispute your decisions, and such disputes should be treated fairly.
  • Monitor feedback forms and community forums to understand what drives users to behave in undesirable ways and how they carry out such behavior. Act on these insights as a first line of defense.