Quando uma compra do Google Play é reembolsada ou estornada, a Voided Purchases API é como você fica sabendo
O Google Play anula uma compra silenciosamente quando ela é reembolsada ou estornada. A Voided Purchases API é a lista desses pedidos, para que você possa revogar o acesso. Aqui estão todos os campos, a janela de 30 dias, a opção de revogação que oculta pedidos e quanto custa.

Principais conclusões
- A Voided Purchases API, o método purchases.voidedpurchases.list, retorna pedidos que o Google Play cancelou, reembolsou ou estornou, para que você possa construir um sistema de revogação que corta o acesso ao que o cliente não possui mais.
- Apenas pedidos revogados aparecem. Um reembolso emitido pelo desenvolvedor sem a opção de revogação é invisível para esta API, então, se você quer retirar o acesso, precisa reembolsar com a revogação ativada.
- A janela é de 30 dias. startTime não pode ser mais antigo que 30 dias atrás, então um servidor que fica fora do ar por mais de um mês perde esses pedidos anulados para sempre. Faça a consulta em um cronograma.
- voidedSource informa quem anulou o pedido: 0 é o usuário, 1 é o desenvolvedor, 2 é o Google. voidedReason informa o motivo, de 0 Other até 7 Chargeback e 8 Unacknowledged_purchase.
- As Real-time developer notifications enviam uma VoidedPurchaseNotification no momento em que uma compra é anulada, mas trate isso como um sinal. Chame a Voided Purchases API para obter a lista oficial antes de revogar.
- Identifique renovações de assinatura por orderId, não por purchaseToken. Um purchaseToken cobre todas as renovações de uma assinatura, então o token sozinho não consegue distinguir duas renovações.
- As cotas são de 6.000 consultas por dia e 30 consultas em qualquer janela de 30 segundos, então percorra os resultados com o token de continuação e consulte por janela de tempo, nunca uma chamada por pedido.
Um reembolso no Google Play não bate na sua porta. O dinheiro sai, o cliente continua com o app aberto e, a menos que você vá procurar, nada muda do seu lado. A Voided Purchases API é onde você vai procurar. Ela lhe entrega uma lista de pedidos que foram cancelados, reembolsados ou estornados, para que você possa revogar o acesso ao que o cliente não pagou mais. Aponte um job agendado para ela, leia a lista, corte o direito de acesso. Esse é o ciclo inteiro.
Há uma pegadinha que atrapalha a maioria das equipes, e ela não está no código. Apenas pedidos que foram revogados aparecem aqui. Se você reembolsar uma compra no Play Console sem marcar a opção de revogação, esse pedido nunca chega a esta API, e seu job roda limpo enquanto um cliente reembolsado mantém tudo o que você vendeu. Este texto percorre a API campo por campo, os números que a limitam e onde o dinheiro vaza quando você a ignora.
O que a Voided Purchases API realmente retorna
A API responde a uma pergunta: quais pedidos deste app foram anulados recentemente. Uma anulação abrange três desfechos que terminam com o cliente recebendo o dinheiro de volta. Um cancelamento, um reembolso ou um estorno. Ela se aplica a produtos avulsos dentro do app e a assinaturas, e você escolhe o escopo com um único parâmetro. Defina type como 0 e você obtém apenas as compras de produtos avulsos anuladas, que é o padrão. Defina como 1 e você obtém as compras avulsas anuladas e as compras de assinatura anuladas juntas.
Cada entrada na lista é um objeto de compra anulada. Os campos são poucos e cada um deles importa.
Os campos de uma compra anulada
| Campo | O que ele contém |
|---|---|
| orderId | O id do pedido que identifica de forma única uma compra avulsa, uma compra de assinatura ou uma única renovação de assinatura. Esta é sua chave de junção |
| purchaseToken | O token que identifica uma compra avulsa ou uma assinatura. Ele não distingue renovações, então use orderId para elas |
| purchaseTimeMillis | Quando a compra foi feita, em milissegundos desde a época |
| voidedTimeMillis | Quando a compra foi cancelada, reembolsada ou estornada, em milissegundos desde a época |
| voidedSource | Quem iniciou a anulação: 0 usuário, 1 desenvolvedor, 2 Google |
| voidedReason | Por que a compra foi anulada, um inteiro de 0 a 8 |
| voidedQuantity | A quantidade anulada de um reembolso parcial baseado em quantidade, retornada apenas quando includeQuantityBasedPartialRefund é true |
Leia voidedReason antes de agir
voidedReason é o campo que transforma uma lista crua em uma decisão. Um reembolso por arrependimento do comprador e um estorno bancário caem na mesma lista, mas não são o mesmo evento, e os preços de agosto tornam um deles caro. Aqui está o conjunto completo.
| voidedReason | Label | O que significa para você |
|---|---|---|
| 0 | Other | Nenhuma categoria foi atribuída. Revogue e siga em frente |
| 1 | Remorse | O comprador mudou de ideia. Um reembolso comum |
| 2 | Not_received | O cliente diz que nunca recebeu o produto. Vale checar sua entrega |
| 3 | Defective | O produto não funcionou. Um sinal de qualidade, registre |
| 4 | Accidental_purchase | Uma compra não intencional, muitas vezes um dispositivo compartilhado |
| 5 | Fraud | O Google marcou a transação como fraudulenta |
| 6 | Friendly_fraud | Um estorno em que o titular legítimo do cartão contesta uma cobrança que ele mesmo fez |
| 7 | Chargeback | O banco do cliente reverteu o pagamento. Final junto ao banco, e agora cobrado de você |
| 8 | Unacknowledged_purchase | O Google reembolsou automaticamente uma compra que seu app nunca reconheceu |
A janela de 30 dias é a armadilha que esvazia sua lista
A Voided Purchases API só consegue mostrar compras anuladas dos últimos 30 dias. O parâmetro startTime tem como padrão o horário atual menos 30 dias, e não pode ser definido mais antigo que isso. endTime tem como padrão agora. Então o endpoint é uma janela móvel de um mês, não um arquivo.
A consequência é direta. Se seu job de consulta quebrar e ninguém perceber por cinco semanas, as anulações da primeira semana envelheceram e saíram da API. Não há chamada que as traga de volta. Você não revogará esses pedidos, e nem saberá que existiram, a menos que os tenha capturado de outra forma. A API é uma rede de segurança com um buraco do tamanho da sua pior interrupção.
A opção de revogação decide se um pedido sequer aparece
Este é o motivo mais comum de uma equipe relatar que a API está quebrada. Apenas pedidos revogados são retornados. Reembolsos iniciados pelo usuário, cancelamentos, estornos e reembolsos iniciados pelo Google são sempre revogados, então sempre aparecem. Um reembolso iniciado pelo desenvolvedor é diferente. Quando você mesmo reembolsa um pedido, pelo Play Console ou pela Orders API, você escolhe se também o revoga. Reembolse sem revogar, e o pedido fica acertado com o cliente, mas nunca aparece na Voided Purchases API.
A regra que decorre disso é simples. Se sua intenção é retirar o acesso, reembolse com a opção de revogação ativada. Caso contrário, você devolveu o dinheiro e deixou a porta aberta, e seu job de revogação, por melhor que seja escrito, não tem nada sobre o que agir.
Como fazer a consulta sem estourar a cota
O endpoint tem limite de taxa, e os limites são baixos o suficiente para que um loop ingênuo os atinja. Você tem 6.000 consultas por dia, contadas no horário do Pacífico, e no máximo 30 consultas em qualquer período de 30 segundos. Esse orçamento é adequado para consulta por janela e hostil a designs de uma requisição por pedido.
Janelas de consulta e o token de continuação
maxResults tem como padrão 1.000, que também é o teto. Quando uma janela contém mais de uma página de anulações, a resposta traz um objeto tokenPagination com um nextPageToken. Passe esse token de volta na próxima chamada para percorrer as páginas. Defina startTime e endTime para delimitar a janela que lhe interessa, avance pelas páginas até o token acabar, então avance a janela. Esse padrão mantém você dentro tanto do limite de rajada de 30 segundos quanto do limite diário.
As Real-time developer notifications fecham a brecha
Consultar todos os dias ainda deixa até um dia de cegueira, e a janela de 30 dias pune longos intervalos. As Real-time developer notifications eliminam o atraso. O Google publica uma VoidedPurchaseNotification em um tópico do Cloud Pub/Sub que você possui no momento em que uma compra é anulada, e seu backend a consome em segundos. A mensagem é pequena.
| Campo da RTDN | O que ele contém |
|---|---|
| purchaseToken | O token da compra original |
| orderId | O id do pedido da transação anulada, um novo por renovação de assinatura |
| productType | 1 para uma assinatura, 2 para uma compra avulsa |
| refundType | 1 para um reembolso total, 2 para um reembolso parcial baseado em quantidade |

