> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack

> Integra Dodo Payments con Slack para recibir notificaciones en tiempo real sobre tus pagos.

## Introducción

La integración de Dodo Payments con Slack te permite recibir notificaciones en tiempo real sobre tus pagos directamente en tu espacio de trabajo de Slack. Esta integración te permite mantenerte actualizado sobre el estado de tus pagos, rastrear transacciones y gestionar tus pagos de manera más eficiente.

<Info>
  Esta integración utiliza nuestro portal de gestión de webhooks para transformar automáticamente los eventos de webhook de Dodo Payments en mensajes compatibles con Slack. No se requiere código adicional: solo configura el conector y comienza a recibir notificaciones.
</Info>

## Comenzando

<Steps>
  <Step title="Open the Webhook Section">
    Ve a la sección de <b>Webhook</b> en tu panel de Dodo Payments. Haz clic en el botón <b>+ Add Endpoint</b>, luego abre el desplegable de webhook para revelar otras integraciones.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/1.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=46218103ebf0646011873758c76b9bb6" alt="Panel de Dodo Payments mostrando el botón Agregar Endpoint y el desplegable de integraciones" style={{ maxHeight: '500px', width: 'auto' }} width="1782" height="1016" data-path="images/integrations/slack/1.png" />
    </Frame>
  </Step>

  <Step title="Select Slack Integration">
    Selecciona la integración de <b>Slack</b> y haz clic en <b>Connect your Slack workspace</b>.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/2.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=4bd696f82dbbab1bc099c6ccae5b9212" alt="Tarjeta de integración de Slack y botón de conexión" style={{ maxHeight: '500px', width: 'auto' }} width="1670" height="226" data-path="images/integrations/slack/2.png" />
    </Frame>
  </Step>

  <Step title="Grant Slack Permissions">
    Concede los permisos necesarios a la aplicación Incoming Webhooks de Slack para que pueda publicar mensajes en el canal elegido.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/3.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=00f04516a2720e377a29551ae42ad812" alt="Pantalla de permisos de OAuth de Slack para la aplicación Incoming Webhooks" style={{ maxHeight: '500px', width: 'auto' }} width="1198" height="1536" data-path="images/integrations/slack/3.png" />
    </Frame>
  </Step>

  <Step title="Customize Transformation Code">
    Añade o edita el código de transformación para personalizar tus notificaciones de Slack según tu caso de uso. Puedes usar las plantillas predefinidas o escribir tu propia lógica.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/4.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=f3c7f2b7a9bb6d6ba1d1d6922ad42bc4" alt="Editor de código de transformación para la integración de Slack" style={{ maxHeight: '500px', width: 'auto' }} width="1686" height="1118" data-path="images/integrations/slack/4.png" />
    </Frame>
  </Step>

  <Step title="Test and Create">
    Prueba tu código de transformación con cargas de eventos personalizadas o predefinidas. Una vez satisfecho, haz clic en <b>Create</b> para activar la integración.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/slack/5.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=7d22a91488a2038a177324fa627b7497" alt="Prueba de transformación y botón de creación" style={{ maxHeight: '500px', width: 'auto' }} width="1852" height="490" data-path="images/integrations/slack/5.png" />
    </Frame>
  </Step>

  <Step title="Integration Complete!">
    🎉 ¡Has creado correctamente la integración con Slack! Los eventos de Dodo Payments ahora se entregarán en tiempo real a tu canal de Slack seleccionado.
  </Step>
</Steps>

## Ejemplos de código de transformación

### Notificaciones básicas de pagos

Esta transformación envía mensajes de texto simples para eventos de pago:

```javascript payment_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "payment.succeeded":
      webhook.payload = {
        text: `✅ Payment Successful\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}\nPayment ID: ${webhook.payload.data.payment_id}`
      };
      break;
      
    case "payment.failed":
      webhook.payload = {
        text: `❌ Payment Failed\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}\nReason: ${webhook.payload.data.error_message || 'Unknown'}`
      };
      break;
      
    case "payment.processing":
      webhook.payload = {
        text: `⏳ Payment Processing\nAmount: $${(webhook.payload.data.total_amount / 100).toFixed(2)}\nCustomer: ${webhook.payload.data.customer.email}`
      };
      break;
  }

  return webhook;
}
```

