> ## 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.

# GoHighLevel

> Integra Dodo Payments con GoHighLevel (GHL) mediante enlaces de pago sin código, checkout superpuesto o checkout integrado, y automatiza el cumplimiento con webhooks.

## Introducción

[GoHighLevel](https://www.gohighlevel.com/) (GHL) es una plataforma CRM y de marketing todo en uno que incluye embudos, sitios web, correo electrónico/SMS y automatización ("Workflows"). GHL no incluye Dodo Payments como procesador integrado, por lo que debes conectar ambos servicios de una de estas tres formas, según el nivel de integración que quieras para el checkout y cuánto código puedas utilizar.

En todos los enfoques, el cumplimiento se gestiona de la misma manera. Dodo envía [eventos de webhook](/developer-resources/webhooks) a un **Inbound Webhook Workflow** de GHL, que etiqueta al contacto, concede acceso y envía confirmaciones.

## Elige tu enfoque

| Enfoque                     | Código necesario                    | Experiencia de checkout                               | Ideal para                                                     |
| --------------------------- | ----------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------- |
| **A. Enlaces de pago**      | Ninguno (sin código)                | El cliente es redirigido al checkout alojado de Dodo  | La mayoría de los usuarios de GHL, lanzamiento rápido          |
| **B. Checkout superpuesto** | Código personalizado más un backend | Se abre un modal sobre tu página de GHL               | Equipos que quieren checkout en la página sin salir del embudo |
| **C. Checkout integrado**   | Código personalizado más un backend | El formulario de checkout está integrado en la página | UX totalmente integrada y con marca                            |

<Info>
  ¿Es tu primera vez? Comienza con el **Enfoque A (Enlaces de pago)**. No requiere código, funciona para cualquier usuario de GHL y se configura en minutos. Los enfoques B y C necesitan un backend para crear [checkout sessions](/api-reference/checkout-sessions/create) y están dirigidos a equipos que se sienten cómodos trabajando con código.
</Info>

## Requisitos previos

* Una cuenta de Dodo Payments con al menos un **product** creado.
* Una cuenta de GoHighLevel con un embudo, sitio web o workflow.
* Acceso a **Settings → Webhooks** (y a **Settings → Developer** para obtener una API key) en tu dashboard de Dodo.
* Para los enfoques B y C: un pequeño **backend o endpoint serverless** para crear checkout sessions.

<Note>
  GHL requiere un **connected domain** para *publicar* un embudo. Mientras lo estés creando, usa la **Preview** del embudo para probarlo. Ten en cuenta que el JavaScript personalizado (enfoques B y C) normalmente solo se ejecuta en la **página publicada en un dominio real**, no en Preview.
</Note>

## Cumplimiento con webhooks (todos los enfoques)

Esta es la capa de automatización. Configúrala una vez y funcionará independientemente del enfoque de checkout que elijas.

<Steps>
  <Step title="Create the workflow">
    En tu **sub-account** de GHL, abre **Automation** en el menú izquierdo (esto te llevará a la pestaña **Workflows**). Haz clic en **Create workflow** y selecciona **Start from Scratch**.
  </Step>

  <Step title="Add the Inbound Webhook trigger">
    En el builder, haz clic en **Add new trigger**. En el panel **Add trigger**, busca **webhook** y selecciona **Inbound webhook** (en **Triggers → Events**). Copia la **Webhook URL** que se genere.
  </Step>

  <Step title="Register the webhook in Dodo">
    En el dashboard de Dodo, ve a **Settings → Webhooks**, añade un endpoint nuevo y pega la URL del Inbound Webhook de GHL. Realiza una compra de prueba para que GHL capture un payload de ejemplo y puedas asignar los campos (correo electrónico del cliente, producto, importe y estado).
  </Step>

  <Step title="Add fulfillment actions">
    De vuelta en el workflow de GHL, añade acciones basadas en el evento, como **find/create contact by email**, **add a tag**, **grant course/membership access** y **send a confirmation email**. Después, **Publish** el workflow.
  </Step>
</Steps>

<Warning>
  Los pagos se procesan en Dodo, por lo que **no** aparecerán en la pestaña Payments de GHL. Concílialos en GHL mediante el workflow de webhook anterior y considera el **webhook como la fuente de verdad** para conceder acceso, no la redirección del navegador, ya que el cliente puede cerrar la pestaña antes de regresar.
</Warning>

## Enfoque A: Enlaces de pago (sin código)

Añade un enlace de pago de Dodo a cualquier botón de GHL, CTA del embudo, botón de la página de pedido, correo electrónico o SMS.

<Steps>
  <Step title="Create a product and copy its payment link">
    En el dashboard de Dodo, ve a **Products → Add Product**, establece el **name** y el **price**, elige **one-time** o **subscription** y haz clic en **Save**. Abre el producto y copia su **Payment Link** (formato: `https://checkout.dodopayments.com/buy/{product_id}`).
  </Step>

  <Step title="Add the link to your GHL button">
    Edita tu embudo o página web, selecciona el **Buy / Checkout button**, establece su acción en **Open URL / Website** y pega tu enlace de pago de Dodo.
  </Step>

  <Step title="Set a success page (optional)">
    Establece la **return URL** del producto en Dodo en una página de agradecimiento de GHL para que los clientes regresen a tu embudo después de pagar.
  </Step>
</Steps>

<Tip>
  Puedes rellenar previamente y bloquear los datos del cliente, o añadir seguimiento, mediante [parámetros de consulta de payment links](/features/checkout). Esto resulta útil para enviar un ID de embudo u oferta como metadata que puedas leer posteriormente desde el webhook.
</Tip>

## Enfoque B: Checkout superpuesto (código personalizado)

Abre el checkout de Dodo como un **modal superpuesto** en tu página de GHL mediante el [Checkout SDK](/developer-resources/overlay-checkout) a través de CDN. Requiere un backend para crear una [checkout session](/api-reference/checkout-sessions/create) y devolver su `checkoutUrl`.

<Steps>
  <Step title="Create a backend endpoint that calls the Checkout Sessions API">
    Este paso **no es opcional**. El SDK necesita un `checkoutUrl` activo, y para crear uno necesitas tu **secret API key**. GHL solo aloja páginas estáticas; no puede ejecutar esta llamada del lado del servidor por ti. Además, nunca debes llamar directamente a la [Create Checkout Session API](/api-reference/checkout-sessions/create) desde el navegador, ya que expondrías tu clave secreta en el código fuente de la página. Por tanto, el checkout superpuesto y el integrado **no pueden funcionar únicamente con GHL**: necesitas un backend bajo tu control que cree la sesión y devuelva solo la URL.

    Cualquier backend pequeño funciona: una función serverless (Cloudflare Workers, Vercel Functions, AWS Lambda, Supabase Edge Functions y similares) o un endpoint en un servidor que ya administres. La lógica es la misma en todos los casos: recibe la solicitud, llama a la API de Dodo con tu clave secreta y devuelve el `checkout_url`.

    Lógica de ejemplo para el handler (adáptala a la plataforma que prefieras):

    ```js theme={null}
    async function createCheckout(env) {
      const res = await fetch("https://test.dodopayments.com/checkouts", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${env.DODO_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          product_cart: [{ product_id: "pdt_your_product_id", quantity: 1 }],
        }),
      });

      const data = await res.json();
      return { checkoutUrl: data.checkout_url };
    }
    ```

    Guarda tu API key de Dodo como un secreto en la plataforma en la que realices el despliegue (nunca la incluyas en el código), permite solicitudes desde tu dominio de GHL (CORS) y publica el endpoint bajo un dominio que controles, por ejemplo, `https://api.example.com/create-checkout`. Cambia a `https://live.dodopayments.com/checkouts` cuando pases al modo live.
  </Step>

  <Step title="Add a Custom Code element in the GHL page builder">
    Abre el paso del embudo o la página web en el page builder de GHL y, a continuación:

    1. Haz clic en el icono **+** situado en la parte superior izquierda del builder para abrir **Quick Add**.
    2. Selecciona **Elements** en la lista de categorías de la izquierda.
    3. Busca **Custom Code** (también aparece como HTML) y arrástralo a la página.
    4. Pega el código siguiente en el editor de código del elemento y guárdalo.

    ```html theme={null}
    <!-- Load the Dodo Checkout SDK -->
    <script src="https://cdn.jsdelivr.net/npm/dodopayments-checkout@latest/dist/index.js"></script>
    <script>
      DodoPaymentsCheckout.DodoPayments.Initialize({
        mode: "test", // change to "live" in production
        displayType: "overlay",
        onEvent: (event) => console.log("Checkout event:", event),
      });

      async function openDodoCheckout() {
        // calls the backend endpoint from the previous step, creating a fresh session per click
        const res = await fetch("https://api.example.com/create-checkout", { method: "POST" });
        const { checkoutUrl } = await res.json();

        DodoPaymentsCheckout.DodoPayments.Checkout.open({ checkoutUrl });
      }
    </script>

    <button onclick="openDodoCheckout()">Pay Now</button>
    ```
  </Step>

  <Step title="Publish and test on your domain">
    El JS personalizado se ejecuta en la página **publicada** (conectada a un dominio), pero no siempre en Preview. Publica la página y haz clic en **Pay Now** para confirmar que se abre el checkout superpuesto.
  </Step>
</Steps>

## Enfoque C: Checkout integrado (embebido)

Integra el formulario de checkout **dentro de tu página de GHL** (sin redirección ni ventana emergente) mediante el mismo SDK y un contenedor de montaje. Al igual que el enfoque B, necesita un backend para crear la sesión.

<Steps>
  <Step title="Create a backend endpoint that calls the Checkout Sessions API">
    Tiene el mismo requisito que el checkout superpuesto y tampoco es **opcional**: crear una sesión requiere tu clave secreta de API, por lo que debe hacerse del lado del servidor. GHL no puede hacerlo por sí solo. Reutiliza el mismo endpoint de backend descrito anteriormente en la sección **Checkout superpuesto** (cualquier función serverless pequeña o servidor que controles) que llame a la [Create Checkout Session API](/api-reference/checkout-sessions/create) y devuelva `{ checkoutUrl }`.
  </Step>

  <Step title="Add a container and SDK via Custom Code">
    En el page builder de GHL:

    1. Haz clic en el icono **+** situado en la parte superior izquierda del builder para abrir **Quick Add**.
    2. Selecciona **Elements** en la lista de categorías de la izquierda.
    3. Busca **Custom Code** (también aparece como HTML) y arrástralo a la página donde quieras que aparezca el formulario de checkout.
    4. Pega el código siguiente en el editor de código del elemento y guárdalo.

    ```html theme={null}
    <script src="https://cdn.jsdelivr.net/npm/dodopayments-checkout@latest/dist/index.js"></script>

    <div id="dodo-inline-checkout"></div>

    <script>
      DodoPaymentsCheckout.DodoPayments.Initialize({
        mode: "test",
        displayType: "inline",
        onEvent: (event) => console.log("Checkout event:", event),
      });

      async function mountDodoCheckout() {
        // calls the backend endpoint from the previous step
        const res = await fetch("https://api.example.com/create-checkout", { method: "POST" });
        const { checkoutUrl } = await res.json();

        DodoPaymentsCheckout.DodoPayments.Checkout.open({
          checkoutUrl,
          elementId: "dodo-inline-checkout",
        });
      }

      mountDodoCheckout();
    </script>
    ```
  </Step>

  <Step title="Verify your domain for wallets (Apple Pay)">
    Para usar Apple Pay en el checkout integrado, [verifica tu dominio](/features/payment-methods/digital-wallets#apple-pay). Aloja el archivo de asociación y registra el dominio en el dashboard.
  </Step>
</Steps>

<Warning>
  El checkout integrado es la opción más compleja en GHL. Requiere código personalizado, un backend, una página publicada en un dominio real y verificación del dominio (para Apple Pay). Si no necesitas un formulario totalmente integrado, prefiere el enfoque A o B.
</Warning>

## Eventos que debes gestionar

| Evento de Dodo                                    | Cuándo se activa               | Acción sugerida en GHL                                                   |
| ------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------ |
| `payment.succeeded`                               | Se captura un pago             | Etiquetar el contacto como pagado, conceder acceso y enviar confirmación |
| `subscription.active`                             | Se activa una suscripción      | Conceder acceso a la membresía e iniciar el workflow de incorporación    |
| `subscription.renewed`                            | Se cobra un pago de renovación | Ampliar el acceso para el siguiente ciclo                                |
| `subscription.on_hold`                            | Una renovación falla           | Activar un workflow de reclamación de pagos o recordatorio               |
| `subscription.cancelled` / `subscription.expired` | Finaliza una suscripción       | Eliminar el acceso y etiquetar como cliente perdido                      |

Cada webhook incluye el **customer email**. Usa la acción **find/create contact by email** de GHL para asociar el pago con el contacto correcto. Para consultar la lista completa, visita la [Guía de eventos de Webhook](/developer-resources/webhooks/intents/webhook-events-guide).

## Pruebas y puesta en producción

<Steps>
  <Step title="Test in test mode">
    Mantén Dodo en **Test Mode**, usa la tarjeta de prueba `4242 4242 4242 4242` (cualquier fecha de caducidad futura y cualquier CVC), completa una compra y confirma que el workflow de GHL se activa y aplica la etiqueta o el acceso.
  </Step>

  <Step title="Go live">
    Cambia Dodo a **Live Mode** y actualiza el endpoint del webhook del modo live. Los demás cambios dependen de tu enfoque:

    * **Enlaces de pago (A):** sustituye el enlace por el **live** del producto.
    * **Checkout superpuesto (B):** configura tu backend para usar `https://live.dodopayments.com/checkouts` con tu API key **live**, y establece `mode` del SDK en `"live"` en la llamada `Initialize`.
    * **Checkout integrado (C):** igual que el checkout superpuesto, ya que utiliza el mismo endpoint de backend y la misma inicialización del SDK.

    Después, realiza una compra real completa para confirmarlo.
  </Step>
</Steps>

## Consejos

<Tip>
  Considera el **webhook como la fuente de verdad** para conceder acceso. Actúa según `payment.succeeded` / `subscription.active`, no según la redirección del navegador.
</Tip>

<Tip>
  Verifica la autenticidad del webhook mediante el encabezado `webhook-signature` ([Standard Webhooks](/developer-resources/webhooks)), para que solo los eventos genuinos de Dodo activen el cumplimiento en GHL.
</Tip>

## Solución de problemas

<AccordionGroup>
  <Accordion title="Payment succeeded but nothing happened in GHL">
    Comprueba que el endpoint del webhook de Dodo apunte a la URL correcta del Inbound Webhook de GHL, que el workflow esté **publicado** y que el trigger haya capturado un payload de ejemplo para que exista la asignación de campos.
  </Accordion>

  <Accordion title="Overlay or inline button does nothing">
    El JS personalizado normalmente solo se ejecuta en la **página publicada (dominio real)**, no en Preview. Confirma que la página esté publicada, que el SDK `<script>` se haya cargado y que `checkoutUrl` sea una URL de sesión válida procedente de tu backend.
  </Accordion>

  <Accordion title="Contact not created or not matched">
    Asegúrate de que tu workflow utilice **find/create contact by email** y que el campo de correo electrónico esté asignado desde el payload del webhook.
  </Accordion>

  <Accordion title="Payment isn't showing in GHL's Payments tab">
    Es lo esperado. Los pagos se procesan en Dodo, por lo que debes conciliarlos en GHL mediante el workflow de webhook.
  </Accordion>
</AccordionGroup>
