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

# Nuxt Adaptor

> Integrasikan Dodo Payments dengan proyek Nuxt Anda menggunakan modul Nuxt resmi. Mencakup checkout, portal pelanggan, webhook, dan pengaturan lingkungan yang aman.

<CardGroup cols={2}>
  <Card title="Checkout API Route" icon="cart-shopping" href="#checkout-api-route">
    Integrasikan Dodo Payments checkout ke dalam aplikasi Nuxt Anda menggunakan routing server.
  </Card>

  <Card title="Customer Portal API Route" icon="user" href="#customer-portal-api-route">
    Biarkan pelanggan mengelola langganan dan detail melalui routing server Nuxt.
  </Card>

  <Card title="Webhooks API Route" icon="bell" href="#webhook-api-route">
    Terima dan proses event webhook Dodo Payments dengan aman di Nuxt.
  </Card>
</CardGroup>

## Ikhtisar

<Info>
  Panduan ini menjelaskan cara mengintegrasikan Dodo Payments ke aplikasi Nuxt Anda menggunakan modul resmi Nuxt. Anda akan mempelajari cara mengatur checkout, portal pelanggan, dan rute API webhook, serta cara mengelola variabel lingkungan dengan aman.
</Info>

## Instalasi

<Steps>
  <Step title="Install the Nuxt module">
    Jalankan perintah berikut di root proyek Anda:

    ```bash theme={null}
    npm install @dodopayments/nuxt
    ```
  </Step>

  <Step title="Register the module in nuxt.config.ts">
    Tambahkan <code>@dodopayments/nuxt</code> ke array <code>modules</code> Anda dan konfigurasikan:

    ```typescript nuxt.config.ts expandable theme={null}
    export default defineNuxtConfig({
      modules: ["@dodopayments/nuxt"],
      devtools: { enabled: true },
      compatibilityDate: "2025-02-25",
      runtimeConfig: {
        private: {
          bearerToken: process.env.NUXT_PRIVATE_BEARER_TOKEN,
          webhookKey: process.env.NUXT_PRIVATE_WEBHOOK_KEY,
          environment: process.env.NUXT_PRIVATE_ENVIRONMENT,
          returnUrl: process.env.NUXT_PRIVATE_RETURNURL
        },
      }
    });
    ```
  </Step>
</Steps>

<Warning>
  Jangan pernah meng-commit file <code>.env</code> atau rahasia Anda ke sistem kontrol versi.
</Warning>

## Contoh Penangan Rute API

<Info>
  Semua integrasi Dodo Payments di Nuxt ditangani melalui rute server di direktori <code>server/routes/api/</code>.
</Info>

