Android · Arazzo Workflow

Android Reconcile Voided Purchases

Version 1.0.0

Poll the voided purchases feed for refunds and chargebacks, then re-verify each token so revoked entitlements can be clawed back.

1 workflow 1 source API 1 provider
View Spec View on GitHub Artificial IntelligenceAndroidAutomotiveGoogleMachine-LearningMobile DevelopmentSDKTVWearablesArazzoWorkflows

Provider

android

Workflows

reconcile-voided-purchases
List voided purchases for a window and re-verify a voided token before clawing back its entitlement.
Lists purchases that were cancelled, refunded, or charged back within the supplied window, ends cleanly when the window is empty, and otherwise reads the first voided purchase token back through the product purchase endpoint to confirm its current state before revoking access internally.
2 steps inputs: endTime, maxResults, packageName, productId, startTime, type outputs: nextPageToken, totalResults, verifiedVoidedOrderId, voidedPurchases
1
listVoided
Read the voided purchases feed for the requested window. This is the authoritative source for refunds and chargebacks that your app never saw.
2
verifyVoidedPurchase
Re-read the first voided purchase token against the product purchase endpoint to confirm Google Play's current view of it before revoking the user's entitlement in your own system.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Android Reconcile Voided Purchases
  summary: Poll the voided purchases feed for refunds and chargebacks, then re-verify each token so revoked entitlements can be clawed back.
  description: >-
    Refunds and chargebacks that happen outside your app — through Google Play
    support, the user's own refund request, or a card chargeback — never reach
    your backend as a client event. The voided purchases feed is the only way to
    learn about them, and failing to poll it is how apps end up granting
    permanent entitlements to users who were fully refunded. This workflow reads
    the voided feed for a time window, then re-verifies the first voided token
    against the product purchase endpoint so the entitlement can be revoked in
    your own system with confirmation from Google Play rather than on the
    strength of the feed alone. Every step spells out its request inline so the
    flow can be read and executed without opening the underlying OpenAPI
    description.
  version: 1.0.0
  x-realizes-capability-ids:
  - BC-4240.70
  x-capability-derivation:
    method: 'deterministic join: sourceDescriptions -> per-tag OpenAPI -> tag/capability edge. No classification at this step.'
    min_confidence: 0.7
    sources:
    - capability_id: BC-4240.70
      capability_name: Entitlement Enforcement
      spec: android-purchases-api-openapi.yml
      confidence: 0.7
    model: Turbo EA Capabilities by Vincent Verdet — Turbo EA, https://github.com/vincentmakes/turbo-ea-capabilities, CC BY 4.0
sourceDescriptions:
- name: purchasesApi
  url: ../openapi/android-purchases-api-openapi.yml
  type: openapi
workflows:
- workflowId: reconcile-voided-purchases
  summary: List voided purchases for a window and re-verify a voided token before clawing back its entitlement.
  description: >-
    Lists purchases that were cancelled, refunded, or charged back within the
    supplied window, ends cleanly when the window is empty, and otherwise reads
    the first voided purchase token back through the product purchase endpoint
    to confirm its current state before revoking access internally.
  inputs:
    type: object
    required:
    - packageName
    properties:
      packageName:
        type: string
        description: The package name of the application (e.g. com.example.myapp).
      startTime:
        type: string
        description: >-
          Milliseconds since the Epoch of the oldest voided purchase to return.
          Defaults to 30 days before now when omitted.
      endTime:
        type: string
        description: >-
          Milliseconds since the Epoch of the newest voided purchase to return.
      maxResults:
        type: integer
        description: Maximum number of voided purchases to return. Maximum is 1000.
      type:
        type: integer
        description: >-
          Which voided purchases to return: 0 for voided in-app product
          purchases, 1 for voided subscription purchases.
      productId:
        type: string
        description: >-
          The in-app product SKU used to re-verify a voided token in the second
          step.
  steps:
  - stepId: listVoided
    description: >-
      Read the voided purchases feed for the requested window. This is the
      authoritative source for refunds and chargebacks that your app never saw.
    operationId: listVoidedPurchases
    parameters:
    - name: packageName
      in: path
      value: $inputs.packageName
    - name: startTime
      in: query
      value: $inputs.startTime
    - name: endTime
      in: query
      value: $inputs.endTime
    - name: maxResults
      in: query
      value: $inputs.maxResults
    - name: type
      in: query
      value: $inputs.type
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      voidedPurchases: $response.body#/voidedPurchases
      firstVoidedToken: $response.body#/voidedPurchases/0/purchaseToken
      firstVoidedOrderId: $response.body#/voidedPurchases/0/orderId
      firstVoidedReason: $response.body#/voidedPurchases/0/voidedReason
      firstVoidedSource: $response.body#/voidedPurchases/0/voidedSource
      nextPageToken: $response.body#/tokenPagination/nextPageToken
      totalResults: $response.body#/pageInfo/totalResults
    onSuccess:
    - name: voidedPurchasesFound
      type: goto
      stepId: verifyVoidedPurchase
      criteria:
      - context: $response.body
        condition: $.voidedPurchases.length > 0
        type: jsonpath
    - name: nothingVoided
      type: end
      criteria:
      - context: $response.body
        condition: $.voidedPurchases.length == 0
        type: jsonpath
  - stepId: verifyVoidedPurchase
    description: >-
      Re-read the first voided purchase token against the product purchase
      endpoint to confirm Google Play's current view of it before revoking the
      user's entitlement in your own system.
    operationId: getPurchaseProduct
    parameters:
    - name: packageName
      in: path
      value: $inputs.packageName
    - name: productId
      in: path
      value: $inputs.productId
    - name: token
      in: path
      value: $steps.listVoided.outputs.firstVoidedToken
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      purchaseState: $response.body#/purchaseState
      consumptionState: $response.body#/consumptionState
      orderId: $response.body#/orderId
      obfuscatedExternalAccountId: $response.body#/obfuscatedExternalAccountId
  outputs:
    voidedPurchases: $steps.listVoided.outputs.voidedPurchases
    totalResults: $steps.listVoided.outputs.totalResults
    nextPageToken: $steps.listVoided.outputs.nextPageToken
    verifiedVoidedOrderId: $steps.verifyVoidedPurchase.outputs.orderId

Work with this as data

Every workflow here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for arazzo workflows

4 MCP tools reach this
  • find_arazzoBrowse and filter every workflow in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This workflow
curl "https://apis.io/api/v1/arazzo/android-reconcile-voided-purchases-workflow"
All arazzo workflows
curl "https://apis.io/api/v1/arazzo?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.