Saltar al contenido principal

Introducción

Dub es una poderosa plataforma de gestión de enlaces que te ayuda a crear, compartir y rastrear enlaces cortos. Al integrar Dodo Payments con Dub, puedes rastrear automáticamente los eventos de conversión de ventas cuando los clientes completan compras, lo que te permite medir el ROI de tus campañas de marketing y programas de referencia. Un evento de “venta” se registra en Dub cuando un cliente:
  • Completa un pago único
  • Se suscribe a un plan de pago
  • Realiza un pago de suscripción recurrente
Esta integración requiere una cuenta de Dub con el seguimiento de conversiones habilitado en tus enlaces.

Cómo Funciona

Dub rastrea a los visitantes a través de un ID de clic único (dub_id) almacenado en una cookie cuando los usuarios hacen clic en tus enlaces cortos de Dub. Para atribuir ventas a tus enlaces, necesitas:
  1. Capturar el ID de clic de Dub de la cookie dub_id al crear sesiones de pago
  2. Almacenar el ID de clic en los metadatos de tu pago junto con el ID externo del cliente
  3. Enviar datos de venta a Dub cuando los pagos sean exitosos utilizando su API de seguimiento
Esto permite que Dub asocie las ventas exitosas con el clic original del enlace, dándote una atribución completa de la conversión.

Requisitos Previos

Antes de configurar esta integración, asegúrate de tener:
  1. Una cuenta de Dub con un espacio de trabajo
  2. Seguimiento de conversiones habilitado para tus enlaces
  3. Tu clave API de Dub (disponible en tu panel de Dub bajo Configuración → Claves API)

Comenzando

1

Habilitar el Seguimiento de Conversiones en Dub

En tu panel de Dub, habilita el seguimiento de conversiones para los enlaces que deseas rastrear ventas. Esto permite que Dub registre eventos de venta cuando los clientes completan compras.
Aprende más sobre cómo habilitar el seguimiento de conversiones en la documentación de Dub.
2

Obtén tu Clave API de Dub

Navega a tu panel de Dub → Configuración → Claves API y crea una nueva clave API con el alcance conversions.write.
Mantén tu clave API segura y nunca la expongas en código del lado del cliente.
3

Capturar ID de Clic en el Pago

Al crear una sesión de pago, captura el ID de clic de Dub de la cookie y agrégalo a los metadatos de tu pago.
4

Enviar Datos de Venta a través de Webhook

Configura un webhook para enviar datos de venta a la API de seguimiento de Dub cuando los pagos sean exitosos.
5

¡Listo!

Los eventos de conversión de ventas ahora aparecerán en tu panel de análisis de Dub con atribución completa a tus enlaces.

Guía de Implementación

Paso 1: Agregar ID de Clic y ID de Cliente a los Metadatos del Pago

Al crear una sesión de pago, captura el ID de clic de Dub de la cookie e inclúyelo en los metadatos de tu pago junto con el ID externo de tu cliente.
import { cookies } from 'next/headers';
import DodoPayments from 'dodopayments';

const client = new DodoPayments();

export async function createCheckout(productId: string, customerId: string) {
  // Capture Dub click ID from cookie
  const dubClickId = cookies().get('dub_id')?.value;

  const payment = await client.payments.create({
    billing: {
      city: 'New York',
      country: 'US',
      state: 'NY',
      street: '123 Main St',
      zipcode: '10001',
    },
    customer: {
      email: '[email protected]',
      name: 'John Doe',
    },
    product_id: productId,
    metadata: {
      dub_click_id: dubClickId,           // Store Dub click ID
      dub_external_id: customerId,        // Store your customer's unique ID
    },
  });

  return payment;
}

Paso 2: Enviar Datos de Venta a Dub

Configura un endpoint de webhook para enviar datos de venta a la API de seguimiento de Dub cuando los pagos sean exitosos.
1

Abrir la Sección de Webhook

En tu panel de Dodo Payments, navega a Webhooks → + Agregar Endpoint y expande el menú desplegable de integraciones.
Agregar Endpoint y menú desplegable de integraciones
2

Seleccionar Dub

Elige la tarjeta de integración Dub.
3

Ingresar Clave API

Proporciona tu Clave API de Dub en el campo de configuración.
Agregar Clave API
4

Configurar Transformación