<Tabs>
  <Tab title="Checkout API Route">
    <Info>
      Gunakan handler ini untuk mengintegrasikan checkout Dodo Payments ke aplikasi Nuxt Anda. Mendukung aliran pembayaran statis (GET), dinamis (POST), dan sesi (POST).
    </Info>

    <CodeGroup>
      ```typescript server/routes/api/checkout.get.ts expandable theme={null}

      export default defineEventHandler((event) => {
        const {
          private: { bearerToken, environment, returnUrl },
        } = useRuntimeConfig();

        const handler = checkoutHandler({
          bearerToken: bearerToken,
          environment: environment,
          returnUrl: returnUrl,
        });

        return handler(event);
      });
      ```
    </CodeGroup>

    <CodeGroup>
      ```typescript server/routes/api/checkout.post.ts expandable theme={null}

      export default defineEventHandler((event) => {
        const {
          private: { bearerToken, environment, returnUrl },
        } = useRuntimeConfig();

        const handler = checkoutHandler({
          bearerToken: bearerToken,
          environment: environment,
          returnUrl: returnUrl,
          type: "dynamic"
        });

        return handler(event);
      });
      ```
    </CodeGroup>

    <CodeGroup>
      ```typescript server/routes/api/checkout.post.ts (Checkout Sessions) expandable theme={null}

      export default defineEventHandler((event) => {
        const {
          private: { bearerToken, environment, returnUrl },
        } = useRuntimeConfig();

        const handler = checkoutHandler({
          bearerToken: bearerToken,
          environment: environment,
          returnUrl: returnUrl,
          type: "session"
        });

        return handler(event);
      });
      ```
    </CodeGroup>

    <Warning>
      Jika <code>productId</code> hilang atau tidak valid, handler mengembalikan respons 400.
    </Warning>

    <CodeGroup>
      ```curl Static Checkout Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/checkout?productId=pdt_fqJhl7pxKWiLhwQR042rh' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Dynamic Checkout Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "billing": {
        "city": "Texas",
        "country": "US",
        "state": "Texas",
        "street": "56, hhh",
        "zipcode": "560000"
      },
      "customer": {
        "email": "test@example.com",
        	"name": "test"
      },
      "metadata": {},
      "payment_link": true,
        "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
        "quantity": 1,
        "billing_currency": "USD",
        "discount_codes": ["IKHZ23M9GQ"],
        "return_url": "https://example.com",
        "trial_period_days": 10
      }'
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Checkout Session Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "product_cart": [
        {
          "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
          "quantity": 1
        }
      ],
      "customer": {
        "email": "test@example.com",
        "name": "test"
      },
      "return_url": "https://example.com/success"
      }'
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Customer Portal API Route">
    <Info>
      Buat rute GET untuk memungkinkan pelanggan mengakses portal mereka. Menerima <code>customer\_id</code> sebagai parameter kueri.
    </Info>

    <CodeGroup>
      ```typescript server/routes/api/customer-portal.get.ts expandable theme={null}

      export default defineEventHandler((event) => {
        const {
          private: { bearerToken, environment },
        } = useRuntimeConfig();

        const handler = customerPortalHandler({
          bearerToken,
          environment: environment,
        });

        return handler(event);
      });
      ```
    </CodeGroup>

    **Parameter Kueri:**

    * <code>customer\_id</code> (wajib): ID pelanggan untuk sesi portal (misalnya, <code>?customer\_id=cus\_123</code>)
    * <code>send\_email</code> (opsional, boolean): Jika <code>true</code>, mengirim email kepada pelanggan dengan tautan portal.

    <Warning>
      Mengembalikan 400 jika <code>customer\_id</code> hilang.
    </Warning>

    <CodeGroup>
      ```curl Customer Portal Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/customer-portal?customer_id=cus_9VuW4K7O3GHwasENg31m&send_email=true' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Webhook API Route">
    <Info>
      Buat rute POST untuk menerima dan memproses event webhook dari Dodo Payments secara aman.
    </Info>

    <CodeGroup>
      ```typescript server/routes/api/webhook.post.ts expandable theme={null}

      export default defineEventHandler((event) => {
        const {
          private: { webhookKey },
        } = useRuntimeConfig();

        const handler = Webhooks({
          webhookKey: webhookKey,
          onPayload: async (payload: any) => {
            // Handle webhook payload here
          },
          // ...add other event handlers as needed
        });

        return handler(event);
      });
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Penangan Rute Checkout

<Info>
  Dodo Payments mendukung tiga jenis aliran pembayaran untuk mengintegrasikan pembayaran ke situs web Anda, adaptor ini mendukung semua jenis aliran pembayaran.
</Info>

* **Tautan Pembayaran Statis:** URL yang dapat dibagikan secara instan untuk pengumpulan pembayaran cepat tanpa kode.
* **Tautan Pembayaran Dinamis:** Menghasilkan tautan pembayaran secara programatis dengan detail kustom menggunakan API atau SDK.
* **Sesi Checkout:** Membuat pengalaman checkout yang aman dan dapat disesuaikan dengan keranjang produk dan detail pelanggan yang telah dikonfigurasi sebelumnya.

<AccordionGroup>
  <Accordion title="Static Checkout (GET)">
    ### Supported Query Parameters

    <ParamField query="productId" type="string" required>
      Identifikasi produk (misalnya, <code>?productId=pdt\_nZuwz45WAs64n3l07zpQR</code>).
    </ParamField>

    <ParamField query="quantity" type="integer">
      Jumlah produk.
    </ParamField>

    <ParamField query="fullName" type="string">
      Nama lengkap pelanggan.
    </ParamField>

    <ParamField query="firstName" type="string">
      Nama depan pelanggan.
    </ParamField>

    <ParamField query="lastName" type="string">
      Nama belakang pelanggan.
    </ParamField>

    <ParamField query="email" type="string">
      Alamat email pelanggan.
    </ParamField>

    <ParamField query="country" type="string">
      Negara pelanggan.
    </ParamField>

    <ParamField query="addressLine" type="string">
      Alamat pelanggan.
    </ParamField>

    <ParamField query="city" type="string">
      Kota pelanggan.
    </ParamField>

    <ParamField query="state" type="string">
      Negara bagian/provinsi pelanggan.
    </ParamField>

    <ParamField query="zipCode" type="string">
      Kode pos pelanggan.
    </ParamField>

    <ParamField query="disableFullName" type="boolean">
      Nonaktifkan kolom nama lengkap.
    </ParamField>

    <ParamField query="disableFirstName" type="boolean">
      Nonaktifkan kolom nama depan.
    </ParamField>

    <ParamField query="disableLastName" type="boolean">
      Nonaktifkan kolom nama belakang.
    </ParamField>

    <ParamField query="disableEmail" type="boolean">
      Nonaktifkan kolom email.
    </ParamField>

    <ParamField query="disableCountry" type="boolean">
      Nonaktifkan kolom negara.
    </ParamField>

    <ParamField query="disableAddressLine" type="boolean">
      Nonaktifkan kolom alamat.
    </ParamField>

    <ParamField query="disableCity" type="boolean">
      Nonaktifkan kolom kota.
    </ParamField>

    <ParamField query="disableState" type="boolean">
      Nonaktifkan kolom negara bagian.
    </ParamField>

    <ParamField query="disableZipCode" type="boolean">
      Nonaktifkan kolom kode pos.
    </ParamField>

    <ParamField query="paymentCurrency" type="string">
      Tentukan mata uang pembayaran (misalnya, <code>USD</code>).
    </ParamField>

    <ParamField query="showCurrencySelector" type="boolean">
      Tampilkan pemilih mata uang.
    </ParamField>

    <ParamField query="paymentAmount" type="integer">
      Tentukan jumlah pembayaran (misalnya, <code>1000</code> untuk \$10,00).
    </ParamField>

    <ParamField query="showDiscounts" type="boolean">
      Tampilkan kolom diskon.
    </ParamField>

    <ParamField query="metadata_*" type="string">
      Setiap parameter kueri yang dimulai dengan <code>metadata\_</code> akan diteruskan sebagai metadata.
    </ParamField>

    <Warning>
      Jika <code>productId</code> hilang, handler mengembalikan respons 400. Parameter kueri yang tidak valid juga menghasilkan respons 400.
    </Warning>

    ### Format Respons

    Checkout statis mengembalikan respons JSON dengan URL checkout:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Dynamic Checkout (POST)">
    * Kirim parameter sebagai badan JSON dalam permintaan POST.
    * Mendukung pembayaran satu kali dan berulang.
    * Untuk daftar lengkap bidang badan POST yang didukung, lihat:
      * [Request body for a One Time Payment Product](https://docs.dodopayments.com/api-reference/payments/post-payments)
      * [Request body for a Subscription Product](https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions)

    ### Format Respons

    Checkout dinamis mengembalikan respons JSON dengan URL checkout:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Checkout Sessions (POST)">
    Sesi checkout memberikan pengalaman checkout yang lebih aman dan dihosting, yang menangani seluruh alur pembayaran untuk pembelian satu kali dan langganan dengan kendali kustomisasi penuh.

    Lihat [Panduan Integrasi Sesi Checkout](https://docs.dodopayments.com/developer-resources/checkout-session) untuk detail lebih lanjut dan daftar lengkap bidang yang didukung.

    ### Format Respons

    Sesi checkout mengembalikan respons JSON dengan URL checkout:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/session/..."
    }
    ```
  </Accordion>