Quanto isso custa a você em dinheiro
A API é encanamento, mas o motivo para conectá-la é uma conta. Toda anulação naquela lista corresponde a um número real, e dois deles estão ficando mais caros.
A conta do estorno cai sobre você a partir de 3 de agosto de 2026
A partir de 3 de agosto de 2026, o Google transfere o custo de um estorno para o desenvolvedor. Você perde o valor da compra e ainda paga a taxa de estorno do banco por cima. Um voidedReason igual a 7 não é mais apenas uma venda perdida, é um item de linha com uma taxa anexada. Você não pode reverter um estorno, ele é final junto ao banco, mas pode estancar o sangramento depois dele. Capturar a anulação rapidamente permite revogar o direito de acesso e, para qualquer coisa que você ainda esteja entregando, parar de gastar com um cliente que foi reembolsado e depois teve a cobrança revertida.
Você continua pagando para atender um cliente reembolsado
O valor da compra some no momento em que uma anulação aparece. O que você ainda controla é o custo de continuar a entregar. A cada hora que um direito de acesso reembolsado permanece ativo, você continua pagando pelas coisas que o cliente não financia mais: computação, chamadas de API de modelos, armazenamento e qualquer repasse a criadores ou parceiros ligado ao uso dele. Um sistema de revogação movido por esta API é como você desliga esse medidor. Ignore-o, e você financia o produto para pessoas que a loja já ressarciu.
A fraude amistosa é um padrão que vale acompanhar
Um voidedReason igual a 5 ou 6 não é um caso isolado. Fraude e fraude amistosa se agrupam por conta, por dispositivo e às vezes por promoção. A API lhe dá o voidedSource e o voidedReason em cada anulação, o que basta para acompanhar o abuso por conta em vez de tratar cada reversão como um custo isolado. Um cliente que faz estorno duas vezes está lhe dizendo algo que o primeiro reembolso não disse.
Montando tudo do jeito RefundHalt
O modelo é pequeno quando você segura todas as peças. Escute a VoidedPurchaseNotification em tempo real para que nada espere um dia inteiro. Chame a Voided Purchases API como fonte da verdade, com chave em orderId para que as renovações de assinatura nunca se confundam. Leia o voidedSource e o voidedReason para que um estorno seja tratado de forma diferente de um reembolso por arrependimento. Faça a consulta em um cronograma apertado o suficiente para que a janela de 30 dias nunca morda, e reembolse com a opção de revogação ativada sempre que sua intenção for cortar o acesso.
Esta é a parte que o RefundHalt roda para você. Ele consome as notificações em tempo real, concilia cada anulação com a API, revoga o pedido exato em vez do produto inteiro e separa um estorno bancário de um reembolso comum para que os caros sejam sinalizados, não enterrados. Você tem o acesso revogado em segundos e um registro de quem anulou o quê e por quê, sem ter que montar você mesmo um pipeline de Pub/Sub e um job de consulta.
Perguntas frequentes
- Por que meus pedidos reembolsados não aparecem na Voided Purchases API?
- Porque apenas pedidos revogados são retornados. Reembolsos de usuário, cancelamentos, estornos e reembolsos iniciados pelo Google são sempre revogados e sempre aparecem. Um reembolso iniciado pelo desenvolvedor só aparece se você também escolheu a opção de revogação. Se você reembolsou um pedido sem revogá-lo, o pedido fica acertado, mas invisível para esta API, então reembolse com a revogação ativada sempre que pretender retirar o acesso.
- Quão para trás a Voided Purchases API vai?
- Trinta dias. O parâmetro startTime tem como padrão o horário atual menos 30 dias e não pode ser definido mais antigo que isso, então o endpoint é uma janela móvel de um mês, não um arquivo. Um pedido anulado que ultrapassa os 30 dias some da API sem forma de recuperá-lo, e é por isso que você faz a consulta em um cronograma e a reforça com notificações em tempo real.
- Devo usar as Real-time developer notifications ou a Voided Purchases API para revogar o acesso?
- Use ambas. A VoidedPurchaseNotification chega em segundos e diz para você olhar, mas a própria orientação do Google é tratá-la como um sinal, não como uma fonte da verdade. Chame a Voided Purchases API para confirmar o estado atual e então revogue. A notificação elimina o atraso, e a API lhe dá o voidedSource e o voidedReason oficiais sobre os quais agir.
- Como distingo um estorno de um reembolso comum na API?
- Leia o campo voidedReason. Um valor de 7 é um estorno, ou seja, o banco do cliente reverteu o pagamento, e 6 é fraude amistosa. Um valor de 1 é um reembolso por arrependimento. Isso importa porque, a partir de 3 de agosto de 2026, o Google repassa o valor da compra do estorno e a taxa do banco para o desenvolvedor, então um voidedReason igual a 7 custa mais a você do que um reembolso comum.
- A Voided Purchases API cobre assinaturas?
- Sim. Defina o parâmetro type como 1 para obter tanto as compras avulsas anuladas quanto as compras de assinatura anuladas. O padrão, type 0, retorna apenas compras de produtos avulsos. Para assinaturas, identifique o período anulado exato por orderId, porque um purchaseToken cobre todas as renovações e um novo orderId é gerado para cada transação de renovação.
Fontes e leituras adicionais
- Google Play Developer API: Voided Purchases API guide
- Google Play Developer API: purchases.voidedpurchases.list method
- Google Play Developer API: purchases.voidedpurchases resource (voidedSource and voidedReason)
- Android Developers: Real-time developer notifications reference (VoidedPurchaseNotification)
- Android Developers: Fight fraud and abuse with Play Billing
RefundHalt
O piloto automático de reembolsos para App Store e Google Play
Continue lendo
Três notificações de reembolso da App Store chegam depois que a Apple decide, e REFUND_REVERSED devolve a venda
A Apple envia quatro mensagens de reembolso pelo App Store Server Notifications V2, e a maioria dos apps trata apenas duas. REFUND diz para revogar, REFUND_DECLINED significa manter a venda, e REFUND_REVERSED devolve a venda e pede que você restaure o que retirou. Aqui está o que cada uma exige.
Toda solicitação de reembolso da Apple agora vem com um motivo, e o consumptionRequestReason é como você o lê
Desde a WWDC24, todo CONSUMPTION_REQUEST da Apple carrega um consumptionRequestReason, o motivo declarado pelo próprio cliente para querer o reembolso. São cinco valores, de UNINTENDED_PURCHASE a LEGAL, e cada um deve mudar o que você envia de volta dentro da sua janela de 12 hours. Veja como ler cada um deles.