Paddle es el proveedor de pagos como comerciante de registro utilizado por muchas empresas SaaS de la UE. Paddle gestiona el IVA de la UE, el impuesto sobre las ventas en EE. UU., los reembolsos, los contracargos y el cumplimiento normativo global en su nombre, y luego le transfiere el neto.
Conectar Paddle a Zenovay le permite ver los ingresos de Paddle junto con sus datos de tráfico: qué campañas cierran el trato, qué páginas convierten, qué fuentes tienen el mejor LTV.
Solo necesita UNA cosa: una clave API de Paddle con permiso de escritura. Zenovay crea el destino del webhook en su nombre, captura el secreto de firma a través de la API de Paddle y almacena ambos, cifrados. El mismo flujo tanto si conecta Sandbox como Live; simplemente selecciona el entorno que corresponda con el botón Sandbox/Live en el formulario.
Configuración (2 minutos)
Generar una clave API con permiso de escritura en Paddle
Haga clic en New API key → asígnele el nombre "Zenovay analytics" → permiso: Write → Create.
Paddle muestra la clave UNA SOLA VEZ. Cópiela ahora. Las claves Live comienzan con
pdl_live_apikey_…; las claves sandbox comienzan conpdl_sdbx_apikey_….Péguela en Zenovay y haga clic en Save Configuration
- En
app.zenovay.com, abra su sitio desde Domains, vaya a Settings y seleccione la pestaña Revenue. - Haga clic en la tarjeta Paddle.
- Pegue la clave API y establezca el botón Sandbox/Live para que coincida (
pdl_sdbx_apikey_…las claves son Sandbox;pdl_live_apikey_…las claves son Live). Si el botón y el prefijo de la clave no coinciden, la conexión se rechaza con un mensaje de error claro. - Haga clic en Save Configuration.
- En
Eso es todo. En segundo plano, Zenovay:
- Valida la clave contra el endpoint
/event-typesde Paddle. - Llama a
POST /notification-settingspara crear un destino de webhook enhttps://api.zenovay.com/api/webhooks/paddle/<su-website-id>suscrito a los cuatro eventos canónicos (transaction.completed,subscription.created,subscription.updated,subscription.canceled). - Captura
endpoint_secret_keyde la respuesta de Paddle y lo almacena cifrado. - Cambia la tarjeta a Connected.
Nunca toca el panel de Paddle. Nunca ve ni copia un secreto de firma. Cada webhook de Paddle se verifica usando el secreto almacenado antes de cualquier escritura en la base de datos.
"¿Dónde encuentro mi secreto de firma en Paddle?" — respuesta corta: no es necesario
Esta es la confusión más común. Paddle deliberadamente oculta el secreto de firma en su panel tras crear el destino. No hay ningún botón "reveal" ni enlace "show": solo Rotate Secret (que invalida el anterior y le da uno nuevo). Para las cuentas que SÍ muestran el secreto en el momento de la creación, tiene una breve ventana para copiarlo antes de que desaparezca.
Este es el comportamiento normal de Paddle, no un error. Existe por una razón de seguridad: los secretos en las interfaces de usuario se filtran en capturas de pantalla, tickets de soporte y miradas indiscretas.
Por eso exactamente el flujo de Connect de Zenovay no requiere que lo encuentre. Usamos la API de Paddle (que SÍ expone el secreto programáticamente para sus propios destinos) para obtenerlo automáticamente. Nunca lo toca.
¿Qué pasa si ya creé el destino manualmente?
No hay problema. Al guardar la tarjeta Paddle en Zenovay:
- Si ya existe un destino en nuestra URL, Zenovay lo reutiliza y obtiene el secreto a través de la API.
- Si está actualmente inactivo (por ejemplo, alguien lo desactivó en el panel de Paddle), Zenovay lo reactiva.
- Sin destinos duplicados, sin limpieza manual.
¿Qué pasa si quiero configurarlo manualmente de todas formas?
Puede hacerlo, pero es una fricción sin beneficio. Si insiste:
Pasos de configuración manual (no recomendado)
- En Paddle → Notifications → Destinations → New destination → Webhook.
- URL:
https://api.zenovay.com/api/webhooks/paddle/YOUR_WEBSITE_ID(su ID de sitio web es el UUID en la URL de la página cuando abre el sitio desde Domains enapp.zenovay.com; también aparece en la parte superior de la pestaña Revenue de configuración). - Suscríbase a All events (Zenovay ignora silenciosamente todo lo que no gestiona).
- Guarde el destino.
- Aquí es donde la mayoría se atasca: Paddle puede o no mostrar el secreto de firma en la pantalla siguiente. Si no lo hace:
- Opción A: Rote el secreto (Paddle → Destinations → haga clic en su destino → Rotate Secret). Copie el nuevo valor.
- Opción B: Elimine este destino y use el flujo Connect de Zenovay (Zenovay lo recreará y obtendrá el secreto a través de la API).
- En Zenovay → tarjeta de Paddle → abra la sección Advanced (optional) después de pegar su clave API → pegue el secreto de firma
pdl_ntfset_…en el campo Webhook Secret. - Guarde.
Para el 99% de los usuarios, simplemente use el flujo Connect anterior y omita esto.
Etiquete sus transacciones con el ID de visitante (recomendado)
Para que la atribución de pagos a la fuente de tráfico funcione con la mayor precisión posible, configure el ID anónimo de Zenovay del visitante como custom_data al crear la transacción o el proceso de pago de Paddle en su servidor:
// Node.js example using Paddle's API directly
const visitorId = req.cookies['zv_visitor_id']; // however your client passes it
await fetch('https://api.paddle.com/transactions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PADDLE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [{ price_id: 'pri_01h…', quantity: 1 }],
customer_id: paddleCustomerId,
custom_data: { zenovay_visitor_id: visitorId },
}),
});
Cuando la transacción se completa, Zenovay lee data.custom_data.zenovay_visitor_id y vincula el pago a la sesión del visitante, incluyendo la fuente, la campaña y las páginas que visitó antes de pagar.
Si no configura custom_data, la atribución funciona igualmente mediante la dirección de email del cliente (cuando está presente en el evento), pero es menos precisa: solo coincide si el visitante se identificó previamente con el mismo email.
Modelo de atribución utilizado
Zenovay admite dos ventanas de atribución:
- First-touch (primer contacto): el crédito va a la fuente desde la que llegó el visitante en su primera sesión.
- Last-touch (último contacto): el crédito va a la fuente desde la que llegó en la sesión que contiene el pago.
Ambas se calculan y muestran lado a lado en la pestaña Revenue.
Paso 5: Pruebas en Sandbox
La forma correcta de verificar su integración de Sandbox es hacer un proceso de pago de prueba real:
- En el panel de sandbox de Paddle, cree un producto de prueba + precio.
- Use un proceso de pago superpuesto o una URL de proceso de pago alojado en una página de prueba que cargue su rastreador de Zenovay.
- Complete el proceso de pago con uno de los números de tarjeta de prueba de Paddle.
- En aproximadamente 10 segundos: Paddle envía un evento
transaction.completedreal y firmado a Zenovay. Verifique que llegó cargando la pestaña Revenue en Zenovay — la captura debería aparecer con el email y el importe del comprador.
Si la captura no aparece después de aproximadamente 30 segundos:
- Compruebe el indicador Verification status en la tarjeta de Paddle en la configuración de Zenovay.
- Confirme que el modo Sandbox vs Live coincide en ambos lados. Un panel de Paddle en entorno sandbox dispara eventos desde
sandbox-api.paddle.com; si Zenovay está configurado en modo Live, la verificación de firma fallará. - Confirme que el destino de notificación sigue habilitado en Paddle (Paddle deshabilita automáticamente los destinos después de 5 respuestas 5xx consecutivas; si Zenovay estaba desplegando durante su prueba, vuelva a habilitarlo).
Soporte de divisas
Paddle devuelve los importes de las transacciones en la unidad más pequeña de la moneda (por ejemplo, "4999" para $49,99 USD). Zenovay lo convierte correctamente según ISO 4217:
- Divisas decimales (USD, EUR, GBP, …): dividir por 100 →
4999se convierte en49,99. - Divisas sin decimales (JPY, KRW, VND, …): usar el valor tal cual →
5000JPY se mantiene en5000. - Divisas de tres decimales (BHD, KWD, OMR, …): dividir por 1000 →
1500BHD se convierte en1,500.
No necesita configurar nada: Zenovay lo hace automáticamente basándose en currency_code del evento.
Cambiar de Sandbox a Live
Cuando esté listo para producción:
- En el panel Live de Paddle (vendors.paddle.com, no sandbox-vendors), repita el Paso 1 y el Paso 2 para crear un destino de notificación Live y una clave API Live.
- En Zenovay, haga clic en la tarjeta Paddle → Disconnect (mantener el historial está bien) → haga clic de nuevo para reconectar → pegue las credenciales Live → cambie el interruptor a Live → Guardar.
La misma URL de webhook de Zenovay funciona para ambos entornos; Paddle envía los eventos al destino que coincide con su clave API activa.
Desconectar
Abra su sitio desde Domains → Settings → la pestaña Revenue → haga clic en la tarjeta de Paddle → Disconnect.
Por defecto, desconectar solo elimina sus credenciales de Paddle. Sus registros de pago existentes, el historial de atribución y los datos del panel de Revenue se mantienen intactos (sujetos a la ventana de retención de datos de su plan). Puede reconectarse en cualquier momento y continuar desde donde lo dejó.
Opcional: también eliminar los datos históricos de Paddle
El diálogo de desconexión incluye una casilla: "Also permanently delete N Paddle records ($X total)". Márquela solo si desea empezar de cero: por ejemplo, para desmantelar una integración de prueba o por motivos de limpieza de privacidad.
Cuando se marca, Zenovay:
- Eliminará todas las filas de eventos de pago de Paddle para este sitio web
- Eliminará todas las filas de pagos de Paddle para este sitio web
- Borrará el campo ID de cliente Paddle en cada usuario identificado (el registro de usuario en sí se conserva: mantienen su ID de Stripe, etc.)
La eliminación se ejecuta en una única transacción: si algún paso falla, los tres se revierten, por lo que nunca quedará en un estado a medias. La acción es irreversible.
No olvide deshabilitar el destino de notificación en Paddle
Desconectar en Zenovay solo detiene que Zenovay acepte eventos. Paddle seguirá disparando el destino en nuestro endpoint hasta que usted lo deshabilite en su panel de Paddle:
- Abra Paddle → Notifications → Destinations.
- Busque el destino que apunta a
https://api.zenovay.com/api/webhooks/paddle/{su-website-id}. - Haga clic en él → active Disabled (o Delete).
Hasta que lo haga, nuestro endpoint responde 400 "Webhook not configured for this website" a cada entrega. Paddle eventualmente deshabilitará automáticamente el destino después de suficientes fallos, pero la eliminación explícita es más limpia e impide que el destino ocupe espacio en su panel.
Limitaciones (V1)
- Los eventos de reembolso aún no se renderizan. Suscríbase a
adjustment.created/adjustment.updateden su destino de todas formas: Zenovay los ignora silenciosamente hoy y comenzará a renderizarlos tan pronto como se lance la V2. - Los eventos
subscription.past_dueysubscription.pausedse reciben y registran con deduplicación, pero aún no se renderizan en el panel. El estado de la suscripción cambia correctamente apast_due, pero no obtiene una vista de incidencia dedicada. - Una cuenta de Paddle por sitio web de Zenovay. Si acepta pagos a través de varias cuentas de Paddle (por ejemplo, una por cada subsidiaria geográfica), configure cada una en su propio sitio web de Zenovay.
- La conexión mediante redireccionamiento OAuth no es compatible. Solo se admite la introducción manual de credenciales.
Resolución de problemas
"Invalid Paddle API key" al guardar
Los tres sospechosos habituales:
- Entorno incorrecto. Una clave
pdl_sdbx_apikey_…con el interruptor en Live (o viceversa) falla la validación. Zenovay muestra este error con un mensaje específico: haga coincidir el interruptor con el prefijo. - La clave debe tener permiso de escritura Y no estar revocada. Las claves de solo lectura pasan la validación pero fallan cuando Zenovay intenta crear el destino (403). Las claves revocadas fallan la validación directamente (401). Genere una nueva clave con ámbito de escritura.
- La clave era para un equipo/cuenta diferente. Las claves API de Paddle están acotadas a una única cuenta de Paddle; pegar una clave de una cuenta diferente falla inmediatamente.
"Webhook not configured for this website"
O bien no ha guardado las credenciales de Paddle en Zenovay todavía, o bien está probando la URL de webhook incorrecta. La URL debe incluir el ID exacto de sitio web para el sitio conectado (el UUID en la URL de la página cuando abre el sitio desde Domains en app.zenovay.com).
"Signature verification failed: replay_window_exceeded"
Zenovay rechaza los eventos de webhook con marcas de tiempo con más de 5 minutos de diferencia respecto a la hora actual. Esto generalmente significa desincronización de reloj en su lado o en el de Paddle. Si ve esto en una prueba nueva:
- Reinicie su servidor (la deriva del reloj es poco común pero sucede después de un funcionamiento prolongado).
- Vuelva a activar el webhook desde el panel de Paddle (Notifications → Deliveries → Resend).
El webhook verificado llega pero la transacción no aparece en la pestaña Revenue
El webhook de Paddle llega en 3 formas distintas dependiendo de si el cliente fue creado de forma independiente o como parte de un proceso de pago. El parser de Zenovay es defensivo, pero si ve una entrega verificada en sus registros y nada en Revenue:
- Confirme que la entrega retornó 2xx en el registro de entregas de Paddle. Una discrepancia de firma o entorno se muestra allí como 4xx.
- Si falta el email del comprador en el evento, Zenovay vuelve a la coincidencia por ID de cliente Paddle. La transacción está registrada pero no aparecerá en las vistas de usuario identificado hasta que el mismo cliente esté vinculado mediante un upsert de usuario identificado futuro.
- Si aún no aparece, póngase en contacto con el soporte en [email protected] con el ID de entrega de Paddle para que podamos rastrearlo.