Todos los artículos
Deep dive7 min de lectura

Adjunta un appAccountToken a cada compra de la App Store, o no podrás defender el reembolso

Apple envía a tu servidor un CONSUMPTION_REQUEST cuando un cliente pide un reembolso, pero la transacción nunca dice quién es. appAccountToken es el UUID que vincula una compra con tu usuario. Configúralo y podrás responder a Apple con datos reales. Omítelo y estarás adivinando.

Una llave de latón numerada sobre un libro de cuentas oscuro, junto a un teléfono que muestra un recibo de compra, ilustrando cómo un appAccountToken vincula una compra de la App Store con una cuenta de usuario

Puntos clave

  • appAccountToken es un UUID que adjuntas a una compra de la App Store para que la transacción resultante apunte de vuelta al usuario exacto en tu propio sistema. Apple lo guarda en la transacción y lo devuelve en todos los lugares donde aparece esa transacción.
  • La única regla de formato que Apple exige es que el valor sea un UUID válido. Pasa cualquier otra cosa, un id, un correo, una cadena concatenada, y StoreKit lo descarta en silencio y devuelve appAccountToken como nil.
  • En StoreKit 2 lo configuras con una sola opción de compra, Product.PurchaseOption.appAccountToken(_:), usando un UUID estable que generaste y guardaste para esa cuenta.
  • Configúralo una vez en la compra original y Apple mantiene el mismo token en cada renovación, reintento de cobro y actualización de la cadena de suscripción.
  • Desde 2025, el endpoint Set App Account Token permite que tu servidor adjunte un token a compras hechas fuera de tu app, como canjes de códigos de oferta y compras promocionadas, que el flujo dentro de la app nunca podía alcanzar.
  • appAccountToken es lo que hace que el CONSUMPTION_REQUEST de Apple tenga respuesta. Sin él no puedes asociar el reembolso con el cliente cuyo uso se supone que debes describir dentro de la ventana de 12 horas.
  • Un reembolso que no puedes identificar es un reembolso que no puedes defender. Devuelves dinero en compras que tenías pruebas para conservar, además del cómputo, las llamadas a la API y los pagos que ya gastaste en entregarlas.

Un cliente le pide un reembolso a Apple, Apple envía a tu servidor un CONSUMPTION_REQUEST, y tienes doce horas para responder con datos reales sobre cómo esa persona usó el producto. Entonces abres la notificación y te das cuenta de que no tienes ni idea de quién es. La transacción lleva un originalTransactionId y un id de producto, pero nada que apunte a la cuenta en tu propia base de datos. Esa brecha es exactamente lo que cierra appAccountToken, y si no lo configuraste en el momento de la compra, no puedes cerrarla después para esa venta.

appAccountToken es un UUID que adjuntas a una compra para que la transacción resultante de la App Store lleve un puntero de vuelta al usuario exacto en tu sistema. Configúralo, y cada pregunta de reembolso que Apple haga sobre ese cliente llegará con su identidad adjunta. Omítelo, y estarás adivinando. Esto es lo que es el campo, cómo configurarlo, el nuevo endpoint que rescata las compras hechas fuera de tu app, y cuánto cuesta realmente el vínculo perdido cuando llega un reembolso.

Qué es realmente appAccountToken

appAccountToken es un UUID opaco que generas y pasas a StoreKit en el momento de la compra. Apple lo guarda en la transacción y lo devuelve en la información de la transacción de esa compra, y ahí se queda. En palabras de Apple, es "el UUID que asocia la transacción con la cuenta del usuario en tu propio servicio". La única regla de formato es que tiene que ser un UUID. Apple no lo lee, no valida a qué apunta, y no le importa qué significa de tu lado. Es un vínculo que tú controlas.

Como vive en la transacción, vuelve a todas partes donde va la transacción. La transacción firmada en una notificación de servidor, la respuesta Get Transaction Info de la App Store Server API, y cada renovación de una cadena de suscripción llevan el mismo token si lo configuraste en la compra original. Un UUID, adjuntado una vez, sigue la facturación del cliente durante toda la relación.

Tiene que ser un UUID real, o desaparece en silencio

La única regla que Apple exige es el formato. StoreKit 2 requiere un UUID de RFC 4122. Si pasas una cadena concatenada, un id entero o una dirección de correo, StoreKit no lanza ningún error. Descarta el valor y la transacción vuelve con appAccountToken en nil. Los desarrolladores tropiezan con esto constantemente, y el síntoma es siempre el mismo, alguna variante de "appAccountToken is missing in the transaction payload" en los propios foros de Apple, casi siempre porque el valor que se pasó no era un UUID válido. Genera un UUID real del lado del servidor, guárdalo asociado a la cuenta, y nunca le des a StoreKit otra cosa.

