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

# SvelteKit 适配器

> 使用 @dodopayments/sveltekit 包和 +server.ts 路由处理程序，将 Dodo Payments checkout、Customer Portal 和 webhook 路由处理程序添加到 SvelteKit 应用。

`@dodopayments/sveltekit` 包为你的 SvelteKit 应用提供三个路由处理程序。`Checkout` 返回 checkout URL，`CustomerPortal` 将客户发送到 Customer Portal，而 `Webhooks` 验证 webhook 事件并将其路由到你的代码。

> **[Checkout Handler](#checkout-route-handler)**
>
> 从你的 SvelteKit 应用创建 checkout URL。

> **[Customer Portal](#customer-portal-route-handler)**
>
> 让客户管理其订阅和详细信息。

> **[Webhooks](#webhook-route-handler)**
>
> 接收并验证 Dodo Payments webhook 事件。

## 安装

**1. Install the Package**

在项目根目录运行此命令：

```bash theme={null}
npm install @dodopayments/sveltekit
```

该包将 SvelteKit 2（`@sveltejs/kit` 2.20.3 或更高版本）和 `zod` 3.25 或更高版本列为 peer dependencies。

**2. Set Up Environment Variables**

在项目根目录创建一个 `.env` 文件：

```env expandable theme={null}
DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
# test_mode or live_mode
DODO_PAYMENTS_ENVIRONMENT=test_mode
DODO_PAYMENTS_RETURN_URL=https://yourdomain.com/checkout/success
```

在 **Developer → API Keys** 下创建 API key。在 **Developer → Webhooks** 下添加 webhook endpoint，并将其 signing secret 复制到 `DODO_PAYMENTS_WEBHOOK_KEY`。`DODO_PAYMENTS_RETURN_URL` 是客户完成 checkout 后跳转到的位置。如果不传入环境，处理程序将使用 `live_mode`。

> [!WARNING]
>
> 切勿将 `.env` 文件或 secrets 提交到版本控制系统。

## 路由处理程序示例

> [!NOTE]
>
> 这些示例是位于 `src/routes/api/` 下的 SvelteKit `+server.ts` endpoints。它们从 `$env/static/private` 导入你的凭据，SvelteKit 会将该文件排除在客户端代码之外。

**Checkout Handler**

> [!NOTE]
>
> 使用此处理程序将 Dodo Payments checkout 添加到你的 SvelteKit 应用。`Checkout` 返回一个 `GET` 处理程序（用于静态 checkout）和一个 `POST` 处理程序（用于 checkout sessions）；当设置 `type: "dynamic"` 时，也可用于动态 checkout。请从使用 `type: "static"` 创建的处理程序中导出 `GET`，或者不使用 `type`，因为 `session` 或 `dynamic` 处理程序的 `GET` 处理程序会返回 400。

```typescript SvelteKit Route Handler expandable theme={null}
// src/routes/api/checkout/+server.ts
import { Checkout } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_RETURN_URL, DODO_PAYMENTS_ENVIRONMENT } from '$env/static/private';

const checkoutGetHandler = Checkout({
    bearerToken: DODO_PAYMENTS_API_KEY,
    returnUrl: DODO_PAYMENTS_RETURN_URL,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
    type: "static",
});

const checkoutPostHandler = Checkout({
    bearerToken: DODO_PAYMENTS_API_KEY,
    returnUrl: DODO_PAYMENTS_RETURN_URL,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
    type: "session", // or "dynamic" for dynamic link
});

export const GET = checkoutGetHandler.GET;
export const POST = checkoutPostHandler.POST;
```

```bash Static Checkout cURL Example theme={null}
curl --request GET \
--url 'https://example.com/api/checkout?productId=pdt_fqJhl7pxKWiLhwQR042rh'
```

```bash Dynamic Checkout cURL Example expandable theme={null}
curl --request POST \
--url https://example.com/api/checkout \
--header 'Content-Type: application/json' \
--data '{
"billing": {
  "city": "Austin",
  "country": "US",
  "state": "TX",
  "street": "123 Main St",
  "zipcode": "78701"
},
"customer": {
  "email": "customer@example.com",
  "name": "John Doe"
},
"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
}'
```

```bash Checkout Session cURL Example expandable theme={null}
curl --request POST \
--url https://example.com/api/checkout \
--header 'Content-Type: application/json' \
--data '{
"product_cart": [
  {
    "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
    "quantity": 1
  }
],
"customer": {
  "email": "customer@example.com",
  "name": "John Doe"
},
"return_url": "https://example.com/success"
}'
```

当 `POST` 来自使用 `type: "dynamic"` 创建的处理程序时，动态 checkout 请求即可正常工作。使用 `type: "session"` 时（如示例路由所示），发送 checkout session 请求。

**Customer Portal Handler**

> [!NOTE]
>
> 使用此处理程序将客户发送到 Dodo Payments Customer Portal，客户可以在其中管理其订阅和详细信息。

```typescript SvelteKit Route Handler expandable theme={null}
// src/routes/api/customer-portal/+server.ts
import { CustomerPortal } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_ENVIRONMENT } from '$env/static/private';

const customerPortalHandler = CustomerPortal({
    bearerToken: DODO_PAYMENTS_API_KEY,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
});

export const GET = customerPortalHandler.GET;
```

**Webhook Handler**

> [!NOTE]
>
> 使用此处理程序在你的 SvelteKit 应用中接收 Dodo Payments webhook 事件并验证其签名。

```typescript SvelteKit Route Handler expandable theme={null}
// src/routes/api/webhook/+server.ts
import { Webhooks } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_WEBHOOK_KEY } from '$env/static/private';

export const POST = Webhooks({
    webhookKey: DODO_PAYMENTS_WEBHOOK_KEY,
    onPayload: async (payload) => {
        console.log(payload);
    }
});
```

## Checkout 路由处理程序

checkout 处理程序支持使用 Dodo Payments 收款的三种方式：

* **静态 Payment Links：** 可分享的 URL，无需代码即可收款。
* **动态 Payment Links：** 使用自定义详细信息生成的 payment links。它们使用已弃用的 endpoints。
* **Checkout Sessions：** 支持产品购物车、客户详细信息和自定义选项的托管 checkout。这是推荐的流程。

`Checkout` 接受以下选项：

| 选项 | 类型 | 描述 |
| - | - | - |
| `bearerToken` | `string` | 你的 Dodo Payments API key。 |
| `environment` | `string` | `test_mode` 或 `live_mode`。默认为 `live_mode`。 |
| `returnUrl` | `string` | 可选。checkout 在付款后将客户重定向到的 URL。POST body 中的 `return_url` 优先级更高。 |
| `type` | `string` | 可选。对于 `GET` 处理程序，使用 `static`（默认值）。对于 `POST` 处理程序，`dynamic` 选择动态 checkout，任何其他值或不设置该值则选择 checkout sessions。 |

> **Static Checkout (GET)**
>
> ### 支持的 Query Parameters
>
> **productId** `string` *required*
>
> 产品标识符，例如 `?productId=pdt_nZuwz45WAs64n3l07zpQR`。
>
> **quantity** `integer` (default: 1)
>
> 产品数量。
>
> **fullName** `string`
>
> 客户的全名。如果提供了 `firstName` 或 `lastName`，则会忽略此项。
>
> **firstName** `string`
>
> 客户的名字。
>
> **lastName** `string`
>
> 客户的姓氏。
>
> **email** `string`
>
> 客户的电子邮件地址。
>
> **country** `string`
>
> 客户所在国家，使用 ISO 3166-1 alpha-2 代码表示。
>
> **addressLine** `string`
>
> 客户的地址行。
>
> **city** `string`
>
> 客户所在城市。
>
> **state** `string`
>
> 客户所在州或省。
>
> **zipCode** `string`
>
> 客户的 ZIP 或邮政编码。
>
> **disableFullName** `boolean`
>
> 设置为 `true` 可禁用全名字段。
>
> **disableFirstName** `boolean`
>
> 设置为 `true` 可禁用名字字段。
>
> **disableLastName** `boolean`
>
> 设置为 `true` 可禁用姓氏字段。
>
> **disableEmail** `boolean`
>
> 设置为 `true` 可禁用电子邮件字段。
>
> **disableCountry** `boolean`
>
> 设置为 `true` 可禁用国家字段。
>
> **disableAddressLine** `boolean`
>
> 设置为 `true` 可禁用地址行字段。
>
> **disableCity** `boolean`
>
> 设置为 `true` 可禁用城市字段。
>
> **disableState** `boolean`
>
> 设置为 `true` 可禁用州字段。
>
> **disableZipCode** `boolean`
>
> 设置为 `true` 可禁用 ZIP code 字段。
>
> **paymentCurrency** `string`
>
> 付款货币，例如 `USD`。
>
> **showCurrencySelector** `boolean` (default: true)
>
> 显示或隐藏货币选择器。
>
> **paymentAmount** `number`
>
> 固定收取的金额，以主要货币单位表示，例如 `12.5` 表示 \$12.50。仅适用于 Pay What You Want 产品；如果该金额低于产品最低价格，则会被忽略。
>
> **showDiscounts** `boolean` (default: true)
>
> 显示或隐藏折扣部分。
>
> **metadata\_**\* `string`
>
> 任何以 `metadata_` 开头的 query parameter 都会作为 metadata 传递。
>
> 处理程序会将其配置中的 `returnUrl` 以 `redirect_url` 的形式添加到链接中。
>
> > [!WARNING]
> >
> > 如果缺少 `productId`，处理程序会返回 400 响应。无效的 query parameters 和不存在的产品 ID 也会返回 400。
>
> ### 响应格式
>
> 静态 checkout 返回包含 checkout URL 的 JSON 响应。在测试模式下，URL 使用 `test.checkout.dodopayments.com`。
>
> ```json theme={null}
> {
>   "checkout_url": "https://checkout.dodopayments.com/..."
> }
> ```

> **Dynamic Checkout (POST)**
>
> * 在 POST 请求中将参数作为 JSON body 发送。
> * 同时支持一次性付款和周期性付款。
> * `billing` 和 `customer` 是必需的。
> * 有关所有受支持的 body 字段，请参阅：
>   * [一次性付款产品的 Request body](https://docs.dodopayments.com/api-reference/payments/post-payments)
>
>   * [订阅产品的 Request body](https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions)
>
> > [!WARNING]
> >
> > 动态 checkout 代理已弃用的 `POST /payments` 和 `POST /subscriptions` endpoints。它会继续为现有集成提供支持，但新集成应使用 checkout sessions。
>
> ### 响应格式
>
> 动态 checkout 返回包含 checkout URL 的 JSON 响应：
>
> ```json theme={null}
> {
>   "checkout_url": "https://checkout.dodopayments.com/..."
> }
> ```

> **Checkout Sessions (POST)**
>
> Checkout sessions 为一次性购买和订阅创建托管 checkout，并提供完整的自定义控制。`product_cart` 是唯一必需的字段。如果 body 中没有 `return_url`，处理程序会使用其配置中的 `returnUrl`。
>
> 有关更多详细信息以及所有受支持的字段，请参阅 [Checkout Sessions Integration Guide](https://docs.dodopayments.com/developer-resources/checkout-session)。
>
> 使用 `payment_method_id` 创建的 session 不会返回 checkout URL，因此处理程序会响应 400。若要向已保存的付款方式收费，请改用 SDK 创建 session。
>
> ### 响应格式
>
> Checkout sessions 返回包含 checkout URL 的 JSON 响应：
>
> ```json theme={null}
> {
>   "checkout_url": "https://checkout.dodopayments.com/session/..."
> }
> ```

## Customer Portal 路由处理程序

Customer Portal 路由处理程序会为你传入的客户创建 Customer Portal session，并使用 302 响应将浏览器重定向到该 session。

> [!WARNING]
>
> 处理程序不会检查调用者的身份。任何使用客户 ID 请求它的人都能获得该客户的 portal。请使用你自己的身份验证保护此路由，并且只传入已登录用户的客户 ID。

### Query Parameters

**customer\_id** `string` *required*

portal session 的客户 ID，例如 `?customer_id=cus_123`。

**send\_email** `boolean`

如果设置为 `true`，Dodo Payments 还会通过电子邮件将 portal 链接发送给客户。

> [!WARNING]
>
> 如果缺少 `customer_id`，则返回 400；如果无法创建 portal session，则返回 500。

## Webhook 路由处理程序

webhook 路由处理程序会在运行你的代码前验证每个请求：

* **Method：** 仅支持 POST 请求。其他 method 返回 405。
* **Signature Verification：** 根据 [Standard Webhooks](https://standardwebhooks.com/) 规范，使用 `webhookKey` 验证原始请求 body 以及 `webhook-id`、`webhook-timestamp` 和 `webhook-signature` headers。如果验证失败，则返回 401。
* **Payload Validation：** 使用 Zod 验证 payload。payload 无效时返回 400。
* **Error Handling：**
  * 401：签名无效
  * 400：payload 无效
  * 500：验证期间发生内部错误
* **Event Routing：** 对每个事件调用 `onPayload`，然后调用与事件类型对应的处理程序，并返回 200。

该 adaptor 不会捕获你的处理程序抛出的错误。错误会传播到 SvelteKit，请求也会失败。

### 支持的 Webhook 事件处理程序

每个处理程序都会接收其事件类型对应的已验证 payload：

```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>;
onSubscriptionPaused?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionUnpaused?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionUpdatePaymentMethod?: (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>;
onCreditOverageReset?: (payload: WebhookPayload) => Promise<void>;
onCreditManualAdjustment?: (payload: WebhookPayload) => Promise<void>;
onCreditBalanceLow?: (payload: WebhookPayload) => Promise<void>;
onEntitlementGrantCreated?: (payload: WebhookPayload) => Promise<void>;
onEntitlementGrantDelivered?: (payload: WebhookPayload) => Promise<void>;
onEntitlementGrantFailed?: (payload: WebhookPayload) => Promise<void>;
onEntitlementGrantRevoked?: (payload: WebhookPayload) => Promise<void>;
onPayoutCreated?: (payload: WebhookPayload) => Promise<void>;
onPayoutOnHold?: (payload: WebhookPayload) => Promise<void>;
onPayoutInProgress?: (payload: WebhookPayload) => Promise<void>;
onPayoutFailed?: (payload: WebhookPayload) => Promise<void>;
onPayoutSuccess?: (payload: WebhookPayload) => Promise<void>;
```

有关每个事件含义的说明，请参阅 [Webhook Event Guide](/developer-resources/webhooks/intents/webhook-events-guide)。

***

## LLM 提示词

将此提示词复制到 AI coding assistant 中，让它将 adaptor 添加到你的项目中。若要同时向 agent 提供 Dodo Payments 文档和 skills，请安装 [Agent Plugin](/developer-resources/build-with-ai-coding-agents)。

```text expandable theme={null}

You are an expert SvelteKit developer assistant. Your task is to guide a user through integrating the @dodopayments/sveltekit adapter into their existing SvelteKit project.

The @dodopayments/sveltekit adapter provides route handlers for Dodo Payments' Checkout, Customer Portal, and Webhook functionalities, designed for SvelteKit server routes (+server.ts files).

First, install the necessary packages. Use the package manager appropriate for your project (npm, yarn, or bun) based on the presence of lock files (e.g., package-lock.json for npm, yarn.lock for yarn, bun.lockb for bun):

npm install @dodopayments/sveltekit

Here's how you should structure your response:

    Ask the user which functionalities they want to integrate.

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

    Checkout Route Handler (for handling product checkouts)

    Customer Portal Route Handler (for managing customer subscriptions/details)

    Webhook Route Handler (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 Route Handler is selected:

Purpose: This handler manages different types of checkout flows. All checkout types (static, dynamic, and sessions) return JSON responses with checkout URLs for programmatic handling.
File Creation: Create a new file at src/routes/api/checkout/+server.ts in your SvelteKit project.

Code Snippet:

// src/routes/api/checkout/+server.ts
import { Checkout } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_RETURN_URL, DODO_PAYMENTS_ENVIRONMENT } from '$env/static/private';

const checkoutGetHandler = Checkout({
    bearerToken: DODO_PAYMENTS_API_KEY,
    returnUrl: DODO_PAYMENTS_RETURN_URL,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
    type: "static",
});

const checkoutPostHandler = Checkout({
    bearerToken: DODO_PAYMENTS_API_KEY,
    returnUrl: DODO_PAYMENTS_RETURN_URL,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
    type: "session", // or "dynamic" for dynamic link
});

export const GET = checkoutGetHandler.GET;
export const POST = checkoutPostHandler.POST;

Configuration & Usage:

    bearerToken: Your Dodo Payments API key. It's recommended to set this via the DODO_PAYMENTS_API_KEY environment variable.

    returnUrl: (Optional) The URL to redirect the user to after a successful checkout.

    environment: (Optional) Set to "test_mode" for testing, or omit/set to "live_mode" for production.

    type: (Optional) Set to "static" for GET/static checkout, "dynamic" for POST/dynamic checkout, or "session" for POST/checkout sessions. Defaults to "static". Export GET only from a handler created with type "static".

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)
    
    Returns: {"checkout_url": "https://checkout.dodopayments.com/..."}

Dynamic Checkout (POST) - 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/..."}. 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, and product_cart is required. 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 parameters are invalid, the handler will return a 400 response.

If Customer Portal Route Handler is selected:

Purpose: This handler redirects a customer to their Dodo Payments customer portal. It does not authenticate the caller, so protect the route and pass only the signed-in user's customer ID.
File Creation: Create a new file at src/routes/api/customer-portal/+server.ts in your SvelteKit project.

Code Snippet:

// src/routes/api/customer-portal/+server.ts
import { CustomerPortal } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_ENVIRONMENT } from '$env/static/private';

const customerPortalHandler = CustomerPortal({
    bearerToken: DODO_PAYMENTS_API_KEY,
    environment: DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
});

export const GET = customerPortalHandler.GET;

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 Route Handler is selected:

Purpose: This handler 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 src/routes/api/webhook/+server.ts in your SvelteKit project.

Code Snippet:

// src/routes/api/webhook/+server.ts
import { Webhooks } from "@dodopayments/sveltekit";
import { DODO_PAYMENTS_WEBHOOK_KEY } from '$env/static/private';

export const POST = Webhooks({
    webhookKey: DODO_PAYMENTS_WEBHOOK_KEY,
    onPayload: async (payload) => {
        console.log(payload);
    }
});

Handler Details:

    Method: Only POST requests are supported. Other methods return 405.

    Signature Verification: The handler verifies the webhook signature using the 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 onPayload for every event, then the handler for the event's type.

Supported Webhook Event Handlers:

    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>

    onSubscriptionPaused?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionUnpaused?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionUpdatePaymentMethod?: (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>

    onCreditOverageReset?: (payload: WebhookPayload) => Promise<void>

    onCreditManualAdjustment?: (payload: WebhookPayload) => Promise<void>

    onCreditBalanceLow?: (payload: WebhookPayload) => Promise<void>

    onEntitlementGrantCreated?: (payload: WebhookPayload) => Promise<void>

    onEntitlementGrantDelivered?: (payload: WebhookPayload) => Promise<void>

    onEntitlementGrantFailed?: (payload: WebhookPayload) => Promise<void>

    onEntitlementGrantRevoked?: (payload: WebhookPayload) => Promise<void>

    onPayoutCreated?: (payload: WebhookPayload) => Promise<void>

    onPayoutOnHold?: (payload: WebhookPayload) => Promise<void>

    onPayoutInProgress?: (payload: WebhookPayload) => Promise<void>

    onPayoutFailed?: (payload: WebhookPayload) => Promise<void>

    onPayoutSuccess?: (payload: WebhookPayload) => Promise<void>

    Environment Variable Setup:

To ensure the adapter functions correctly, you will need to manually set up the following environment variables in your SvelteKit project's deployment environment (e.g., Vercel, Netlify, AWS, etc.):

    DODO_PAYMENTS_API_KEY: Your Dodo Payments API Key (required for Checkout and Customer Portal).

    DODO_PAYMENTS_RETURN_URL: (Optional) The URL to redirect to after a successful checkout (for Checkout handler).

    DODO_PAYMENTS_ENVIRONMENT: (Optional) "test_mode" or "live_mode". Defaults to "live_mode".

    DODO_PAYMENTS_WEBHOOK_KEY: Your Dodo Payments Webhook Secret (required for Webhook handler).

Example .env file:

DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
DODO_PAYMENTS_RETURN_URL=your-return-url
DODO_PAYMENTS_ENVIRONMENT=test_mode

Usage in your code (SvelteKit server routes import these from $env/static/private):

import { DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_WEBHOOK_KEY } from '$env/static/private';
bearerToken: DODO_PAYMENTS_API_KEY
webhookKey: DODO_PAYMENTS_WEBHOOK_KEY

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. You can also add comments to their PR or chat depending on the context

```


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