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

> Integrasikan Dodo Payments dengan GoHighLevel (GHL) menggunakan payment links tanpa kode, overlay checkout, atau inline checkout, lalu otomatisasi fulfillment dengan webhook.

## Pendahuluan

[GoHighLevel](https://www.gohighlevel.com/) (GHL) adalah platform CRM dan marketing all-in-one yang mencakup funnels, website, email/SMS, serta automation ("Workflows"). GHL tidak mencantumkan Dodo Payments sebagai processor bawaan, jadi Anda perlu menghubungkan keduanya dengan salah satu dari tiga cara, tergantung seberapa terintegrasi pengalaman checkout yang Anda inginkan dan seberapa banyak kode yang dapat Anda gunakan.

Dalam setiap pendekatan, fulfillment ditangani dengan cara yang sama. Dodo mengirimkan [webhook events](/developer-resources/webhooks) ke **Inbound Webhook Workflow** GHL, yang menambahkan tag ke contact, memberikan access, dan mengirimkan confirmation.

## Pilih pendekatan Anda

| Pendekatan              | Kode yang diperlukan     | Pengalaman checkout                              | Cocok untuk                                                         |
| ----------------------- | ------------------------ | ------------------------------------------------ | ------------------------------------------------------------------- |
| **A. Payment Links**    | Tidak ada (no-code)      | Customer dialihkan ke hosted checkout milik Dodo | Sebagian besar pengguna GHL, peluncuran tercepat                    |
| **B. Overlay Checkout** | Kode kustom plus backend | Modal terbuka di atas halaman GHL Anda           | Tim yang menginginkan checkout di halaman tanpa meninggalkan funnel |
| **C. Inline Checkout**  | Kode kustom plus backend | Form checkout disematkan di dalam halaman        | UX yang sepenuhnya tersemat dan sesuai branding                     |

<Info>
  Baru mengenal ini? Mulailah dengan **Pendekatan A (Payment Links)**. Pendekatan ini tidak memerlukan kode, berfungsi untuk setiap pengguna GHL, dan dapat disiapkan dalam hitungan menit. Pendekatan B dan C memerlukan backend untuk membuat [checkout sessions](/api-reference/checkout-sessions/create) dan ditujukan bagi tim yang terbiasa menggunakan kode.
</Info>

## Prasyarat

* Akun Dodo Payments dengan setidaknya satu **product** yang telah dibuat.
* Akun GoHighLevel dengan funnel, website, atau workflow.
* Akses ke **Settings → Webhooks** (dan **Settings → Developer** untuk API key) di dashboard Dodo Anda.
* Untuk Pendekatan B dan C: **backend atau serverless endpoint** kecil untuk membuat checkout sessions.

<Note>
  GHL memerlukan **connected domain** untuk *publish* funnel. Saat melakukan pembuatan, gunakan **Preview** funnel untuk menguji. Perhatikan bahwa custom JavaScript (Pendekatan B dan C) umumnya hanya berjalan di **published page pada domain sungguhan**, bukan di Preview.
</Note>

## Fulfillment dengan webhooks (semua pendekatan)

Ini adalah lapisan automation. Siapkan sekali dan fitur ini akan berfungsi terlepas dari pendekatan checkout yang Anda pilih.

<Steps>
  <Step title="Create the workflow">
    Di **sub-account** GHL Anda, buka **Automation** di menu sebelah kiri (ini akan membuka tab **Workflows**). Klik **Create workflow**, lalu pilih **Start from Scratch**.
  </Step>

  <Step title="Add the Inbound Webhook trigger">
    Di builder, klik **Add new trigger**. Di panel **Add trigger**, cari **webhook** dan pilih **Inbound webhook** (tercantum di bawah **Triggers → Events**). Salin **Webhook URL** yang dibuat.
  </Step>

  <Step title="Register the webhook in Dodo">
    Di dashboard Dodo, buka **Settings → Webhooks**, tambahkan endpoint baru, lalu tempel GHL Inbound Webhook URL. Lakukan test purchase agar GHL menangkap sample payload dan Anda dapat memetakan field (customer email, product, amount, status).
  </Step>

  <Step title="Add fulfillment actions">
    Kembali ke workflow GHL, tambahkan actions berdasarkan event, seperti **find/create contact by email**, **add a tag**, **grant course/membership access**, dan **send a confirmation email**. Kemudian **Publish** workflow tersebut.
  </Step>
</Steps>

<Warning>
  Payment diproses di Dodo, sehingga **tidak** akan muncul di tab Payments GHL. Rekonsiliasikan payment tersebut ke GHL menggunakan workflow webhook di atas, dan jadikan **webhook sebagai source of truth** untuk memberikan access, bukan browser redirect, karena customer dapat menutup tab sebelum kembali.
</Warning>

## Pendekatan A: Payment Links (no-code)

Tambahkan Dodo payment link ke tombol GHL, funnel CTA, tombol order page, email, atau SMS mana pun.

<Steps>
  <Step title="Create a product and copy its payment link">
    Di dashboard Dodo, buka **Products → Add Product**, tetapkan **name** dan **price**, pilih **one-time** atau **subscription**, lalu klik **Save**. Buka product tersebut dan salin **Payment Link** (format: `https://checkout.dodopayments.com/buy/{product_id}`).
  </Step>

  <Step title="Add the link to your GHL button">
    Edit funnel atau halaman website Anda, pilih **Buy / Checkout button**, atur action-nya ke **Open URL / Website**, lalu tempel Dodo payment link Anda.
  </Step>

  <Step title="Set a success page (optional)">
    Atur **return URL** product di Dodo ke halaman terima kasih GHL agar customer kembali ke funnel setelah melakukan payment.
  </Step>
</Steps>

<Tip>
  Anda dapat melakukan prefill dan mengunci detail customer, atau menambahkan tracking, menggunakan [payment-link query parameters](/features/checkout). Ini berguna untuk meneruskan funnel atau offer ID sebagai metadata yang dapat Anda baca kembali dari webhook.
</Tip>

## Pendekatan B: Overlay Checkout (custom code)

Membuka Dodo checkout sebagai **modal overlay** di halaman GHL menggunakan [Checkout SDK](/developer-resources/overlay-checkout) melalui CDN. Memerlukan backend untuk membuat [checkout session](/api-reference/checkout-sessions/create) dan mengembalikan `checkoutUrl`.

<Steps>
  <Step title="Create a backend endpoint that calls the Checkout Sessions API">
    Langkah ini **wajib dilakukan**. SDK memerlukan `checkoutUrl` yang aktif, dan pembuatannya memerlukan **secret API key** Anda. GHL hanya meng-host static pages dan tidak dapat menjalankan server-side call ini untuk Anda. Anda juga tidak boleh memanggil [Create Checkout Session API](/api-reference/checkout-sessions/create) langsung dari browser, karena secret key Anda akan terekspos di source halaman. Jadi, overlay dan inline checkout **tidak dapat berfungsi hanya dengan GHL**: Anda memerlukan backend yang Anda kendalikan untuk membuat session dan hanya mengembalikan URL.

    Backend kecil apa pun dapat digunakan: serverless function (Cloudflare Workers, Vercel Functions, AWS Lambda, Supabase Edge Functions, dan sejenisnya), atau endpoint di server yang sudah Anda jalankan. Logikanya sama di mana pun: menerima request, memanggil API Dodo dengan secret key Anda, lalu mengembalikan `checkout_url`.

    Contoh logic handler (sesuaikan dengan platform pilihan Anda):

    ```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 };
    }
    ```

    Simpan Dodo API key Anda sebagai secret di platform tempat Anda melakukan deployment (jangan pernah commit ke code), izinkan request dari domain GHL Anda (CORS), dan tempatkan endpoint di bawah domain yang Anda kendalikan, misalnya `https://api.example.com/create-checkout`. Beralihlah ke `https://live.dodopayments.com/checkouts` setelah Anda berpindah ke live mode.
  </Step>

  <Step title="Add a Custom Code element in the GHL page builder">
    Buka funnel step atau halaman website Anda di GHL page builder, lalu:

    1. Klik ikon **+** di kiri atas builder untuk membuka **Quick Add**.
    2. Pilih **Elements** dari daftar kategori di sebelah kiri.
    3. Temukan **Custom Code** (juga ditampilkan sebagai HTML) dan seret ke halaman.
    4. Tempel kode di bawah ini ke code editor element tersebut, lalu simpan.

    ```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">
    Custom JS berjalan di halaman **published** (connected domain), tidak selalu di Preview. Lakukan publish, lalu klik **Pay Now** untuk memastikan overlay terbuka.
  </Step>
</Steps>

## Pendekatan C: Inline (embedded) Checkout

Menyematkan form checkout **di dalam** halaman GHL Anda (tanpa redirect dan tanpa popup) menggunakan SDK yang sama dengan mount container. Seperti Pendekatan B, pendekatan ini memerlukan backend untuk membuat session.

<Steps>
  <Step title="Create a backend endpoint that calls the Checkout Sessions API">
    Persyaratannya sama seperti overlay dan juga **wajib dilakukan**: pembuatan session memerlukan secret API key Anda, sehingga harus dilakukan server-side. GHL tidak dapat melakukannya sendiri. Gunakan kembali backend endpoint yang dijelaskan di bagian **Overlay Checkout** di atas (serverless function kecil atau server apa pun yang Anda kendalikan) yang memanggil [Create Checkout Session API](/api-reference/checkout-sessions/create) dan mengembalikan `{ checkoutUrl }`.
  </Step>

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

    1. Klik ikon **+** di kiri atas builder untuk membuka **Quick Add**.
    2. Pilih **Elements** dari daftar kategori di sebelah kiri.
    3. Temukan **Custom Code** (juga ditampilkan sebagai HTML) dan seret ke halaman tempat form checkout ingin ditampilkan.
    4. Tempel kode di bawah ini ke code editor element tersebut, lalu simpan.

    ```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)">
    Untuk Apple Pay pada inline checkout, [verifikasi domain Anda](/features/payment-methods/digital-wallets#apple-pay). Host association file dan daftarkan domain tersebut di dashboard.
  </Step>
</Steps>

<Warning>
  Inline adalah opsi yang paling kompleks di GHL. Pendekatan ini memerlukan custom code, backend, published page pada domain sungguhan, dan (untuk Apple Pay) verifikasi domain. Jika Anda tidak memerlukan form yang sepenuhnya tersemat, pilih Pendekatan A atau B.
</Warning>

## Event yang Perlu Ditangani

| Dodo event                                        | Kapan terjadi              | GHL action yang disarankan                                      |
| ------------------------------------------------- | -------------------------- | --------------------------------------------------------------- |
| `payment.succeeded`                               | Payment berhasil ditangkap | Tandai contact sebagai paid, berikan access, kirim confirmation |
| `subscription.active`                             | Subscription diaktifkan    | Berikan membership, mulai onboarding workflow                   |
| `subscription.renewed`                            | Renewal payment dilakukan  | Perpanjang access untuk cycle berikutnya                        |
| `subscription.on_hold`                            | Renewal gagal              | Picu dunning atau reminder workflow                             |
| `subscription.cancelled` / `subscription.expired` | Subscription berakhir      | Hapus access, tambahkan tag churned                             |

Setiap webhook menyertakan **customer email**. Gunakan action **find/create contact by email** milik GHL untuk mengaitkan payment dengan contact yang tepat. Untuk daftar lengkap, lihat [Webhook Event Guide](/developer-resources/webhooks/intents/webhook-events-guide).

## Pengujian & Go Live

<Steps>
  <Step title="Test in test mode">
    Biarkan Dodo dalam **Test Mode**, gunakan test card `4242 4242 4242 4242` (expiry apa pun di masa mendatang dan CVC apa pun), selesaikan purchase, lalu pastikan workflow GHL berjalan dan menerapkan tag atau access.
  </Step>

  <Step title="Go live">
    Alihkan Dodo ke **Live Mode** dan perbarui live-mode webhook endpoint. Perubahan lainnya bergantung pada pendekatan Anda:

    * **Payment Links (A):** ganti dengan payment link **live** milik product.
    * **Overlay checkout (B):** arahkan backend Anda ke `https://live.dodopayments.com/checkouts` dengan **live** API key, dan atur `mode` milik SDK ke `"live"` dalam pemanggilan `Initialize`.
    * **Inline checkout (C):** sama seperti overlay, karena menggunakan backend endpoint dan inisialisasi SDK yang sama.

    Kemudian lakukan satu purchase end-to-end sungguhan untuk memastikan semuanya berjalan.
  </Step>
</Steps>

## Tips

<Tip>
  Jadikan **webhook sebagai source of truth** untuk memberikan access. Tindak lanjuti `payment.succeeded` / `subscription.active`, bukan browser redirect.
</Tip>

<Tip>
  Verifikasi authenticity webhook menggunakan header `webhook-signature` ([Standard Webhooks](/developer-resources/webhooks)), agar hanya event Dodo yang asli yang memicu fulfillment di GHL.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Payment succeeded but nothing happened in GHL">
    Periksa apakah Dodo webhook endpoint mengarah ke GHL Inbound Webhook URL yang benar, workflow sudah **published**, dan trigger telah menangkap sample payload sehingga field mapping tersedia.
  </Accordion>

  <Accordion title="Overlay or inline button does nothing">
    Custom JS biasanya hanya berjalan di **published page (real domain)**, bukan di Preview. Pastikan halaman sudah dipublish, SDK `<script>` telah dimuat, dan `checkoutUrl` adalah session URL valid dari backend Anda.
  </Accordion>

  <Accordion title="Contact not created or not matched">
    Pastikan workflow Anda menggunakan **find/create contact by email** dan email field dipetakan dari webhook payload.
  </Accordion>

  <Accordion title="Payment isn't showing in GHL's Payments tab">
    Ini adalah hal yang wajar. Payment diproses di Dodo, jadi rekonsiliasikan ke GHL menggunakan webhook workflow.
  </Accordion>
</AccordionGroup>