Cómo configurarlo en el momento de la compra

En StoreKit 2 es una sola opción de compra. Genera el UUID en tu servidor cuando el usuario se registra o llega por primera vez al pago, guárdalo en el registro de su cuenta, y pasa ese mismo valor a la llamada de compra.

La firma es Product.PurchaseOption.appAccountToken(_ token: UUID), y una compra se ve así try await product.purchase(options: [.appAccountToken(token)]). Cuando la transacción vuelve, verificada a través de la App Store Server API o entregada por una notificación de servidor, lleva ese UUID, y tu servidor busca al cliente en una sola consulta.

Usa un token estable por cuenta

No generes un token nuevo para cada compra del mismo usuario. Apple devuelve el token en las renovaciones, los reintentos de cobro y las actualizaciones de la misma cadena, así que un UUID estable por cuenta te da un hilo limpio desde la primera compra a través de cada evento futuro. Un token que cambia en cada compra rompe ese hilo y frustra todo el propósito. Una cuenta, un token, reutilizado cada vez que esa cuenta compra.

El endpoint que rescata las compras fuera de la app

Hasta 2025 había un agujero. Si un cliente canjeaba un código de oferta o compraba una compra dentro de la app promocionada directamente desde la App Store, tu app nunca ejecutaba el flujo de compra, así que no había dónde configurar appAccountToken. Esas transacciones llegaban anónimas y así se quedaban.

WWDC 2025 cerró la brecha con el endpoint Set App Account Token. Tu servidor llama a PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken en la App Store Server API con el UUID en el cuerpo, y Apple configura el token en esa transacción. Funciona para todos los tipos de producto, cubre los canjes de códigos de oferta y las compras promocionadas, y el valor que envías anula cualquier token que ya estuviera en la transacción. Ahora puedes asociar una compra después del hecho, desde tu servidor, sin que nunca pase por tu app.

Una pila de recibos de venta en papel sobre un escritorio oscuro con la línea del nombre del cliente en blanco, uno iluminado por un foco cálido, ilustrando una compra de la App Store que llega sin appAccountToken para identificar al comprador
Canal de compraDónde configuras appAccountTokenNotas
Compra dentro de la appOpción de compra de StoreKit en el momento de comprarProduct.PurchaseOption.appAccountToken(UUID)
Canje de código de ofertaEndpoint Set App Account Token, del lado del servidorNo hay flujo dentro de la app al que engancharse, así que configúralo después
Compra dentro de la app promocionada desde la App StoreEndpoint Set App Account Token, del lado del servidorLa compra ocurre fuera de tu app
Renovación de suscripciónNada que hacerSe traslada automáticamente desde la compra original

Dónde el vínculo perdido te cuesta dinero

El objetivo del token no son registros ordenados. Es que la única pregunta de reembolso de Apple para los desarrolladores, el CONSUMPTION_REQUEST, solo tiene respuesta si puedes encontrar al cliente al que se refiere.

Cuando un comprador solicita un reembolso de un consumible o una suscripción no renovable, Apple envía a tu servidor una notificación CONSUMPTION_REQUEST y te da doce horas para responder con Send Consumption Information. Tu respuesta son datos sobre ese cliente específico: cuánto del producto consumió, la antigüedad de su cuenta, su gasto de por vida, su estado de entrega. appAccountToken es en sí mismo uno de los campos de esa solicitud, y más al grano, es la forma en que la transacción de la notificación se asocia con la cuenta cuyo uso estás a punto de describir. Sin token, sin búsqueda, sin respuesta precisa.

Cuánto cuesta realmente una respuesta en blanco

Un reembolso no identificado obliga a una mala decisión. Puedes responder a la solicitud de consumo con nada, lo que se lee como bajo consumo y empuja a Apple hacia conceder el reembolso, incluso a clientes que usaron el producto intensamente. O puedes adivinar. De cualquier forma estás reembolsando compras que tenías pruebas para defender, y ya pagaste el costo real de servirlas.

Ese costo no es el precio de venta. Un consumible que ejecutó un lote de llamadas a la API de un modelo, generó imágenes, exportó un video o activó un pago a un creador gastó dinero real en el momento en que se entregó. El reembolso devuelve el pago del cliente. No devuelve la factura del proveedor. Multiplica un cliente no identificable por cada reembolso que presenta, y por cada reembolsador en serie que cuenta con que no sepas quién es, y el token que omitiste se convierte en la línea de código más cara que nunca escribiste.