</AccordionGroup>

## Penangan Rute Portal Pelanggan

Penangan Rute Portal Pelanggan memungkinkan Anda untuk mengintegrasikan portal pelanggan Dodo Payments ke dalam aplikasi Nuxt Anda dengan mulus.

### Parameter Kuery

<ParamField query="customer_id" type="string" required>
  ID pelanggan untuk sesi portal (misalnya, <code>?customer\_id=cus\_123</code>).
</ParamField>

<ParamField query="send_email" type="boolean">
  Jika disetel ke <code>true</code>, mengirim email ke pelanggan dengan tautan portal.
</ParamField>

<Warning>
  Mengembalikan 400 jika <code>customer\_id</code> hilang.
</Warning>

## Penangan Rute Webhook

* **Metode:** Hanya permintaan POST yang didukung. Metode lain mengembalikan 405.
* **Verifikasi Tanda Tangan:** Memverifikasi tanda tangan webhook menggunakan <code>webhookKey</code>. Mengembalikan 401 jika verifikasi gagal.
* **Validasi Payload:** Divalidasi dengan Zod. Mengembalikan 400 untuk payload yang tidak valid.
* **Penanganan Kesalahan:**
  * 401: Tanda tangan tidak valid
  * 400: Payload tidak valid
  * 500: Kesalahan internal selama verifikasi
