Revogar Acesso Após um Reembolso: A Etapa que Apple e Google Não Fazem por Você
Apple e Google podem processar um reembolso enquanto o cliente continua com a compra. Veja exatamente quando o acesso é removido automaticamente, quando o seu servidor precisa fazer isso, e a notificação que quase nenhuma integração trata.

Principais conclusões
- No Google Play, reembolsar um pedido não remove o acesso do usuário por si só. O acesso só é removido quando a opção "Remove entitlement" é marcada no Play Console, ou quando a chamada de API passa revoke=true, o que não é o padrão.
- Um reembolso emitido sem a opção de revogação nunca aparece na Voided Purchases API. Um processo de revogação que lê apenas esse feed vai perder silenciosamente todos esses pedidos.
- A Apple pode revogar uma licença de itens não consumíveis e assinaturas automaticamente, mas um item consumível já é considerado entregue no momento em que é gasto, então o StoreKit não tem mecanismo para revogá-lo. O seu servidor precisa deduzir o saldo por conta própria.
- A Apple também pode desfazer o próprio reembolso. Uma notificação REFUND_REVERSED significa que um reembolso concedido anteriormente foi revertido, revocationDate volta para null, e qualquer acesso ou saldo que você removeu precisa ser restaurado.
- O campo voidedReason do Google carrega nove valores, de remorse e accidental_purchase até fraud, friendly_fraud e unacknowledged_purchase, então o mesmo feed que indica quando revogar acesso também indica quais revogações são fraude e quais são um bug na sua própria integração.
- Cada dia em que uma compra reembolsada mantém seu acesso é um dia em que você está pagando pelo processamento, armazenamento e chamadas de API por trás dela, com dinheiro que você já devolveu.
Aprovar um reembolso e remover o acesso são duas etapas separadas, e apenas uma delas acontece automaticamente. Desenvolvedores que presumem que um reembolso processado equivale a uma compra revogada estão errados nas duas principais lojas, de formas diferentes e por motivos diferentes. Saber exatamente onde a automação para é o que é preciso para revogar o acesso após um reembolso, em vez de descobrir meses depois que isso nunca aconteceu.
Por que um reembolso não revoga o acesso por padrão
Apple e Google tratam o dinheiro e o acesso como duas operações diferentes. O lado financeiro é política da loja: uma vez aprovado o reembolso, ele é final e o registro é atualizado. O lado do acesso é opcional, ou é trabalho do desenvolvedor, ou ambos, dependendo da plataforma e do tipo de compra. Nenhuma das lojas presume que você quer o acesso removido no instante em que o reembolso é concluído, porque muitos casos legítimos (um reembolso parcial, um crédito de cortesia, um gesto de suporte) não devem retirar o produto de forma alguma.
Google Play: a caixa de seleção que ninguém percebe
No Play Console, reembolsar um pedido é um formulário em duas partes: escolher o valor do reembolso e depois decidir separadamente se marca "Remove entitlement". Deixar essa opção desmarcada é o caminho padrão que a maioria dos agentes de suporte segue, porque a maior parte dos pedidos de reembolso são gestos de boa vontade em que o cliente mantém o que comprou. O problema é que nada na tela de confirmação do reembolso avisa que é assim também que um cliente mantém uma assinatura ou item dentro do aplicativo depois de um reembolso que você pretendia ser definitivo.
O caminho da API tem a mesma armadilha
A mesma escolha existe no código. O endpoint orders.refund aceita um parâmetro de consulta opcional chamado revoke; quando é true, o acesso ao item é encerrado imediatamente, e no caso de uma assinatura recorrente todo pagamento futuro é cancelado junto. Omitir o parâmetro faz com que ele assuma false por padrão: o reembolso é registrado, o registro da compra é atualizado, e o usuário continua usando o produto exatamente como antes.
| Ação | Acesso removido? | Aparece na Voided Purchases API? |
|---|---|---|
| Reembolso no Play Console, "Remove entitlement" desmarcado | Não | Não |
| Reembolso no Play Console, "Remove entitlement" marcado | Sim, imediatamente | Sim |
| API orders.refund, parâmetro revoke omitido (assume false por padrão) | Não | Não |
| API orders.refund, revoke=true | Sim, imediatamente | Sim |
Essa última linha é a que pega as integrações de surpresa. A Voided Purchases API existe para permitir que você construa um pipeline de revogação sem verificar o Play Console manualmente, mas ela só lista pedidos que foram efetivamente anulados com revogação. Um reembolso processado sem a caixa marcada, ou sem revoke=true, é invisível para esse feed por design, não por falha.

