Cliente: Crédito 365
Runbook del onboarding de Crédito 365 (cliente 50): canales web / FB web / app, postbacks S2S, test links, campañas y QA.
Crédito 365 (client_id 50)
Cliente lead-gen events (commission_source=events, tracking_type=pixel, attribution_field=sub1). Relo corre el tráfico con sus propios partners y con medios propios (Facebook). El cliente confirma los leads en su backend (flujo de crédito: el lead no se valida en el formulario) y los reporta vía postback S2S.
Onboarded: 2026-10-05. Contacto cliente: Karolina / Valentyn (dev). Grupo WhatsApp "Credito-365.mx | Relo".
Canales y piezas entregadas
El cliente pidió "2 postbacks + 2 test links" (web y FB web) más la integración de app por AppsFlyer. Mapeo real en Relo:
| Canal | Pieza | Valor |
|---|---|---|
| Web | Data source | client_data_sources id 13 (Crédito 365 — Web S2S, source credito365_web) |
| Web | Campaña | campaigns id 29 (C365 — Web, slug c365-web) |
| Web | Test link | https://t.relo.mx/c/tJe2CT |
| FB Web | Data source | client_data_sources id 14 (Crédito 365 — FB Web S2S, source credito365_fbweb) |
| FB Web | Campaña | campaigns id 30 (C365 — FB Web, slug c365-fb-web) |
| FB Web | Test link | https://t.relo.mx/c/UPe3nw |
| App | Campaña | campaigns id 31 (C365 — App, slug c365-app, tracking_type mmp) |
| App | AF S2S inbound | s2s.relo.mx/postback/appsflyer?client_id=50 — pendiente, lo configura Valentyn en su dashboard de AF |
Ambas campañas con key event lead_submit (fire_postback: true). Los postback URLs con sus auth_token viven en client_data_sources.extra_config (visibles en admin → Tracking sources) — no se documentan aquí porque docs.relo.mx es público.
Partner house
Se creó el partner Relo Direct (id 106, status Activo, sin payouts) para colgar los test links y los links de las campañas que Relo corre con medios propios. Los partners externos se dan de alta aparte.
Partners externos (altas 2026-10-06)
Corren los 3 canales (web, FB web, app). Cada uno tiene: partner_clients (client 50, token p<id> exact para atribución AF por sub1), partner_campaigns × 3 campañas (29/30/31), y partner_lead_rates $4 USD flat por lead_submit (efectivo 2026-10-06).
| Partner | id | Token atribución (sub1) | Acceso portal | Link web | Link FB web |
|---|---|---|---|---|---|
| Strongmetrics | 107 | p107 | ✅ email de lanzamiento enviado 2026-10-06 con signup link (7 días) | t.relo.mx/c/FBnWib | t.relo.mx/c/tYkycd |
| Xapads | 104 | p104 | ✅ Yair Sanjuanero — email enviado 2026-10-06 | t.relo.mx/c/HzR8C8 | t.relo.mx/c/Ol4Es5 |
| BEdigitech | 13 | p13 | ✅ Akhil Pandey — email enviado 2026-10-06 (cc Vikas) | t.relo.mx/c/7xXBoe | t.relo.mx/c/C3IqOI |
Links generados 2026-10-06 y verificados en vivo (302 + click cache con el partner correcto). Los partners pueden generar más links self-serve en el portal (Links & creatives).
Emails de lanzamiento (2026-10-06, POST /api/admin/send-generic-email, subject "Crédito 365 is live — €4 per confirmed lead (links inside)", todos status=sent en email_log ids 3726-3729): Akhil (cc Vikas), Yair, Nimit y Alexis (estos dos con su signup link de activación incluido). Ese día se envió corrección ("Correction: Crédito 365 payout is $4 USD per confirmed lead") — el primer email decía EUR por error; el rate correcto y el que quedó en DB es $4 USD.
Notas:
- Xapads estaba duplicado (103 Activo y 104 Prospecto) — el 104 es el operativo porque tiene el usuario de portal (Yair). C365 quedó en el 104; el 103 se marcó como LEGACY/DUPLICADO en
partners.notes(aún tiene attribution vieja de Samsung, no borrar). - Strongmetrics se creó desde cero (107) — TODO: IO, datos de billing, contact_email para invitarlo.
- No se envió email de invitación a ninguno (alta directa en DB). Xapads/BEdigitech ya tenían usuario — al entrar verán C365 aparecer en el switcher de cliente. Para avisarles formalmente:
POST /api/invitations(role partner, partner_id) re-envía el email de bienvenida, o se les avisa por WhatsApp. - Para el canal app: el partner pone su token en
af_sub1del tracking de AF (o en el nombre de campaña) — así el matcher atribuye porsub1(attribution_field del cliente).
Portal del partner: switchers
El portal tiene dos selectores en el top bar (src/v2/pages/PartnerPortal.tsx):
- Cliente (
pp-client-switcher, línea 350): aparece solo con 2+ clientes (derivado departner_campaigns). Todo el portal se scopea a un cliente a la vez (los modelos de dinero no se mezclan). - Campaña (
pp-campaign-switcher, línea 371): "All campaigns" + cada campaña activa del cliente seleccionado; aparece solo con 2+ campañas. Para C365 verán: All / C365 — Web / C365 — FB Web / C365 — App.
El truco del channel (importante)
En la ruta de network postbacks (/s2s/:id, /admitad/:id, /everflow/:id) no se persisten media_source ni campaign ni campaign_id en el evento de ClickHouse — el click join solo resuelve partner_id (ver backbone/internal/handler/everflow.go:150-161 vs el path pixel en batch.go:392-407 que sí propaga campaña). Dos funnels que usen el mismo event_name llegan idénticos a CH.
Solución sin código ni cambios del cliente: buildNetworkPayload fusiona los query params de la URL del postback dentro del payload → caen en event_properties. Por eso las URLs entregadas llevan un tag estático:
POST https://ingest.relo.mx/s2s/13?key=<token_web>&channel=web
POST https://ingest.relo.mx/s2s/14?key=<token_fbweb>&channel=fb_web
Cada evento cae con event_properties.channel = 'web' | 'fb_web' → reporting por canal garantizado (queryable y usable en segment rules vía prop:channel). Usar este patrón en cualquier cliente S2S multi-funnel.
Flujo end-to-end
Payload del postback (contrato con el cliente)
{
"click_id": "<relo_click_id de la landing URL — requerido>",
"lead_id": "<id único del lead en Crédito 365 — requerido, dedup>",
"event_name": "lead_submit",
"value": 0
}
- Acepta GET o POST (JSON, form o query params). Moneda default MXN.
- Ping de conectividad: disparar la URL solo con
key(sin payload) responde{"status":"ok"}sin escribir evento. - El
lead_idse hashea a unevent_iddeterminista de 26 chars (dedupIDenbackbone/internal/ingest/normalize.go:109-121) — el lead_id original queda enevent_properties.lead_id.
QA ejecutado (2026-10-05/06)
| Prueba | Resultado |
|---|---|
Links 302 + relo_click_id + cookie _relo_cid | ✅ ambos |
| Click registrado en cache con partner 106 / client 50 | ✅ |
| End-to-end: click → postback → evento en CH atribuido | ✅ partner_id=106, click_id correcto |
| Evento sin click_id | ✅ ingresa no atribuido (correcto) |
| Dedup: mismo lead_id disparado 2 veces | ✅ 1 solo evento |
| Ping / key mala / sin key / ds inexistente | ✅ ok / 401 / 401 / 404 |
channel en query param → event_properties.channel | ✅ |
| Limpieza post-QA | ✅ 5 eventos de prueba borrados de CH (ALTER TABLE relo.events DELETE WHERE client_id=50), contadores de data sources en 0 |
Nota: DELETE FROM (lightweight) está bloqueado en relo.events por proyecciones (lightweight_mutation_projection_mode=THROW) — usar ALTER TABLE ... DELETE para limpiezas. La limpieza post-QA tiene 3 pasos: (1) ALTER TABLE relo.events DELETE, (2) resetear contadores events_received de los data sources, y (3) borrar las filas QA de partner_lead_daily — SyncLeadCommissions corre cada 10 min y rola los eventos de prueba a ese agregado; si no se borra, la RPC calculate_client_lead_income muestra income fantasma (pasó en el QA de 2026-10-06: €52 fantasma por una fila con count 4).
Economía del deal
No se documenta aquí — docs.relo.mx es público y el partner nunca debe ver lo que Relo cobra al cliente (regla no-ammo). Los términos del deal (client rate, payout, margen) viven en el repo privado: docs/sales/credito365-deal.md.
Config: client_lead_rates (id 3) y partner_lead_rates × 3 partners ya creados — montos solo en el repo privado. El partner house (Relo Direct, 106) no lleva rate (su costo es el spend de FB).
Pendientes para go-live real
-
client_lead_ratesclient 50 (id 3, efectivo 2026-10-01) — monto endocs/sales/credito365-deal.md(privado) -
partner_lead_rates× 3 partners (Strongmetrics 107, Xapads 104, BEdigitech 13), efectivo 2026-10-06 — monto endocs/sales/credito365-deal.md(se configuró primero como EUR por error; corregido a USD el mismo día + email de corrección a los partners) -
partner_campaigns× 3 partners × 3 campañas (29/30/31) - Usuarios de portal: Xapads (Yair) y BEdigitech (Akhil) ya tenían. Strongmetrics: invitaciones en
partner_invitations+ signup links enviados por email de plataforma - Aviso a partners: emails de lanzamiento enviados a los 4 contactos (2026-10-06,
email_log3726-3729) - AppsFlyer S2S (app): Valentyn configura en su dashboard →
s2s.relo.mx/postback/appsflyer?client_id=50. OJO: el HMACAF_SIGNATURE_SECRETes global — verificar que compartirlo no rompa la verificación de otro cliente AF S2S antes de entregarlo - Cuando el cliente avise su primer test lead: verificar en CH que cae con
partner_id,channelylead_idcorrectos, y avisarle que quedó atribuido
Troubleshooting
| Síntoma | Causa probable | Fix |
|---|---|---|
Leads llegan pero partner_id=0 | El sitio no capturó relo_click_id o el click cache expiró (30d) | Revisar implementación del cliente; verificar click en redis-cli GET click:<ulid> |
| Mismo lead contado 2 veces | El cliente no manda lead_id o manda uno distinto por re-fire | El dedup necesita lead_id estable por lead |
| 401 en el postback | Token viejo o mal copiado | Comparar con extra_config.auth_token en admin → Tracking sources |
| No se distingue web de fb_web en reportes | Eventos sin channel en props (URL sin el param) | Revisar que disparan a la URL completa con &channel= |
| Lead en CH pero $0 comisión | Faltan partner_lead_rates para client 50 | Configurar rate (ver pendientes) |