Edita el código de transformación para formatear los datos de pago para la API de Seguimiento de Ventas de Dub.
5

Probar y Crear

Prueba con cargas útiles de muestra y haz clic en Crear para activar la integración.

Ejemplos de Código de Transformación

Seguimiento Básico de Ventas

Rastrea ventas cuando los pagos son exitosos:
basic_sale.js
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const payment = webhook.payload.data;

    // Only send to Dub if click ID exists in metadata
    if (payment.metadata && payment.metadata.dub_click_id) {
      webhook.payload = {
        clickId: payment.metadata.dub_click_id,
        externalId: payment.metadata.dub_external_id || payment.customer.customer_id,
        amount: payment.total_amount, // Ensure the amount is in cents
        currency: payment.currency || "USD",
        paymentProcessor: "dodo",
        invoiceId: payment.payment_id,
        metadata: {
          customer_email: payment.customer.email,
          customer_name: payment.customer.name,
          product_id: payment.product_cart ? payment.product_cart.map(product => product.product_id).join(', ') : undefined,
        },
      };
    } else {
      // Cancel dispatch if no click ID (organic traffic)
      webhook.cancel = true;
    }
  }
  return webhook;
}

Rastrear Ventas de Suscripción

Rastrea tanto las suscripciones iniciales como los pagos recurrentes:
subscription_sale.js
function handler(webhook) {
  const data = webhook.payload.data;

  // Track initial subscription activation
  if (webhook.eventType === "subscription.active") {
    if (data.metadata && data.metadata.dub_click_id) {
      webhook.payload = {
        clickId: data.metadata.dub_click_id,
        externalId: data.metadata.dub_external_id || data.customer.customer_id,
        amount: data.recurring_pre_tax_amount, // Amount in cents
        currency: data.currency || "USD",
        paymentProcessor: "dodo",
        invoiceId: data.subscription_id,
        eventName: "Subscription Started",
        metadata: {
          subscription_id: data.subscription_id,
          product_id: data.product_id,
          billing_interval: data.payment_frequency_interval,
          customer_email: data.customer.email,
        },
      };
    } else {
      // Cancel dispatch if no click ID (organic traffic)
      webhook.cancel = true;
    }
  }

  // Track recurring subscription payments
  if (webhook.eventType === "subscription.renewed") {
    if (data.metadata && data.metadata.dub_click_id) {
      webhook.payload = {
        clickId: data.metadata.dub_click_id,
        externalId: data.metadata.dub_external_id || data.customer.customer_id,
        amount: data.recurring_pre_tax_amount,
        currency: data.currency || "USD",
        paymentProcessor: "dodo",
        invoiceId: `${data.subscription_id}_${Date.now()}`,
        eventName: "Subscription Renewed",
        metadata: {
          subscription_id: data.subscription_id,
          product_id: data.product_id,
          customer_email: data.customer.email,
        },
      };
    } else {
      // Cancel dispatch if no click ID (organic traffic)
      webhook.cancel = true;
    }
  }

  return webhook;
}

Rastrear Ventas con Exclusión de Impuestos

Envía solo el monto antes de impuestos a Dub para un seguimiento preciso de los ingresos:
sale_without_tax.js
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const payment = webhook.payload.data;

    if (payment.metadata && payment.metadata.dub_click_id) {
      // Calculate pre-tax amount (total minus tax)
      const preTaxAmount = payment.total_amount - (payment.tax || 0);

      webhook.payload = {
        clickId: payment.metadata.dub_click_id,
        externalId: payment.metadata.dub_external_id || payment.customer.customer_id,
        amount: preTaxAmount, // Pre-tax amount in cents
        currency: payment.currency || "USD",
        paymentProcessor: "dodo",
        invoiceId: payment.payment_id,
        metadata: {
          total_amount: payment.total_amount,
          tax_amount: payment.tax || 0,
          customer_email: payment.customer.email,
        },
      };
    } else {
      // Cancel dispatch if no click ID (organic traffic)
      webhook.cancel = true;
    }
  }
  return webhook;
}

Rastrear Ventas con Nombres de Eventos Personalizados