* **Rute Acara:** Memanggil penangan acara yang sesuai berdasarkan jenis payload.

### Penangan Event Webhook yang Didukung

<CodeGroup>
  ```typescript Typescript expandable theme={null}
  onPayload?: (payload: WebhookPayload) => Promise<void>;
  onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onPaymentFailed?: (payload: WebhookPayload) => Promise<void>;
  onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>;
  onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>;
  onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onRefundFailed?: (payload: WebhookPayload) => Promise<void>;
  onDisputeOpened?: (payload: WebhookPayload) => Promise<void>;
  onDisputeExpired?: (payload: WebhookPayload) => Promise<void>;
  onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>;
  onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>;
  onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>;
  onDisputeWon?: (payload: WebhookPayload) => Promise<void>;
  onDisputeLost?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionUpdated?: (payload: WebhookPayload) => Promise<void>;
  onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>;
  onAbandonedCheckoutDetected?: (payload: WebhookPayload) => Promise<void>;
  onAbandonedCheckoutRecovered?: (payload: WebhookPayload) => Promise<void>;
  onDunningStarted?: (payload: WebhookPayload) => Promise<void>;
  onDunningRecovered?: (payload: WebhookPayload) => Promise<void>;
  onCreditAdded?: (payload: WebhookPayload) => Promise<void>;
  onCreditDeducted?: (payload: WebhookPayload) => Promise<void>;
  onCreditExpired?: (payload: WebhookPayload) => Promise<void>;
  onCreditRolledOver?: (payload: WebhookPayload) => Promise<void>;
  onCreditRolloverForfeited?: (payload: WebhookPayload) => Promise<void>;
  onCreditOverageCharged?: (payload: WebhookPayload) => Promise<void>;
  onCreditManualAdjustment?: (payload: WebhookPayload) => Promise<void>;
  onCreditBalanceLow?: (payload: WebhookPayload) => Promise<void>;
  ```
</CodeGroup>

***

## Prompt untuk LLM

