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

> Tích hợp Dodo Payments với GoHighLevel (GHL) bằng payment links không cần code, overlay checkout hoặc inline checkout, đồng thời tự động hóa việc hoàn tất đơn hàng bằng webhooks.

## Giới thiệu

Kết nối Dodo Payments với [GoHighLevel](https://www.gohighlevel.com/) (GHL) để bán hàng từ funnel, website, email và SMS của GHL, đồng thời xử lý đơn hàng bằng tính năng tự động hóa của GHL. GHL là một nền tảng CRM và marketing với funnel, website, email và SMS, cùng tính năng tự động hóa (**Workflows**). GHL không liệt kê Dodo Payments là payment processor tích hợp sẵn, vì vậy bạn cần kết nối hai nền tảng theo một trong ba cách. Hãy chọn cách phù hợp dựa trên mức độ tích hợp checkout mong muốn và khả năng viết code của bạn.

Mọi phương thức đều xử lý fulfillment theo cùng một cách: Dodo Payments gửi [webhook events](/developer-resources/webhooks) đến workflow **Inbound Webhook** của GHL. Workflow này gắn tag cho contact, cấp quyền truy cập và gửi email xác nhận.

## Chọn phương thức

Ba phương thức khác nhau về lượng code cần viết và nơi khách hàng thực hiện thanh toán:

| Phương thức | Code cần thiết | Trải nghiệm checkout | Phù hợp nhất với |
| - | - | - | - |
| **A. Payment Links** | Không có (no-code) | Khách hàng được chuyển đến checkout do Dodo Payments host | Hầu hết người dùng GHL, triển khai nhanh nhất |
| **B. Overlay Checkout** | Code tùy chỉnh và backend | Một modal mở phía trên trang GHL | Các đội ngũ muốn checkout nằm trên trang mà không rời khỏi funnel |
| **C. Inline Checkout** | Code tùy chỉnh và backend | Form checkout được nhúng vào trang | Checkout được nhúng hoàn toàn, có branding riêng |

<Info>
  Nếu bạn mới sử dụng Dodo Payments, hãy bắt đầu với **Phương thức A (Payment Links)**. Phương thức này không cần code và phù hợp với mọi người dùng GHL. Phương thức B và C cần backend để tạo [checkout sessions](/api-reference/checkout-sessions/create), vì vậy phù hợp với các đội ngũ có khả năng làm việc với code.
</Info>

## Điều kiện tiên quyết

Trước khi bắt đầu, bạn cần:

* Một tài khoản Dodo Payments có ít nhất một **product**.
* Một tài khoản GoHighLevel có funnel, website hoặc workflow.
* Quyền truy cập **Developer → Webhooks** trong dashboard Dodo Payments và **Developer → API Keys** nếu bạn cần API key.
* Đối với Phương thức B và C: một **backend hoặc serverless endpoint** nhỏ để tạo checkout sessions.

<Note>
  GHL yêu cầu một **connected domain** để *publish* funnel. Trong khi xây dựng, hãy dùng **Preview** của funnel để kiểm thử. Custom JavaScript (Phương thức B và C) thường chỉ chạy trên **published page trên domain thực**, không chạy trong Preview.
</Note>

## Fulfillment với Webhooks (Tất cả phương thức)

Workflow webhook là lớp tự động hóa. Bạn chỉ cần thiết lập một lần, sau đó có thể dùng với mọi phương thức checkout.

<Steps>
  <Step title="Create the Workflow">
    Trong **sub-account** GHL, mở **Automation** ở menu bên trái. Tab **Workflows** sẽ được mở. Nhấp vào **Create workflow**, sau đó chọn **Start from Scratch**.
  </Step>

  <Step title="Add the Inbound Webhook Trigger">
    Trong builder, nhấp vào **Add new trigger**. Trong bảng **Add trigger**, tìm kiếm **webhook** và chọn **Inbound webhook**, nằm trong **Triggers → Events**. Sao chép **Webhook URL** được tạo.
  </Step>

  <Step title="Register the Webhook in Dodo Payments">
    Trong dashboard Dodo Payments, đi đến **Developer → Webhooks** và nhấp vào **Add endpoint**. Dán URL GHL Inbound Webhook vào **Endpoint URL** rồi nhấp vào **Create endpoint**. Sau đó cung cấp cho GHL một sample payload để ánh xạ các field, chẳng hạn như email khách hàng, product, amount và status. Bạn có thể thực hiện một giao dịch thử nghiệm hoặc mở tab **Testing** của endpoint, chọn event type rồi nhấp vào **Send example**.
  </Step>

  <Step title="Add Fulfillment Actions">
    Trong workflow GHL, thêm các action cho event, chẳng hạn như **find/create contact by email**, **add a tag**, **grant course/membership access** và **send a confirmation email**. Sau đó **Publish** workflow.
  </Step>
</Steps>

<Warning>
  Dodo Payments xử lý các khoản thanh toán, vì vậy chúng **không** xuất hiện trong tab **Payments** của GHL. Hãy ghi nhận chúng trong GHL bằng workflow webhook ở trên. Cấp quyền truy cập từ **webhook**, không phải từ browser redirect, vì khách hàng có thể đóng tab trước khi redirect hoàn tất.
</Warning>

## Phương thức A: Payment Links (No-Code)

Thêm payment link của Dodo Payments vào bất kỳ nút GHL, call to action trong funnel, nút trên trang order, email hoặc SMS nào. Khách hàng thanh toán trên checkout do Dodo Payments host. Để xem checkout hỗ trợ những gì, hãy tham khảo [Checkout Features](/features/checkout).

<Steps>
  <Step title="Create a Product and Copy Its Payment Link">
    Trong dashboard Dodo Payments, đi đến **Products** và nhấp vào **Add Product**. Thiết lập **name** và **price**, chọn **one-time** hoặc **subscription**, rồi lưu product. Trong hàng của product, nhấp vào **Share**, sau đó nhấp vào **Copy payment link**. Link có định dạng `https://checkout.dodopayments.com/buy/{product_id}`.
  </Step>

  <Step title="Add the Link to Your GHL Button">
    Chỉnh sửa funnel hoặc trang website rồi chọn **Buy / Checkout button**. Đặt action thành **Open URL / Website** và dán payment link của bạn.
  </Step>

  <Step title="Set a Success Page (Optional)">
    Để đưa khách hàng trở lại funnel sau khi thanh toán, nhập trang cảm ơn GHL của bạn vào **Redirect URL** trong bảng **Share** của product trước khi sao chép link. Khi đó, link sẽ chứa trang này dưới dạng parameter `redirect_url`.
  </Step>
</Steps>

<Tip>
  Query parameter của payment link có thể điền sẵn và khóa thông tin khách hàng hoặc thêm tracking. Ví dụ: truyền ID của funnel hoặc offer dưới dạng parameter `metadata_*` rồi đọc lại parameter này từ webhook. Xem [Static Payment Links](/developer-resources/integration-guide#static-payment-links) để biết tất cả parameter.
</Tip>

## Phương thức B: Overlay Checkout (Custom Code)

Phương thức B mở checkout Dodo Payments dưới dạng **modal overlay** trên trang GHL của bạn, sử dụng [Checkout SDK](/developer-resources/overlay-checkout) từ CDN. Phương thức này cần backend để tạo [checkout session](/api-reference/checkout-sessions/create) và trả về `checkoutUrl`.

<Steps>
  <Step title="Create a Backend Endpoint That Calls the Checkout Sessions API">
    Bước này **bắt buộc**. SDK cần URL của checkout session, trong khi việc tạo session yêu cầu **secret API key** của bạn. GHL chỉ host các trang và không thể thực hiện server-side call này thay bạn. Không bao giờ gọi [Create Checkout Session API](/api-reference/checkout-sessions/create) từ browser, vì điều đó sẽ làm lộ secret key trong source của trang. Vì vậy, overlay và inline checkout **không thể hoạt động chỉ với GHL**: bạn cần một backend do mình kiểm soát để tạo session và chỉ trả về URL.

    Bất kỳ backend nhỏ nào cũng có thể dùng: serverless function (Cloudflare Workers, Vercel Functions, AWS Lambda, Supabase Edge Functions và các nền tảng tương tự) hoặc endpoint trên server bạn đã vận hành. Logic trên mọi nền tảng đều giống nhau: nhận request, gọi Dodo Payments API bằng secret key của bạn và trả về `checkout_url`.

    Ví dụ về logic của handler, bạn có thể điều chỉnh cho phù hợp với nền tảng của mình:

    ```js theme={null}
    async function createCheckout(env) {
      const res = await fetch("https://test.dodopayments.com/checkouts", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${env.DODO_PAYMENTS_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 };
    }
    ```

    Lưu API key dưới dạng secret trong environment variable `DODO_PAYMENTS_API_KEY` trên nền tảng bạn deploy và không bao giờ commit key vào code. Cho phép request từ domain GHL của bạn (CORS) và cung cấp endpoint từ domain do bạn kiểm soát, chẳng hạn như `https://api.example.com/create-checkout`. Khi chuyển sang live mode, đổi URL thành `https://live.dodopayments.com/checkouts`.
  </Step>

  <Step title="Add a Custom Code Element in the GHL Page Builder">
    Mở funnel step hoặc trang website trong GHL page builder, sau đó:

    1. Nhấp vào biểu tượng **+** ở góc trên bên trái của builder để mở **Quick Add**.
    2. Chọn **Elements** từ danh sách category ở bên trái.
    3. Tìm **Custom Code** (cũng hiển thị dưới dạng HTML) và kéo vào trang.
    4. Dán code bên dưới vào code editor của element rồi lưu.

    ```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 JavaScript chạy trên trang **published** thuộc connected domain của bạn và có thể không chạy trong Preview. Publish trang, sau đó nhấp vào **Pay Now** để xác nhận overlay mở thành công.
  </Step>
</Steps>

## Phương thức C: Inline (Embedded) Checkout

Phương thức C nhúng form checkout **bên trong** trang GHL của bạn, không redirect và không popup. Phương thức này sử dụng cùng SDK với một container element để mount. Giống Phương thức B, phương thức này cần backend để tạo session.

<Steps>
  <Step title="Create a Backend Endpoint That Calls the Checkout Sessions API">
    Bước này **bắt buộc**, giống như với overlay checkout. Việc tạo session cần secret API key, nên phải được thực hiện trên server và GHL không thể tự thực hiện. Tái sử dụng backend endpoint từ phần **Overlay Checkout** ở trên: bất kỳ serverless function hoặc server nhỏ nào do bạn kiểm soát, có thể gọi [Create Checkout Session API](/api-reference/checkout-sessions/create) và trả về `{ checkoutUrl }`.
  </Step>

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

    1. Nhấp vào biểu tượng **+** ở góc trên bên trái của builder để mở **Quick Add**.
    2. Chọn **Elements** từ danh sách category ở bên trái.
    3. Tìm **Custom Code** (cũng hiển thị dưới dạng HTML) và kéo vào trang tại vị trí bạn muốn hiển thị form checkout.
    4. Dán code bên dưới vào code editor của element rồi lưu.

    ```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)">
    Để cung cấp Apple Pay trong inline checkout, [hãy xác minh miền của bạn](/features/payment-methods/digital-wallets#apple-pay). Trong dashboard Dodo Payments, đi đến **Settings → Payment Methods** và nhấp vào **Manage domains** trên dòng **Apple Pay**. Tải xuống tệp liên kết miền, lưu trữ tệp trên miền của bạn và đăng ký miền. Apple Pay không khả dụng trong overlay checkout (Approach B).

    Miền do GHL lưu trữ không thể lưu trữ tệp liên kết miền. Apple Pay trong inline checkout cần một miền do bạn kiểm soát và có thể cung cấp `/.well-known/apple-developer-merchantid-domain-association`. Trên các trang do GHL lưu trữ, hãy sử dụng hosted checkout từ Payment Links (Approach A) hoặc bỏ qua Apple Pay.
  </Step>
</Steps>

<Warning>
  Inline checkout là tùy chọn phức tạp nhất trong GHL. Tùy chọn này cần custom code, backend, một trang đã xuất bản trên miền thực và, đối với Apple Pay, cần xác minh miền. Nếu bạn không cần một biểu mẫu được nhúng hoàn toàn, hãy sử dụng Approach A hoặc B.
</Warning>

## Các sự kiện cần xử lý

Đăng ký endpoint GHL với các sự kiện mà workflow của bạn xử lý. Bảng dưới đây đề xuất một hành động GHL cho từng sự kiện:

| Sự kiện Dodo Payments | Thời điểm kích hoạt | Hành động GHL đề xuất |
| - | - | - |
| `payment.succeeded` | Một khoản thanh toán thành công | Gắn tag đã thanh toán cho contact, cấp quyền truy cập, gửi xác nhận |
| `subscription.active` | Một subscription được kích hoạt | Cấp quyền thành viên, bắt đầu workflow onboarding |
| `subscription.renewed` | Một subscription gia hạn cho kỳ thanh toán tiếp theo | Gia hạn quyền truy cập cho chu kỳ tiếp theo |
| `subscription.past_due` | Gia hạn không thành công và thời gian gia hạn bắt đầu. Khách hàng vẫn giữ quyền truy cập cho đến hạn chót | Bắt đầu workflow thu hồi công nợ hoặc nhắc nhở trong khi khách hàng vẫn còn quyền truy cập |
| `subscription.on_hold` | Subscription bị tạm dừng sau khi gia hạn không thành công | Tạm dừng quyền truy cập, nâng cấp mức độ của chuỗi nhắc nhở |
| `subscription.cancelled` / `subscription.expired` | Subscription kết thúc | Xóa quyền truy cập, gắn tag đã rời bỏ |

Các sự kiện thanh toán và subscription bao gồm **customer email** trong `data.customer.email`. Sử dụng hành động **find/create contact by email** của GHL để đối chiếu khoản thanh toán với contact phù hợp. Để xem mọi sự kiện, hãy tham khảo [Webhook Event Guide](/developer-resources/webhooks/intents/webhook-events-guide).

## Kiểm thử & đưa vào vận hành

<Steps>
  <Step title="Test in Test Mode">
    Tắt công tắc **Live Mode** trong thanh bên Dodo Payments để làm việc ở test mode. Hoàn tất một giao dịch mua bằng thẻ kiểm thử `4242 4242 4242 4242` (ngày hết hạn `06/32`, CVV `123`), rồi xác nhận rằng workflow GHL chạy và áp dụng tag hoặc quyền truy cập.
  </Step>

  <Step title="Go Live">
    Bật công tắc **Live Mode** và thêm GHL Inbound Webhook URL làm endpoint trong live mode. Những thay đổi khác phụ thuộc vào approach của bạn:

    * **Payment Links (A):** Thay thế liên kết bằng payment link **live** của sản phẩm.
    * **Overlay checkout (B):** Trỏ backend của bạn đến `https://live.dodopayments.com/checkouts` bằng API key **live** và đặt `mode` thành `"live"` trong lệnh gọi `Initialize` của SDK.
    * **Inline checkout (C):** Thực hiện các thay đổi giống như đối với overlay checkout vì tùy chọn này sử dụng cùng endpoint backend và quá trình khởi tạo SDK.

    Sau đó, thực hiện một giao dịch mua thực tế từ đầu đến cuối để xác nhận thiết lập.
  </Step>
</Steps>

## Mẹo

<Tip>
  Hãy coi **webhook là nguồn dữ liệu chuẩn** để cấp quyền truy cập. Hãy xử lý `payment.succeeded` hoặc `subscription.active`, không xử lý dựa trên chuyển hướng của trình duyệt.
</Tip>

<Tip>
  GHL Inbound Webhook không thể xác minh header `webhook-signature`. Vì vậy, để chỉ các sự kiện Dodo Payments chính thức kích hoạt fulfillment trong GHL, hãy trỏ endpoint webhook Dodo Payments đến backend riêng của bạn, xác minh từng sự kiện tại đó ([Webhooks](/developer-resources/webhooks)), rồi chuyển tiếp sự kiện đến GHL Inbound Webhook URL.
</Tip>

## Khắc phục sự cố

<AccordionGroup>
  <Accordion title="Payment succeeded but nothing happened in GHL">
    Kiểm tra để đảm bảo endpoint webhook Dodo Payments trỏ đến đúng GHL Inbound Webhook URL, workflow đã được **xuất bản** và trigger đã thu thập payload mẫu để tạo field mapping.
  </Accordion>

  <Accordion title="Overlay or inline button does nothing">
    Custom JavaScript thường chỉ chạy trên **trang đã xuất bản trên miền thực**, không chạy trong Preview. Xác nhận rằng trang đã được xuất bản, SDK `<script>` đã được tải và `checkoutUrl` là session URL hợp lệ từ backend của bạn.
  </Accordion>

  <Accordion title="Contact not created or not matched">
    Kiểm tra để đảm bảo workflow của bạn sử dụng **find/create contact by email** và field email được ánh xạ từ webhook payload.
  </Accordion>

  <Accordion title="Payment isn't showing in GHL's Payments tab">
    Điều này là bình thường. Dodo Payments xử lý các khoản thanh toán, vì vậy hãy ghi lại chúng trong GHL bằng workflow webhook.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.