App Store Refund Management

Por dentro del CONSUMPTION_REQUEST de Apple: el medio día que decide tu reembolso

Todo reembolso en la App Store es decisión de Apple, pero un CONSUMPTION_REQUEST te da una ventana fija para responder con datos sobre la compra. Si respondes bien, los reclamos injustificados se rechazan. Si guardas silencio, la versión del cliente es la única que Apple escucha.

5 min read
Por dentro del CONSUMPTION_REQUEST de Apple: el medio día que decide tu reembolso

Todo reembolso en la App Store es decisión de Apple, pero Apple prefiere no tomarla sin información. Una solicitud de reembolso pausa el proceso, le hace una pregunta a tu servidor y abre un período fijo para que respondas con datos sobre la compra. Si respondes con sustancia, los reclamos injustificados se rechazan. Si guardas silencio, la versión del cliente es la única que Apple escucha.

Puntos clave

  • Las solicitudes de reembolso en la App Store hacen que Apple envíe a tu servidor una notificación CONSUMPTION_REQUEST y luego espere hasta 12 horas por evidencia antes de decidir.

  • Responder implica llamar al endpoint Send Consumption Information con un payload compacto: consentimiento, estado de entrega, si existió una muestra, cuánto se consumió y el resultado que quieres.

  • No enviar nada también es una respuesta. Apple procede usando solo lo que el cliente reclamó junto con su historial de cuenta.

  • El consentimiento funciona como un filtro estricto. La documentación de Apple es explícita en que no debes responder en absoluto cuando el cliente no haya aceptado que se comparta su información de consumo.

  • En las suscripciones de renovación automática, Apple calcula el porcentaje de consumo a partir del tiempo transcurrido, y enviar tu propia cifra produce un error.

  • Ningún proceso manual cabe dentro de esa ventana de tiempo. Los desarrolladores que se benefician de esto son aquellos cuya respuesta se ensambla y se envía de forma automática.

Todo reembolso en la App Store comienza de la misma manera: alguien visita reportaproblem.apple.com, selecciona una compra y elige un motivo.

La notificación que casi nunca se responde

Las apps configuradas para App Store Server Notifications V2 reciben una notificación CONSUMPTION_REQUEST en cuanto se solicita el reembolso. Dentro de ese payload están la transacción, el producto y, desde 2024, el motivo que seleccionó el cliente: UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL u OTHER.

A partir de ahí comienzan doce horas, durante las cuales puedes llamar al endpoint Send Consumption Information y dejar constancia de tu versión. Lo que ese endpoint pide es intencionalmente mínimo: cinco campos que solo contienen indicadores y números.

  • customerConsented le indica a Apple si el cliente aceptó que se compartieran sus datos de uso. Un valor típico es true.

  • deliveryStatus le indica a Apple si la compra llegó y funcionó. Un valor típico es DELIVERED.

  • sampleContentProvided le indica a Apple si hubo disponible una muestra gratuita o una prueba de antemano. Un valor típico es true.

  • consumptionPercentage le indica a Apple la proporción consumida, expresada en milésimas de unidad, donde 100000 equivale a 100 por ciento. Un valor típico es 67500.

  • refundPreference le indica a Apple el resultado que prefieres, ya sea aprobar, rechazar o sin preferencia. Un valor típico es DECLINE.

consumptionPercentage tiene un alcance limitado: consumibles, compras únicas y suscripciones no renovables. En las suscripciones de renovación automática, Apple lo calcula a partir del tiempo transcurrido dentro del período de facturación, y cualquier valor que envíes se rechaza.

Qué hace Apple con lo que envías

Apple usa explícitamente la información de consumo como un insumo para resolver el reembolso. Si no envías nada, la decisión se basa únicamente en lo que el cliente afirmó más su historial de cuenta. Si envías evidencia, los reembolsos cuestionados se rechazan con bastante frecuencia.

Cómo construir tú mismo el proceso de respuesta, de principio a fin

Nada en esta secuencia es un secreto. Sin embargo, todo debe funcionar sin supervisión a las tres de la madrugada.

1. Haz que lleguen las notificaciones

