Hay un endpoint que devuelve todo el historial de reembolsos de App Store de un cliente, y esto es lo que entrega
El endpoint Get Refund History de Apple devuelve el historial completo de reembolsos de App Store de un cliente como transacciones firmadas. Aquí tienes cada campo, cómo pagina el token revision, por qué es por cliente y no por app, y cuánto te cuesta un reembolso que se te escapa.

Puntos clave
- Get Refund History es un endpoint de la App Store Server API que devuelve las compras dentro de la app reembolsadas de un cliente para tu app como una lista de transacciones firmadas, para que puedas conciliar reembolsos y revocar el acceso incluso cuando una notificación nunca te llegó.
- Llamas a GET /inApps/v2/refund/lookup/{transactionId} con cualquier id de transacción de ese cliente, y Apple devuelve sus reembolsos de todos los tipos de compra de tu app, no solo el que consultaste.
- La respuesta tiene tres campos: signedTransactions, hasta 20 transacciones JWS por página ordenadas del reembolso más antiguo primero, más un token revision y un booleano hasMore para paginar.
- Guarda el token revision final. Pásalo la próxima vez y Apple devuelve solo los reembolsos más recientes que ese punto, lo que convierte un volcado completo del historial en una lista corta de filas nuevas en cada ejecución.
- Cada transacción decodificada lleva revocationDate y revocationReason. Un revocationReason de 1 significa que el cliente pidió el reembolso por un problema real o percibido en tu app, y 0 significa otra razón, como una compra accidental.
- El endpoint es por cliente, no por app. No hay una sola llamada que liste todos los reembolsos de toda tu app, así que concilias por cuenta a partir de un id de transacción, o lees tu feed de notificaciones REFUND para la vista de toda la app.
- La razón para conectarlo es el dinero. Un reembolso que nunca detectas mantiene una cuenta activa, y sigues pagando cómputo, llamadas a la API del modelo, almacenamiento y pagos por un cliente al que App Store ya reembolsó.
Apple mantiene un registro consultable de cada reembolso que ha concedido en la cuenta de un cliente para tu app, y una llamada lo devuelve. El endpoint es Get Refund History, parte de la App Store Server API, y te entrega el historial completo de reembolsos de App Store de ese cliente como una lista de transacciones firmadas. Pasas un id de transacción, recibes lo que Apple reembolsó, y lo concilias con lo que aún tienes activado.
Aquí está por qué merece la pena. Un reembolso que nunca ves es un reembolso que sigues pagando. El dinero ya se fue, pero la cuenta sigue activa, y cada hora que lo hace sigues gastando en cómputo, llamadas a la API del modelo, almacenamiento y cualquier pago vinculado a ese cliente. Tus notificaciones de reembolso deberían detectar esto en el momento en que ocurre. Get Refund History es la red de seguridad para cuando no lo hacen, tras una caída, un despliegue que perdió un webhook, o un caso de soporte donde necesitas el panorama completo en una sola llamada.
Qué devuelve el endpoint de historial de reembolsos de App Store
Llamas a GET /inApps/v2/refund/lookup/{transactionId} contra la App Store Server API, firmada con el mismo JWT que usas para las demás llamadas. El id de transacción en la ruta puede ser cualquier transacción del cliente. Apple lo lee como una identidad, no como un filtro, y devuelve las compras reembolsadas de ese cliente en toda tu app: consumibles, no consumibles, suscripciones auto-renovables y no renovables por igual. La V1 anterior de este endpoint devolvía hasta 50 reembolsos en una sola respuesta y está obsoleta. La versión actual pagina, así que gestionas a clientes con historiales largos sin una carga gigante.
La respuesta son tres campos
| Campo | Qué contiene |
|---|---|
| signedTransactions | Hasta 20 transacciones reembolsadas de este cliente, cada una un JWS firmado que verificas y decodificas. Ordenadas por reembolso más antiguo primero, por revocationDate. Un array vacío significa que el cliente no tiene reembolsos en tu app |
| revision | Un token de paginación. Pásalo de vuelta para obtener la siguiente página, y guarda el último para obtener solo los reembolsos nuevos la próxima vez |
| hasMore | Verdadero cuando Apple tiene más transacciones reembolsadas de las que devolvió esta página, así que vuelves a llamar con el revision |
Qué te dice una transacción reembolsada
Cada entrada en signedTransactions es un JWS. Verifícalo contra la cadena de certificados de Apple, decodifícalo, y tienes un payload de transacción normal con los campos de reembolso rellenados. Estos son los que importan aquí.
| Campo | Qué te dice |
|---|---|
| transactionId | El id de la transacción reembolsada, tu clave de unión con la compra que registraste |
| originalTransactionId | El id de la primera compra de la cadena, cómo vinculas las renovaciones de una suscripción |
| productId | El producto que se reembolsó, para que revoques el derecho correcto y nada más |
| revocationDate | La hora UNIX, en milisegundos, en que Apple reembolsó la transacción |
| revocationReason | Por qué Apple lo reembolsó. 1 significa un problema real o percibido con tu app, 0 significa otra razón, como una compra accidental |
| price, currency | El importe, en milliunits, y su código de moneda ISO 4217, para que puedas totalizar el dinero devuelto |
| appAccountToken | El UUID que adjuntaste en la compra, la forma más limpia de asignar un reembolso a tu propio usuario |
El token revision es cómo dejas de releer la lista entera
La forma ingenua de usar este endpoint es buscar a un cliente y recorrer todas las páginas cada vez. Eso funciona, y en un cliente con cincuenta reembolsos son cincuenta filas que ya conocías más la única nueva. El token revision existe para eliminar ese desperdicio. Cada respuesta lleva un revision. Cuando hasMore es verdadero, lo pasas de vuelta para obtener la siguiente página. Cuando llegas al final, guardas el último revision que viste.
Lo que este endpoint no hará
Hay una expectativa que debes descartar antes de construir sobre él. Get Refund History es por cliente, no por app. No puedes pedirle todos los reembolsos que recibió tu app la semana pasada. Responde una pregunta, qué reembolsos tiene esta cuenta, y tienes que llegar con un id de transacción de esa cuenta para preguntárselo. Los desarrolladores chocan con este muro constantemente y salen a buscar un endpoint de reembolsos de toda la app que no existe.
La vista de toda la app vive en otro sitio. Tu feed de App Store Server Notifications envía una notificación REFUND en el momento en que Apple concede cada uno, y Get Notification History te permite reproducir ese feed filtrado a los tipos de reembolso en un rango de fechas. Así que la división es limpia. Las notificaciones y su historial te dan el flujo de toda la app. Get Refund History te da la lista autoritativa de una cuenta, bajo demanda, que es lo que quieres en un mostrador de soporte o tras una caída.

