uindocs
Developer

Recompensas y entrega

Cómo llega a tu sistema lo que el usuario ganó, la rama de espera, y el reclamo explícito

La recompensa se configura en el Control Center. Tu sistema no decide qué se entrega ni cuándo — solo lo recibe y lo muestra.

Cuándo se paga

Una recompensa se entrega al completarse la campaña, nunca al completarse una misión suelta. Vale para las cuatro mecánicas por igual: una campaña de tipo hito con tres misiones paga una vez, cuando las tres están cumplidas — no tres veces.

ExperienciaQué tiene que completarse
HitoTodas las misiones de la campaña
RetoLa cadena completa
RachaLa meta de ventanas seguidas
RutinaEl último ciclo

Los tres caminos por los que llega

Según cómo integres, la recompensa aparece en un lugar distinto:

CaminoCuándoQué obtenés
En la respuesta del eventoEmitís por el camino sincrónico y la entrega se resolvió en el momentoEl detalle en el mismo request que la disparó
Por webhookEmitís por el camino asincrónicoUn aviso a tu endpoint. Ver Recibir notificaciones
ConsultandoSiempre disponibleGET /v1/gamification/missions/my-rewards/{accountId}. Ver Mis recompensas

Los tres pueden convivir. El patrón robusto es usar el primero o el segundo para reaccionar rápido, y el tercero para reconciliar — porque es el único que no depende de que una entrega puntual haya llegado.

La rama de espera

La misión puede completarse sin que la recompensa esté disponible todavía. Si el stock se agotó justo en ese momento, la misión queda completada y la recompensa se entrega después.

El feed lo resuelve por vos: el ítem trae rewardStatus: PENDING_STOCK. Mostrale al usuario "misión cumplida, tu recompensa llega en breve". Cuando la entrega se concreta, el mismo ítem pasa a DELIVERED. Nunca digas "no ganaste".

En la respuesta del evento lo ves como una misión COMPLETED con rewards vacío. En my-rewards aparece solo si la entrega llegó a registrarse: si el stock ya estaba en cero al completarse, no hay entrada todavía y el rewardStatus del feed es la única fuente de ese estado.

Es una rama real y hay que diseñarla: si la pantalla solo contempla "ganaste" y "no ganaste", este caso se muestra como una pérdida que en realidad no ocurrió.

Mis recompensas

GET /v1/gamification/missions/my-rewards/{accountId} es el historial de lo que el usuario ganó. Devuelve una entrada por entrega: la misma recompensa pagada por dos campañas son dos entradas, cada una con sus códigos, y una recompensa que se entrega en varias partes también son varias entradas.

Además de la recompensa, cada entrada trae:

CampoQué es
redemptionIdLa entrega. Sirve para pedir el código a demanda.
campaignIdLa campaña en la que la ganó. Viene en null en entregas antiguas.
statusDELIVERED, o PENDING_STOCK mientras la entrega no se concretó.
deliveredAtCuándo se entregó (UTC). Viene en null mientras está en PENDING_STOCK.
rewardTypePRODUCTS, FRAGMENTS, POINTS o CHEST. En el feed el mismo dato se llama reward.type.
amountCuánto se entregó: unidades del producto, o puntos.
productEl producto entregado, en PRODUCTS y FRAGMENTS.
codesLos códigos de esta entrega, como { code, item }. Solo en PRODUCTS.
  • status es por entrega, no por campaña. PENDING_STOCK cubre tanto la entrega que espera stock como la que no se pudo cumplir: pasado tu SLA de reposición no se resuelve sola, es una alerta operativa. El rewardStatus del feed, en cambio, es el estado agregado de la campaña, así que durante una entrega parcial el feed puede decir PENDING_STOCK mientras my-rewards ya lista una entrada DELIVERED.
  • Para filtrar, usá el parámetro filters estándar sobre campaignId, rewardType o status. Ver Paginación y filtros. Sin paginación: siempre devuelve un array. Para un rango de fechas, filtrá por deliveredAt en tu app.
  • Los códigos vienen incluidos por defecto, y solo en recompensas PRODUCTS. Si tu pantalla los muestra recién cuando el usuario toca la recompensa, pedí la lista con includeCodes=false y traé los códigos de esa entrega con GET /redemptions/{redemptionId}/code, que devuelve { "codes": ["ABCD-1234", "EFGH-5678"] } — strings sueltos, sin el item que sí traen los codes de my-rewards.

Reclamo explícito de la recompensa

Solo si tu UX incluye un botón de reclamo. Si no lo incluye, la recompensa se entrega sola y este caso no existe en tu app. Habilitá el botón solo cuando el ítem del feed trae rewardStatus: CLAIMABLE.

POST /v1/campaigns/{campaignId}/completion-bonus/claim/account/{accountId}

El campaignId viene en cada ítem del feed. El claim es idempotente: varias llamadas resuelven una única entrega.

RespuestaQué significaQué mostrar
200Recompensa entregada.El código, o el saldo de puntos acreditado.
200 en un reclamo repetidoYa lo había reclamado.La misma recompensa, nunca un error de "ya reclamado".
422Todavía no completó la mecánica.Refrescá el feed y mostrá cuánto le falta. Revisá por qué el botón estaba habilitado.
409La recompensa se agotó."Te avisamos cuando esté disponible". Alerta operativa para reponer stock.
400 · 404La campaña no tiene recompensa configurada, o el id no existe.Nada al usuario: ocultá el botón. Es un problema de configuración.

Lo que ya se entregó no se toca

Ni cuando la campaña se pausa, ni cuando termina, ni cuando el usuario pierde una racha. El historial de recompensas del usuario se mantiene intacto.

Qué sigue

Recibir notificaciones — si vas por el camino asincrónico.

On this page