Dentro de App Store Connect, abre la página App Information de tu app y configura una Production Server URL dentro de App Store Server Notifications, eligiendo Version 2. Las solicitudes de consumo no viajan por V1. A partir de ahí, cada notificación, incluidos los reembolsos, llega a esa URL mediante POST como un payload JWS firmado.

2. Genera la clave correcta

La autenticación de las respuestas usa una clave In-App Purchase, creada en Users and Access, dentro de la sección Integrations. Es un tipo de clave distinto, y la clave de la API de App Store Connect que está junto a ella no autenticará estas llamadas. El archivo .p8 se descarga exactamente una vez, y después de eso generas un JWT ES256 de corta duración para cada solicitud.

3. Verifica, relaciona y luego decide

Las notificaciones CONSUMPTION_REQUEST que llegan necesitan que se valide su cadena de firma JWS contra los certificados raíz de Apple antes de confiar en cualquier parte de su contenido. Luego, relaciona la transacción con un usuario, idealmente mediante el UUID de appAccountToken que hayas asignado durante la compra, y obtén su uso real. Después, decide una preferencia: cede en los casos de buena voluntad y disputa aquellos en los que el producto claramente se consumió.

4. Envíalo antes de que se cierre la ventana

Haz un PUT con esos cinco campos al endpoint Send Consumption Information, asociados a ese transaction id, dentro de las 12 horas. Casi todos cometen dos errores. El porcentaje se rige por milésimas de unidad, así que 100% equivale a 100000 y no a un millón. Y el consentimiento condiciona todo el proceso, porque la propia documentación de Apple indica que no debes responder en absoluto si no existe el consentimiento del cliente. Incluye ese lenguaje de consentimiento en tus términos de servicio antes de lanzar cualquiera de estos pasos.

Por qué tantos desarrolladores pierden esta oportunidad

Medio día es un plazo implacable para cualquier proceso operado por personas. Las notificaciones llegan a las 3 a.m. un sábado. Lo que exigen es un servidor capaz de validar la cadena de firma JWS de Apple, relacionar la transacción con un usuario, calcular un porcentaje de consumo en milésimas de unidad y llamar a una API autenticada con JWT. Para cada solicitud. De manera indefinida.

En la práctica, la lista de verificación es la siguiente:

  • Configura App Store Server Notifications V2; sin esto, la solicitud nunca te llega.

  • Valida el payload firmado contra la cadena de certificados de Apple antes de confiar en él.

  • Relaciona la transacción con un usuario en tu propio sistema, por lo general mediante el appAccountToken asignado en la compra.

  • Calcula un porcentaje de consumo a partir del uso real registrado, en lugar de una estimación.

  • Llama a Send Consumption Information usando una clave In-App Purchase mientras la ventana siga abierta.

Refund Sensor existe para asumir esa carga, enviando una respuesta completa y con evidencia dentro de la ventana, sin que nadie tenga que despertarse.

Dónde está documentado todo esto

Preguntas frecuentes

El reembolso se decide de todas formas, pero solo con base en el reclamo del cliente y su historial de cuenta. Pierdes la única oportunidad disponible para demostrar que la compra llegó y se usó de forma extensa. En la práctica, las solicitudes sin respuesta se aprueban considerablemente más seguido.

Sí, se requiere. customerConsented debe ser true, y el acuerdo detrás de ese indicador debe ser genuino, por lo general registrado en el documento legal que cubra el intercambio de datos. La propia guía de Apple indica a los desarrolladores que dejen la notificación sin responder por completo cuando no exista ese consentimiento.

Solo para las de tipo no renovable. En las suscripciones de renovación automática, Apple calcula el consumo a partir del tiempo transcurrido dentro del período de facturación actual, y la API rechaza cualquier porcentaje que envíes. Aun así, tu preferencia de reembolso sigue teniendo peso.

Una clave In-App Purchase, generada en App Store Connect dentro de Users and Access, en Integrations. Esta es distinta de la clave de la API de App Store Connect, y su archivo .p8 solo se puede descargar una vez, en el momento de su creación.

En producción tienes 12 horas desde la notificación. En sandbox son solo 5 minutos, lo cual es una señal bastante directa de lo que Apple espera: automatización, no una persona.

#consumption request#send consumption information#app store server notifications#refunds#storekit#ios
Refund SensorRefund Sensor TeamRefund defense for App Store and Google Play developers