Voided Purchases API

The Google Play Voided Purchases API provides a list of in-app 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 in-app orders.

This API applies to Purchases. For Subscriptions, see Real-time Developer Notifications.

The user can void a purchase in the following ways:

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

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 associated with in-app orders. 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/v2/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 of an in-app product 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 an in-app product 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.

The response is a JSON string that contains a list of voided purchases related to in-app orders. 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 of an in-app product.

{
  "tokenPagination": {
    "nextPageToken": "next_page_token"
  },
  "voidedPurchases": [
    {
      "kind": "androidpublisher#voidedPurchase",
      "purchaseToken": "some_purchase_token",
      "purchaseTimeMillis": "1468825200000",
      "voidedTimeMillis": "1469430000000"
    },
    {
      "kind": "androidpublisher#voidedPurchase",
      "purchaseToken": "some_other_purchase_token",
      "purchaseTimeMillis": "1468825100000",
      "voidedTimeMillis": "1470034800000"
    },
  ]
}

Quotas

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

  • 500 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 100,000 voided purchases.
  • If a response includes a value for nextPageToken, assign this value to the token parameter during your next request.
  • Minimize your experimentation with values of optional request parameters, as bad requests still count toward each quota.

Best Practices

As you determine how to use 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.