```
You are an expert Nuxt developer assistant. Your task is to guide a user through integrating the @dodopayments/nuxt module into their existing Nuxt project.

The @dodopayments/nuxt module provides API route handlers for Dodo Payments' Checkout, Customer Portal, and Webhook functionalities, designed for Nuxt 3 server routes.

First, install the necessary package:

npm install @dodopayments/nuxt

Second, add the configuration to nuxt.config.ts

export default defineNuxtConfig({
  modules: ["@dodopayments/nuxt"],
  devtools: { enabled: true },
  compatibilityDate: "2025-02-25",
  runtimeConfig: {
    private: {
      bearerToken: process.env.NUXT_PRIVATE_BEARER_TOKEN,
      webhookKey: process.env.NUXT_PRIVATE_BEARER_TOKEN,
      environment: process.env.NUXT_PRIVATE_ENVIRONMENT,
      returnUrl: process.env.NUXT_PRIVATE_RETURNURL
    },
  }
});

Here's how you should structure your response:

    Ask the user which functionalities they want to integrate.

"Which parts of the @dodopayments/nuxt module would you like to integrate into your project? You can choose one or more of the following:

    Checkout API Route (for handling product checkouts)
    Customer Portal API Route (for managing customer subscriptions/details)
    Webhook API Route (for receiving Dodo Payments webhook events)
    All (integrate all three)"

    Based on the user's selection, provide detailed integration steps for each chosen functionality.

If Checkout API Route is selected:

Purpose: This route redirects users to the Dodo Payments checkout page.
File Creation: Create a new file at server/routes/api/checkout.get.ts in your Nuxt project.

Code Snippet:

// server/routes/api/checkout.get.ts

export default defineEventHandler((event) => {
  const {
    private: { bearerToken, environment, returnUrl },
  } = useRuntimeConfig();

  const handler = checkoutHandler({
    bearerToken: bearerToken,
    environment: environment,
    returnUrl: returnUrl,
  });

  return handler(event);
});

Configuration & Usage:
- bearerToken: Your Dodo Payments API key. Set via the NUXT_PRIVATE_BEARER_TOKEN environment variable.
- returnUrl: (Optional) The URL to redirect the user to after a successful checkout.
- environment: (Optional) Set to your environment (e.g., "test_mode" or "live_mode").

Static Checkout (GET) Query Parameters:
- productId (required): Product identifier (e.g., ?productId=pdt_nZuwz45WAs64n3l07zpQR)
- quantity (optional): Quantity of the product
- Customer Fields (optional): fullName, firstName, lastName, email, country, addressLine, city, state, zipCode
- Disable Flags (optional, set to true to disable): disableFullName, disableFirstName, disableLastName, disableEmail, disableCountry, disableAddressLine, disableCity, disableState, disableZipCode
- Advanced Controls (optional): paymentCurrency, showCurrencySelector, paymentAmount, showDiscounts
- Metadata (optional): Any query parameter starting with metadata_ (e.g., ?metadata_userId=abc123)

Dynamic Checkout (POST): Parameters are sent as a JSON body. Supports both one-time and recurring payments. For a complete list of supported POST body fields, refer to:
- Docs - One Time Payment Product: https://docs.dodopayments.com/api-reference/payments/post-payments
- Docs - Subscription Product: https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions

Checkout Sessions (POST) - (Recommended) A more customizable checkout experience. Returns JSON with checkout_url: Parameters are sent as a JSON body. Supports both one-time and recurring payments. Returns: {"checkout_url": "https://checkout.dodopayments.com/session/..."}. For a complete list of supported fields, refer to:

  Checkout Sessions Integration Guide: https://docs.dodopayments.com/developer-resources/checkout-session

Error Handling: If productId is missing or other query parameters are invalid, the handler will return a 400 response.

If Customer Portal API Route is selected:

Purpose: This route allows customers to access their Dodo Payments customer portal.
File Creation: Create a new file at server/routes/api/customer-portal.get.ts in your Nuxt project.

Code Snippet:

// server/routes/api/customer-portal.get.ts

export default defineEventHandler((event) => {
  const {
    private: { bearerToken, environment },
  } = useRuntimeConfig();

  const handler = customerPortalHandler({
    bearerToken,
    environment: environment,
  });

  return handler(event);
});

Query Parameters:
- customer_id (required): The customer ID for the portal session (e.g., ?customer_id=cus_123)
- send_email (optional, boolean): If set to true, sends an email to the customer with the portal link.
- Returns 400 if customer_id is missing.

If Webhook API Route is selected:

Purpose: This route processes incoming webhook events from Dodo Payments, allowing your application to react to events like successful payments, refunds, or subscription changes.
File Creation: Create a new file at server/routes/api/webhook.post.ts in your Nuxt project.

Code Snippet:

// server/routes/api/webhook.post.ts

export default defineEventHandler((event) => {
  const {
    private: { webhookKey },
  } = useRuntimeConfig();

  const handler = Webhooks({
    webhookKey: webhookKey,
    onPayload: async (payload) => {
      // handle the payload
    },
    // ... other event handlers for granular control
  });

  return handler(event);
});

Handler Details:
- Method: Only POST requests are supported. Other methods return 405.
- Signature Verification: The handler verifies the webhook signature using webhookKey and returns 401 if verification fails.
- Payload Validation: The payload is validated with Zod. Returns 400 for invalid payloads.

Error Handling:
- 401: Invalid signature
- 400: Invalid payload
- 500: Internal error during verification

Event Routing: Calls the appropriate event handler based on the payload type. Supported event handlers include:
- onPayload?: (payload: WebhookPayload) => Promise<void>
- onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>
- onPaymentFailed?: (payload: WebhookPayload) => Promise<void>
- onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>
- onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>
- onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>
- onRefundFailed?: (payload: WebhookPayload) => Promise<void>
- onDisputeOpened?: (payload: WebhookPayload) => Promise<void>
- onDisputeExpired?: (payload: WebhookPayload) => Promise<void>
- onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>
- onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>
- onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>
- onDisputeWon?: (payload: WebhookPayload) => Promise<void>
- onDisputeLost?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>
- onSubscriptionUpdated?: (payload: WebhookPayload) => Promise<void>
- onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>
- onAbandonedCheckoutDetected?: (payload: WebhookPayload) => Promise<void>
- onAbandonedCheckoutRecovered?: (payload: WebhookPayload) => Promise<void>
- onDunningStarted?: (payload: WebhookPayload) => Promise<void>
- onDunningRecovered?: (payload: WebhookPayload) => Promise<void>
- onCreditAdded?: (payload: WebhookPayload) => Promise<void>
- onCreditDeducted?: (payload: WebhookPayload) => Promise<void>
- onCreditExpired?: (payload: WebhookPayload) => Promise<void>
- onCreditRolledOver?: (payload: WebhookPayload) => Promise<void>
- onCreditRolloverForfeited?: (payload: WebhookPayload) => Promise<void>
- onCreditOverageCharged?: (payload: WebhookPayload) => Promise<void>
- onCreditManualAdjustment?: (payload: WebhookPayload) => Promise<void>
- onCreditBalanceLow?: (payload: WebhookPayload) => Promise<void>

Environment Variable Setup:
To ensure the module functions correctly, set up the following environment variables in your Nuxt project's deployment environment (e.g., Vercel, Netlify, AWS, etc.):
- NUXT_PRIVATE_BEARER_TOKEN: Your Dodo Payments API Key (required for Checkout and Customer Portal).
- NUXT_PRIVATE_WEBHOOK_KEY: Your Dodo Payments Webhook Secret (required for Webhook handler).
- NUXT_PRIVATE_ENVIRONMENT: (Optional) Set to your environment (e.g., "test_mode" or "live_mode").
- NUXT_PRIVATE_RETURNURL: (Optional) The URL to redirect to after a successful checkout (for Checkout handler).

Usage in your code:
bearerToken: useRuntimeConfig().private.bearerToken
webhookKey: useRuntimeConfig().private.webhookKey

Important: Never commit sensitive environment variables directly into your version control. Use environment variables for all sensitive information.

If the user needs assistance setting up environment variables for their specific deployment environment, ask them what platform they are using (e.g., Vercel, Netlify, AWS, etc.), and provide guidance.
```