### Notificaciones ricas de suscripción

Esta transformación crea mensajes ricos de Slack con adjuntos para eventos de suscripción:

```javascript subscription_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "subscription.active":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "🎉 Subscription Activated",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.recurring_pre_tax_amount / 100).toFixed(2)}/${webhook.payload.data.payment_frequency_interval}`,
              short: true
            },
            {
              title: "Next Billing",
              value: new Date(webhook.payload.data.next_billing_date).toLocaleDateString(),
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "subscription.cancelled":
      webhook.payload = {
        attachments: [{
          color: "warning",
          title: "⚠️ Subscription Cancelled",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Cancellation Date",
              value: new Date(webhook.payload.data.cancelled_at).toLocaleDateString(),
              short: true
            },
            {
              title: "Cancel at Next Billing",
              value: webhook.payload.data.cancel_at_next_billing_date ? "Yes" : "No",
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "subscription.renewed":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "🔄 Subscription Renewed",
          fields: [
            {
              title: "Customer",
              value: webhook.payload.data.customer.email,
              short: true
            },
            {
              title: "Product ID",
              value: webhook.payload.data.product_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.recurring_pre_tax_amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Next Billing",
              value: new Date(webhook.payload.data.next_billing_date).toLocaleDateString(),
              short: true
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
  }

  return webhook;
}
```

### Notificaciones de gestión de disputas

Esta transformación maneja eventos de disputa con colores y urgencia apropiados:

```javascript dispute_notifs.js icon="js" expandable theme={null}
function handler(webhook) {
  switch (webhook.eventType) {
    case "dispute.opened":
      webhook.payload = {
        attachments: [{
          color: "danger",
          title: "🚨 New Dispute Opened",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Stage",
              value: webhook.payload.data.dispute_stage,
              short: true
            },
            {
              title: "Remarks",
              value: webhook.payload.data.remarks || "No remarks",
              short: false
            }
          ],
          footer: "Dodo Payments - Action Required",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "dispute.won":
      webhook.payload = {
        attachments: [{
          color: "good",
          title: "✅ Dispute Won",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Resolution",
              value: "Dispute resolved in your favor",
              short: false
            }
          ],
          footer: "Dodo Payments",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
      
    case "dispute.lost":
      webhook.payload = {
        attachments: [{
          color: "danger",
          title: "❌ Dispute Lost",
          fields: [
            {
              title: "Payment ID",
              value: webhook.payload.data.payment_id,
              short: true
            },
            {
              title: "Amount",
              value: `$${(webhook.payload.data.amount / 100).toFixed(2)}`,
              short: true
            },
            {
              title: "Status",
              value: webhook.payload.data.dispute_status,
              short: true
            },
            {
              title: "Impact",
              value: "Funds will be debited from your account",
              short: false
            }
          ],
          footer: "Dodo Payments - Review Required",
          ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
        }]
      };
      break;
  }

  return webhook;
}
```

### Manejador integral de todos los eventos

Esta transformación maneja todos los tipos de eventos con un formato consistente:

```javascript all_events_notifs.js icon="js" expandable  theme={null}
function handler(webhook) {
  const event = webhook.payload.data;
  const timestamp = new Date(webhook.payload.timestamp).toLocaleString();
  
  let color, emoji, title, fields = [];
  
  switch (webhook.eventType) {
    case "payment.succeeded":
      color = "good";
      emoji = "✅";
      title = "Payment Successful";
      fields = [
        { title: "Amount", value: `$${(event.total_amount / 100).toFixed(2)}`, short: true },
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Method", value: event.payment_method || "Unknown", short: true }
      ];
      break;
      
    case "payment.failed":
      color = "danger";
      emoji = "❌";
      title = "Payment Failed";
      fields = [
        { title: "Amount", value: `$${(event.total_amount / 100).toFixed(2)}`, short: true },
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Reason", value: event.error_message || "Unknown", short: false }
      ];
      break;
      
    case "subscription.active":
      color = "good";
      emoji = "🎉";
      title = "Subscription Activated";
      fields = [
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "Amount", value: `$${(event.recurring_pre_tax_amount / 100).toFixed(2)}/${event.payment_frequency_interval}`, short: true },
        { title: "Next Billing", value: new Date(event.next_billing_date).toLocaleDateString(), short: true }
      ];
      break;
      
    case "subscription.cancelled":
      color = "warning";
      emoji = "⚠️";
      title = "Subscription Cancelled";
      fields = [
        { title: "Customer", value: event.customer.email, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "Cancellation Date", value: new Date(event.cancelled_at).toLocaleDateString(), short: true },
        { title: "Cancel at Next Billing", value: event.cancel_at_next_billing_date ? "Yes" : "No", short: true }
      ];
      break;
      
    case "refund.succeeded":
      color = "good";
      emoji = "💰";
      title = "Refund Processed";
      fields = [
        { title: "Amount", value: `$${(event.amount / 100).toFixed(2)}`, short: true },
        { title: "Refund ID", value: event.refund_id, short: true },
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Reason", value: event.reason || "Not specified", short: true }
      ];
      break;
      
    case "dispute.opened":
      color = "danger";
      emoji = "🚨";
      title = "New Dispute Opened";
      fields = [
        { title: "Payment ID", value: event.payment_id, short: true },
        { title: "Amount", value: `$${(event.amount / 100).toFixed(2)}`, short: true },
        { title: "Status", value: event.dispute_status, short: true },
        { title: "Stage", value: event.dispute_stage, short: true },
        { title: "Remarks", value: event.remarks || "No remarks", short: false }
      ];
      break;
      
    case "license_key.created":
      color = "good";
      emoji = "🔑";
      title = "License Key Created";
      fields = [
        { title: "License ID", value: event.id, short: true },
        { title: "Product ID", value: event.product_id, short: true },
        { title: "License Key", value: event.key.substring(0, 8) + "...", short: true },
        { title: "Expires", value: event.expires_at ? new Date(event.expires_at).toLocaleDateString() : "Never", short: true }
      ];
      break;
      
    default:
      // Handle any other events with a generic format
      color = "warning";
      emoji = "ℹ️";
      title = webhook.eventType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
      fields = [
        { title: "Event Type", value: webhook.eventType, short: true },
        { title: "Timestamp", value: timestamp, short: true }
      ];
  }
  
  webhook.payload = {
    attachments: [{
      color: color,
      title: `${emoji} ${title}`,
      fields: fields,
      footer: "Dodo Payments",
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    }]
  };

  return webhook;
}
```

## Mejores prácticas

Para que tus notificaciones de Slack sean efectivas:

* Utiliza adjuntos enriquecidos con colores, campos y formato para mayor claridad y capacidad de acción.
* Incluye siempre datos clave como montos, correos electrónicos de clientes e identificadores para una identificación rápida.
* Elige colores que coincidan con el tipo de evento: verde (`good`) para éxito, rojo (`danger`) para disputas o fallos, amarillo (`warning`) para cancelaciones y azul (`#36a64f`) para eventos informativos.
* Agrega marcas de tiempo para ayudar a seguir cuándo ocurrió cada evento.

<Warning>
  **Maneja datos sensibles**: Ten cuidado de no incluir información sensible como claves completas de licencia o datos personales en los mensajes de Slack. Considera truncar o enmascarar los valores sensibles.
</Warning>

## Solución de problemas

<AccordionGroup>
  <Accordion title="Notifications not appearing in Slack">
    * Verifica que la URL del webhook de Slack sea correcta y esté activa
    * Comprueba que el código de transformación sea JavaScript válido
    * Asegúrate de que los tipos de eventos seleccionados se estén activando
    * Verifica que tu aplicación de Slack tenga los permisos necesarios
  </Accordion>

  <Accordion title="Transformation errors">
    * Consulta el portal de gestión de webhooks para ver los registros de errores de transformación
    * Verifica que la estructura de la carga útil del webhook coincida con tu código de transformación
    * Prueba tu código de transformación con datos de muestra
    * Asegúrate de que todos los campos requeridos estén presentes en la carga útil del webhook
  </Accordion>

  <Accordion title="Missing event types">
    * Confirma que los eventos que deseas recibir estén habilitados en tu configuración de webhook de Dodo Payments
    * Comprueba que los tipos de eventos estén seleccionados en la configuración de tu conector de Slack
    * Verifica que tu endpoint esté configurado correctamente para recibir los eventos
  </Accordion>
</AccordionGroup>