La misma idea existe en Android, con otro nombre

Google Play resuelve el problema idéntico con setObfuscatedAccountId, que adjunta un identificador de cuenta a una compra para que la revisión de contracargos de Google a través de orders.reviewrefund pueda responderse contra un usuario real. Distinta tienda, distinta mecánica, la misma lección: adjunta la identidad en el momento de la compra o no podrás defender la disputa después. En la App Store, esa herramienta es appAccountToken, y tiene que ser un UUID.

Tres hábitos que mantienen el token en su lugar

  • Genera un UUID por cuenta y guárdalo. Un token estable por cliente, creado cuando se registra o en el primer pago, guardado en su registro y reutilizado para cada compra.
  • Valida antes de pasarlo. Confirma que el valor es un UUID real en tu código de compra, para que un id malformado nunca pueda convertirse en silencio en un token nil en la transacción.
  • Rellena las compras hechas fuera de la app. Cuando llega una notificación de servidor por un canje de código de oferta o una compra promocionada sin token, llama al endpoint Set App Account Token para adjuntar el correcto.

Haz esas tres cosas y cada transacción que Apple te envíe, incluidas las solicitudes de reembolso, llegará ya vinculada al cliente al que pertenece.

Este es el trabajo de base del que depende RefundHalt. Leemos appAccountToken de cada transacción y notificación de servidor, lo asociamos con el uso que ya rastreamos para esa cuenta, y respondemos a la solicitud de consumo de Apple dentro de la ventana de doce horas con los números reales del cliente. El token es el hilo. Configúralo una vez y tu defensa de reembolsos tendrá algo de qué sostenerse.

Preguntas frecuentes

¿Qué es appAccountToken en la App Store?
appAccountToken es un UUID que generas y adjuntas a una compra a través de StoreKit para que la transacción resultante de la App Store apunte de vuelta a una cuenta de usuario específica en tu propio sistema. Apple lo guarda en la transacción y lo devuelve en la información de la transacción, las notificaciones de servidor y cada renovación de la misma cadena, lo que te permite conectar cualquier evento futuro, incluida una solicitud de reembolso, con el cliente correcto.
¿Por qué mi appAccountToken es nil o falta?
Casi siempre porque el valor que pasaste no era un UUID válido. StoreKit 2 requiere un UUID de RFC 4122 y descarta en silencio cualquier otra cosa, así que una cadena concatenada, un id entero o un correo vuelven como un appAccountToken nil mientras la compra igual se completa. La otra causa común es una compra hecha fuera de tu app, como un canje de código de oferta, donde no se ejecutó ningún flujo dentro de la app para configurar el token.
¿Puedo configurar appAccountToken después de la compra, para códigos de oferta?
Sí, desde 2025. El endpoint Set App Account Token de la App Store Server API permite que tu servidor adjunte o sobrescriba el token en una transacción existente llamando a PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken con el UUID en el cuerpo. Funciona para todos los tipos de producto y está pensado para compras hechas fuera de tu app, como canjes de códigos de oferta y compras dentro de la app promocionadas.
¿appAccountToken tiene que ser un UUID?
Sí. La única regla de formato que Apple exige es que el valor sea un UUID válido. Por lo demás es opaco, así que puede apuntar a la clave de cuenta que quieras de tu lado, pero si no es un UUID StoreKit no lo guardará y la transacción volverá con appAccountToken en nil.
¿Cómo ayuda appAccountToken con los reembolsos?
Cuando un cliente solicita un reembolso, Apple envía un CONSUMPTION_REQUEST y te da doce horas para responder con datos sobre ese comprador específico. appAccountToken es la forma en que asocias la transacción de la notificación con la cuenta cuyo uso necesitas reportar, y es uno de los campos de la propia solicitud de consumo. Sin él no puedes responder con el uso real, así que Apple se inclina por conceder reembolsos que tenías pruebas para impugnar.
¿appAccountToken debería ser distinto para cada compra?
No. Usa un UUID estable por cuenta y reutilízalo para cada compra que haga ese usuario. Apple mantiene el token a través de las renovaciones y actualizaciones de una cadena de suscripción, así que un token estable te da un vínculo limpio a lo largo del tiempo. Un token que cambia en cada compra rompe ese vínculo y hace más difícil asociar las transacciones con el mismo cliente.

Fuentes y lecturas adicionales

RefundHalt

El piloto automático de reembolsos para App Store y Google Play

Seguir leyendo

La próxima solicitud de reembolso ya está en camino.

Configura RefundHalt en el tiempo que tardas en leer otro correo de soporte sobre un reembolso que no llegaste a impugnar.