Cuánto te cuesta en dinero un reembolso que se te escapa
El endpoint es fontanería. La factura es la razón por la que tiendes la tubería. Cada reembolso de esa lista es dinero ya devuelto, y la única variable que queda bajo tu control es cuánto tiempo sigues gastando en una cuenta que ya no paga.
Sigues pagando por dar servicio a una cuenta reembolsada
El precio de compra desaparece en el instante en que Apple concede el reembolso. Lo que sigue en marcha es el coste de la entrega. Para una app que hace trabajo real por usuario, eso es cómputo, llamadas a la API del modelo, almacenamiento y cualquier pago a creadores o socios vinculado a su uso. Un cliente reembolsado al que nunca le cortas el acceso es una suscripción que financias de tu bolsillo. Conciliar contra Get Refund History y revocar según lo que encuentres es cómo apagas ese contador cuando se coló una notificación.
Una razón de reembolso de 1 es un informe de defecto disfrazado
revocationReason te cuesta el doble si lo ignoras. El primer coste es el reembolso en sí. El segundo es cada reembolso futuro por la misma causa. Cuando un producto sigue volviendo con revocationReason 1, un problema real o percibido en tu app, Apple te está entregando una muestra etiquetada de lo que hace que los clientes pidan su dinero de vuelta. Analiza la tendencia por producto y podrás tapar la fuga en lugar de pagarla reembolso a reembolso.
Detectarlo tarde sigue siendo mejor que no detectarlo
Un contracargo es definitivo con el banco y, en la otra tienda, ahora conlleva una comisión que el desarrollador asume. Un reembolso de App Store no es eso. Está liquidado, pero el derecho es tuyo para revocarlo en el momento en que te enteras. Así que incluso un reembolso que encuentras con días de retraso a través de este endpoint vale la pena encontrarlo. No puedes recuperar el dinero, pero puedes detener el gasto que aún corría por detrás.
Cómo encaja esto con las notificaciones, y con Google
Piensa en las piezas como un solo sistema. La notificación REFUND es la señal en vivo, enviada a tu servidor a medida que Apple decide. Get Refund History es la fuente de verdad basada en extracción para un solo cliente, la llamada que haces cuando el envío falló o cuando una persona necesita la cuenta completa delante. En el lado de Google Play la forma es la misma idea con nombres distintos: una VoidedPurchaseNotification se envía en tiempo real, y la Voided Purchases API es la lista que extraes. Ambas tiendas te dan un flujo y un libro de registro. El error es confiar solo en el flujo, porque los flujos se caen.
Conectarlo al estilo de RefundHalt
El bucle es pequeño una vez que todas las piezas están en su sitio. Toma una notificación REFUND como disparador. Concilia contra Get Refund History para que un webhook perdido nunca deje activa una cuenta reembolsada. Decodifica cada transacción, vincúlala por appAccountToken o transactionId con tu usuario, lee revocationReason para que un reembolso por defecto se marque y no solo se archive, y revoca el derecho exacto en lugar de toda la cuenta. Pagina con el token revision para leer los reembolsos nuevos, no los viejos.
Esta es la parte que RefundHalt ejecuta por ti. Escucha las notificaciones de reembolso, recurre a Get Refund History cuando necesita la lista autoritativa, verifica cada transacción firmada, revoca la compra precisa, y guarda el revision para que cada pasada lea solo lo que cambió. Obtienes el acceso cortado en segundos y un registro limpio de quién fue reembolsado, por qué producto y por qué motivo, sin tener que montar tú mismo el sondeo y la verificación JWS.
Preguntas frecuentes
- ¿Cómo veo todos los reembolsos de toda mi app, no solo de un cliente?
- No puedes con Get Refund History, porque es por cliente y necesita un id de transacción de la cuenta que consultas. Para la vista de toda la app, usa tu feed de App Store Server Notifications, que envía una notificación REFUND por cada reembolso a medida que Apple lo concede, y Get Notification History para reproducir ese feed filtrado a los tipos de reembolso en un rango de fechas.
- ¿Cuántos reembolsos devuelve el endpoint Get Refund History?
- La versión actual devuelve hasta 20 transacciones reembolsadas por página, ordenadas con el reembolso más antiguo primero, y pagina por el resto con un token revision cuando hasMore es verdadero. El endpoint V1 obsoleto devolvía hasta 50 en una sola respuesta. No hay tope en el total, así que un cliente con un historial largo simplemente abarca más páginas.
- ¿Para qué sirve el token revision?
- Es cómo paginas y cómo evitas releer todo el historial de un cliente cada vez. Cada respuesta incluye un revision. Lo pasas de vuelta para obtener la siguiente página, y guardas el último para que tu próxima consulta devuelva solo los reembolsos más recientes que ese punto. Eso mantiene una conciliación programada en una lista corta de filas nuevas.
- ¿Qué significa revocationReason en una transacción reembolsada?
- Es por qué Apple reembolsó la transacción. Un valor de 1 significa que el cliente pidió el reembolso por un problema real o percibido dentro de tu app, y 0 significa otra razón, como una compra accidental. revocationDate te dice cuándo ocurrió el reembolso, en milisegundos UNIX. Leer revocationReason te permite separar un defecto de producto de un reembolso puntual por arrepentimiento.
- ¿Sigo necesitando esto si ya gestiono las notificaciones REFUND?
- Sí, como red de seguridad. Las notificaciones son la señal en vivo, pero un envío puede no llegar durante una caída, un mal despliegue o un cambio de webhook, y un reembolso que se te escapa deja activa una cuenta reembolsada que te cuesta dinero. Get Refund History es la fuente de verdad basada en extracción contra la que concilias para que no quede nada activado que Apple ya haya reembolsado.
Fuentes y lecturas adicionales
- Apple Developer: Get Refund History (App Store Server API)
- Apple Developer: RefundHistoryResponse
- Apple Developer: JWSTransactionDecodedPayload (revocationDate, revocationReason)
- Apple Developer: Get Refund History V1 (deprecated)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND)
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
El piloto automático de reembolsos para App Store y Google Play
Seguir leyendo
Tu app puede mostrar una hoja de solicitud de reembolso dentro de la app, y esto es lo que hace Apple cuando el cliente toca enviar
La solicitud de reembolso dentro de la app de Apple permite que un cliente pida un reembolso sin salir de tu app, en una hoja que Apple construye y revisa. Esto es lo que devuelve beginRefundRequest, los relojes de CONSUMPTION_REQUEST y de 48 horas que arranca en tu servidor, y si vale la pena publicar el botón.
Cuando se reembolsa o revierte un cargo de una compra en Google Play, la Voided Purchases API es como te enteras
Google Play anula una compra de forma silenciosa cuando se reembolsa o se revierte el cargo. La Voided Purchases API es la lista de esos pedidos, para que puedas revocar el acceso. Aqui tienes cada campo, la ventana de 30 dias, la opcion de revocar que oculta pedidos y lo que cuesta.