Usa nombres de eventos personalizados para categorizar diferentes tipos de ventas:
custom_events.js
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const payment = webhook.payload.data;

    if (payment.metadata && payment.metadata.dub_click_id) {
      // Determine event name based on payment type
      let eventName = "Purchase";
      if (payment.subscription_id) {
        eventName = "Subscription Purchase";
      } else if (payment.metadata && payment.metadata.is_upgrade) {
        eventName = "Plan Upgrade";
      }

      webhook.payload = {
        clickId: payment.metadata.dub_click_id,
        externalId: payment.metadata.dub_external_id || payment.customer.customer_id,
        amount: payment.total_amount,
        currency: payment.currency || "USD",
        paymentProcessor: "dodo",
        invoiceId: payment.payment_id,
        eventName: eventName,
        metadata: {
          product_id: payment.product_cart ? payment.product_cart.map(product => product.product_id).join(', ') : undefined,
          customer_email: payment.customer.email,
        },
      };
    } else {
      // Cancel dispatch if no click ID (organic traffic)
      webhook.cancel = true;
    }
  }
  return webhook;
}

Alternativa: Implementación del Lado del Cliente

Si prefieres rastrear ventas desde tu servidor en lugar de usar webhooks, puedes llamar a la API de Seguimiento de Dub directamente después de un pago exitoso:
'use server';

import { Dub } from 'dub';

const dub = new Dub();

export async function trackSale(
  paymentId: string,
  clickId: string,
  customerId: string,
  amount: number,
  currency: string
) {
  await dub.track.sale({
    clickId: clickId,
    externalId: customerId,
    amount: amount,
    currency: currency,
    paymentProcessor: 'dodo',
    invoiceId: paymentId,
  });
}

Mejores Prácticas

Captura el ID de clic temprano: Almacena el ID de clic de Dub lo antes posible en tu flujo de pago para asegurar una atribución precisa, incluso si el usuario navega lejos y regresa más tarde.
  • Siempre incluye el ID de clic en los metadatos: Sin el ID de clic, Dub no puede atribuir ingresos a tus enlaces
  • Usa IDs externos de manera consistente: Pasa el mismo ID de cliente que usas en tu sistema para análisis precisos a nivel de cliente
  • Maneja el tráfico orgánico con gracia: Establece webhook.cancel = true cuando no hay ID de clic para evitar llamadas API innecesarias
  • Prueba con pagos de muestra: Verifica que la integración funcione correctamente antes de activarla
  • Monitorea tu panel de Dub: Verifica que las ventas aparezcan correctamente con la atribución adecuada

Notas Importantes

  • Formato de monto: Dub espera montos en centavos (por ejemplo, $10.00 = 1000)
  • Moneda: Usa códigos de moneda ISO 4217 (USD, EUR, GBP, etc.)
  • Pruebas gratuitas: Los pagos de $0 no se rastrean como ventas
  • Reembolsos: Considera rastrear reembolsos por separado si es necesario para un informe de ingresos preciso

Solución de Problemas

  • Verifica que tu clave API de Dub sea correcta y tenga el alcance conversions.write
  • Asegúrate de que el dub_click_id se esté capturando y almacenando en los metadatos de pago
  • Asegúrate de que la transformación del webhook esté formateando correctamente la carga útil
  • Verifica que el webhook se esté activando en eventos payment.succeeded
  • Confirma que el seguimiento de conversiones esté habilitado para tus enlaces de Dub
  • Confirma que los usuarios estén haciendo clic en tus enlaces cortos de Dub antes del pago
  • Verifica que la cookie dub_id se esté configurando correctamente en tu dominio
  • Asegúrate de que los IDs de clic coincidan entre la creación del pago y la finalización del pago
  • Asegúrate de estar capturando el ID de clic antes de crear la sesión de pago
  • Valida que la estructura JSON coincida con el formato de la API de Seguimiento de Ventas de Dub
  • Verifica que todos los campos requeridos (clickId, externalId, amount) estén presentes
  • Asegúrate de que el monto esté en centavos (entero, no decimal)
  • Verifica que la URL del endpoint de la API sea correcta: https://api.dub.co/track/sale
  • Prueba la transformación con cargas útiles de webhook de muestra
  • Asegúrate de que solo estás rastreando en eventos payment.succeeded, no en payment.processing
  • Usa valores únicos invoiceId para cada venta
  • Para suscripciones, agrega marcas de tiempo o períodos de facturación para evitar duplicados en renovaciones

Recursos Adicionales

¿Necesitas ayuda? Contacta al soporte de Dodo Payments en [email protected] para obtener asistencia con la integración.