Lendo o campo voidedReason Quando uma compra aparece como anulada, o campo voidedReason informa o motivo, em uma escala de nove valores: other, remorse, not_received, defective, accidental_purchase, fraud, friendly_fraud, chargeback e unacknowledged_purchase. Isso não é apenas controle contábil. Remorse e accidental_purchase são reembolsos comuns. Fraud, friendly_fraud e chargeback são os que valem a pena encaminhar para uma fila de análise de fraude, em vez de um simples caminho de revogar e esquecer, porque a mesma conta tem estatisticamente mais chance de repetir o comportamento.
Um detalhe operacional importa se você construir integrações diretamente sobre esse feed: purchases.voidedpurchases.list tem um limite de 6.000 consultas por dia e 30 consultas em qualquer janela de 30 segundos. Um design que faz polling em loop apertado atinge esse limite rapidamente; o padrão pretendido é uma busca agendada com tokens de paginação, não polling contínuo.
Apple: a App Store pode revogar uma licença, mas não um item consumível
As App Store Server Notifications V2 da Apple enviam uma notificação REFUND no momento em que um reembolso é concluído, tanto para consumíveis quanto para não consumíveis, assinaturas de renovação automática e assinaturas sem renovação. O que acontece depois dessa notificação depende inteiramente do tipo de compra, porque o próprio mecanismo de revogação do StoreKit cobre apenas dois dos quatro tipos.
Por que os itens consumíveis são a exceção
Um item não consumível ou uma assinatura tem um direito permanente que os sistemas da Apple conseguem desativar. Um item consumível não: uma vez utilizado, é considerado entregue, e não sobra nada no StoreKit para revogar. Se um cliente comprou 500 moedas, gastou-as e recebeu um reembolso, as moedas já se foram do ponto de vista da Apple. O único registro que ainda as tem é o seu. A notificação REFUND é o seu único sinal para encontrar o ID da transação original correspondente e deduzir esse saldo dos seus próprios registros; nada do lado da Apple vai fazer isso por você.
| Notificação | O que significa | O que o seu servidor deve fazer |
|---|---|---|
| REFUND | Apple reembolsou uma compra consumível, não consumível, de renovação automática ou sem renovação | Revogar imediatamente o acesso de itens não consumíveis e assinaturas; deduzir o saldo consumível você mesmo |
| REFUND_DECLINED | Apple recusou o pedido de reembolso de um cliente | Nada. O acesso nunca esteve em risco |
| REFUND_REVERSED | Apple reverteu um reembolso que já havia concedido | Restaurar qualquer acesso ou saldo que a notificação REFUND fez você remover |
| CONSUMPTION_REQUEST | Apple quer suas evidências antes de decidir sobre um reembolso | Responder em até 12 horas; isso é disparado antes de um REFUND, não depois |
A notificação que quase ninguém trata
REFUND_REVERSED é a que a maioria das integrações ignora completamente, porque descreve a Apple desfazendo sua própria decisão, um caso para o qual poucos desenvolvedores planejam na primeira tentativa. Quando ela chega, revocationDate na transação volta para null: no que diz respeito à Apple, a compra é válida novamente. Se o seu servidor apagou um direito de acesso, cancelou o registro de uma assinatura ou zerou um saldo consumível quando o REFUND original chegou, REFUND_REVERSED é o sinal para desfazer tudo isso.
Como fechar essa lacuna, passo a passo
- No Google Play, configure todo caminho de reembolso para usar revoke=true por padrão, seja pelo Play Console ou pela API, a menos que um caso específico de suporte exija que o cliente mantenha o acesso.
- Faça polling em purchases.voidedpurchases.list em um cronograma com tokens de paginação, não em loop apertado, e fique abaixo de 6.000 requisições por dia e 30 a cada 30 segundos.
- Encaminhe valores de voidedReason como fraud, friendly_fraud e chargeback para uma fila de análise, em vez de um revoke-and-close automático.
- Na Apple, inscreva-se nas App Store Server Notifications V2 e revogue o acesso de itens não consumíveis e assinaturas no momento em que uma notificação REFUND os mencionar.
- Armazene o ID da transação original para cada compra consumível, para que uma notificação REFUND consiga encontrar o saldo exato a deduzir sem uma busca manual.
- Trate REFUND_REVERSED explicitamente e registre cada revogação vinculada ao seu ID de transação ou pedido, para que uma reversão possa restaurar precisamente o que foi removido.
O que essa lacuna realmente custa
Nada disso tem a ver com justiça para o cliente; tem a ver com o que continua rodando depois que o dinheiro já se foi. Uma assinatura reembolsada que continua chamando sua API, armazenando dados e consumindo processamento não é um problema moral, é um item de custo: você está pagando a conta de infraestrutura por uma compra cuja receita você já devolveu. As lojas não rastreiam esse custo para você, porque do lado delas o reembolso está concluído no momento em que o dinheiro se move. O lado do acesso é inteiramente sua conta para controlar.
Esse é o mesmo motivo pelo qual a RefundHalt trata a revogação como parte do pipeline de reembolso, e não como uma reflexão tardia: um evento REFUND e uma mudança de acesso são registrados como uma única ação, e um evento REFUND_REVERSED restaura o estado automaticamente, em vez de esperar que alguém perceba que o cliente ainda está bloqueado de algo que a Apple já devolveu.
Perguntas frequentes
- Reembolsar uma compra no Google Play revoga o acesso automaticamente?
- Não. O acesso só é removido se "Remove entitlement" estiver marcado no Play Console ou se a chamada da API orders.refund incluir revoke=true. Nenhuma das duas é o padrão, então um reembolso pode ser concluído enquanto o cliente continua usando o produto.
- O que acontece quando uma compra consumível dentro do aplicativo é reembolsada na App Store?
- A Apple envia uma notificação REFUND, mas o StoreKit não tem como revogar um item consumível porque ele é considerado entregue assim que é gasto. O servidor do desenvolvedor precisa encontrar a transação original e deduzir o saldo manualmente.
- O que é a notificação REFUND_REVERSED e ela precisa de tratamento especial?
- REFUND_REVERSED significa que a Apple reverteu um reembolso que já havia concedido; revocationDate volta para null e a compra é válida novamente. Qualquer acesso ou saldo que o REFUND original removeu precisa ser restaurado, e a maioria das integrações nunca escuta essa notificação.
- Por que um pedido reembolsado do Google Play não apareceria na Voided Purchases API?
- A API só lista pedidos que foram anulados com revogação. Se um reembolso foi processado sem a opção de revogação, o pedido simplesmente não é retornado por esse endpoint, então um pipeline que depende só dele vai perder completamente esses reembolsos.
- Com que frequência posso fazer polling na Voided Purchases API do Google?
- O endpoint tem limite de 6.000 consultas por dia e 30 consultas em qualquer janela de 30 segundos, então ele foi feito para uma busca agendada com tokens de paginação, não para polling contínuo.
Fontes e leituras adicionais
- Apple: Handling refund notifications
- Apple: notificationType (App Store Server Notifications)
- Apple: revocationReason (App Store Server Notifications)
- Google: Voided Purchases API overview
- Google: purchases.voidedpurchases REST resource
- Google: orders.refund API reference (revoke parameter)
- Google Play Console Help: manage your app's orders and issue refunds
RefundHalt
O piloto automático de reembolsos para App Store e Google Play
Continue lendo
The refunds you cannot contest: what Apple and Google decide without asking you
Only two refund flows ever ask for your evidence: Apple's consumption request and Google Play's chargeback review. Everything else, the 48-hour Play refund, support refunds, voided purchases, unacknowledged trials, is decided without you. Here is the full map, what you can prevent, and what you can only record.
Apple's CONSUMPTION_REQUEST, explained: the 12 hours that decide your refund
When a customer asks Apple for a refund, Apple asks you first. Here's exactly what the CONSUMPTION_REQUEST notification contains, what Apple expects back, how to answer one end to end, and why most developers silently forfeit.