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

# Astro 适配器

> 了解如何使用我们的 Astro 适配器将 Dodo Payments 集成到您的 Astro App Router 项目中。涵盖结账、客户门户、Webhook 和安全环境设置。

<CardGroup cols={2}>
  <Card title="Checkout Handler" icon="cart-shopping" href="#checkout-route-handler">
    将 Dodo Payments 结账集成到你的 Astro 应用中。
  </Card>

  <Card title="Customer Portal" icon="user" href="#customer-portal-route-handler">
    允许客户管理订阅和详细信息。
  </Card>

  <Card title="Webhooks" icon="bell" href="#webhook-route-handler">
    接收并处理 Dodo Payments Webhook 事件。
  </Card>
</CardGroup>

## 安装

<Steps>
  <Step title="Install the package">
    在项目根目录运行以下命令：

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

  <Step title="Set up environment variables">
    在项目根目录创建一个 <code>.env</code> 文件：

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

    <Warning>
      切勿将 <code>.env</code> 文件或秘密提交到版本控制。
    </Warning>
  </Step>
</Steps>

## 路由处理器示例

<Info>
  所有示例均假设你正在使用 Astro 应用路由。
</Info>

<Tabs>
  <Tab title="Checkout Handler">
    <Info>
      使用此处理器将 Dodo Payments 结账集成到你的 Astro 应用中。支持静态（GET）、动态（POST）和会话（POST）付款流程。
    </Info>

    <CodeGroup>
      ```typescript Astro Route Handler expandable theme={null}
      // src/pages/api/checkout.ts
      import { Checkout } from "@dodopayments/astro";
      export const prerender = false;

      export const GET = Checkout({
          bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
          returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
          environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "static", // optional, defaults to 'static'
      });

      export const POST = Checkout({
          bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
          returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
          environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "dynamic", // for dynamic checkout
      });

      export const POST = Checkout({
          bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
          returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
          environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "session", // for checkout sessions
      });
      ```
    </CodeGroup>

    <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 Handler">
    <Info>
      使用此处理器通过 Dodo Payments 客户门户允许客户管理其订阅和详细信息。
    </Info>

    <CodeGroup>
      ```typescript Astro Route Handler expandable theme={null}
      // src/pages/api/customer-portal.ts
      import { CustomerPortal } from "@dodopayments/astro";
      export const GET = CustomerPortal({
          bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
          environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
      });
      ```
    </CodeGroup>

    <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 Handler">
    <Info>
      使用此处理器在你的 Astro 应用中安全地接收并处理 Dodo Payments Webhook 事件。
    </Info>

    <CodeGroup>
      ```typescript expandable theme={null}
      // src/pages/api/webhook.ts
      import { Webhooks } from "@dodopayments/astro";

      export const POST = Webhooks({
          webhookKey: import.meta.env.DODO_PAYMENTS_WEBHOOK_KEY,
          onPayload: async (payload) => {
              // handle the payload
          },
          // ... other event handlers for granular control
      });
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## 结账路由处理器

<Info>
  Dodo Payments 支持三种类型的支付流程用于将支付集成到你的网站中，此适配器支持所有类型的支付流程。
</Info>

* **静态支付链接：** 可即时分享的 URL，用于快速、无代码的支付收集。
* **动态支付链接：** 使用 API 或 SDK 程序化生成带有自定义详细信息的支付链接。
* **结账会话：** 创建安全、可自定义的结账体验，具有预配置的产品购物车和客户详细信息。

<AccordionGroup>
  <Accordion title="Static Checkout (GET)">
    ### 支持的查询参数

    <ParamField query="productId" type="string" required>
      产品标识符（例如 <code>?productId=pdt\_nZuwz45WAs64n3l07zpQR</code>）。
    </ParamField>

    <ParamField query="quantity" type="integer">
      产品数量。
    </ParamField>

    <ParamField query="fullName" type="string">
      客户全名。
    </ParamField>

    <ParamField query="firstName" type="string">
      客户名。
    </ParamField>

    <ParamField query="lastName" type="string">
      客户姓。
    </ParamField>

    <ParamField query="email" type="string">
      客户邮箱地址。
    </ParamField>

    <ParamField query="country" type="string">
      客户所在国家。
    </ParamField>

    <ParamField query="addressLine" type="string">
      客户地址行。
    </ParamField>

    <ParamField query="city" type="string">
      客户所在城市。
    </ParamField>

    <ParamField query="state" type="string">
      客户所在州/省。
    </ParamField>

    <ParamField query="zipCode" type="string">
      客户邮政编码。
    </ParamField>

    <ParamField query="disableFullName" type="boolean">
      禁用全名字段。
    </ParamField>

    <ParamField query="disableFirstName" type="boolean">
      禁用名字段。
    </ParamField>

    <ParamField query="disableLastName" type="boolean">
      禁用姓字段。
    </ParamField>

    <ParamField query="disableEmail" type="boolean">
      禁用邮箱字段。
    </ParamField>

    <ParamField query="disableCountry" type="boolean">
      禁用国家字段。
    </ParamField>

    <ParamField query="disableAddressLine" type="boolean">
      禁用地址行字段。
    </ParamField>

    <ParamField query="disableCity" type="boolean">
      禁用城市字段。
    </ParamField>

    <ParamField query="disableState" type="boolean">
      禁用州字段。
    </ParamField>

    <ParamField query="disableZipCode" type="boolean">
      禁用邮政编码字段。
    </ParamField>

    <ParamField query="paymentCurrency" type="string">
      指定支付货币（例如 <code>USD</code>）。
    </ParamField>

    <ParamField query="showCurrencySelector" type="boolean">
      显示货币选择器。
    </ParamField>

    <ParamField query="paymentAmount" type="integer">
      指定支付金额（例如 <code>1000</code> 表示 \$10.00）。
    </ParamField>

    <ParamField query="showDiscounts" type="boolean">
      显示折扣字段。
    </ParamField>

    <ParamField query="metadata_*" type="string">
      任何以 <code>metadata\_</code> 开头的查询参数将作为元数据传递。
    </ParamField>

    <Warning>
      如果缺少 <code>productId</code>，处理程序将返回 400 响应。无效的查询参数也会导致 400 响应。
    </Warning>

    ### 响应格式

    静态结账返回一个包含结账 URL 的 JSON 响应：

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

  <Accordion title="Dynamic Checkout (POST)">
    * 以 JSON 正文发送参数（POST 请求）。
    * 支持一次性和订阅型付款。
    * 有关受支持的 POST 正文字段的完整列表，请参阅：
      * [一次性支付产品的请求正文](https://docs.dodopayments.com/api-reference/payments/post-payments)
      * [订阅产品的请求正文](https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions)

    ### 响应格式

    动态结账返回一个包含结账 URL 的 JSON 响应：

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

  <Accordion title="Checkout Sessions (POST)">
    结账会话提供更安全的托管结账体验，处理一次性购买和订阅的完整付款流程，并提供完全的定制控制。

    有关更多详细信息和支持字段的完整列表，请参阅 [结账会话集成指南](https://docs.dodopayments.com/developer-resources/checkout-session)。

    ### 响应格式

    结账会话返回一个包含结账 URL 的 JSON 响应：

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

## 客户门户路由处理器

客户门户路由处理器使您能够将 Dodo Payments 客户门户无缝集成到您的 Astro 应用中。

### 查询参数

<ParamField query="customer_id" type="string" required>
  门户会话的客户 ID（例如 <code>?customer\_id=cus\_123</code>）。
</ParamField>

<ParamField query="send_email" type="boolean">
  如果设置为 <code>true</code>，会向客户发送包含门户链接的电子邮件。
</ParamField>

<Warning>
  如果缺少 <code>customer\_id</code>，将返回 400。
</Warning>

## Webhook 路由处理器

* **方法：** 仅支持 POST 请求。其他方法返回 405。
* **签名验证：** 使用 <code>webhookKey</code> 验证 Webhook 签名。如果验证失败，返回 401。
* **有效负载验证：** 使用 Zod 进行验证。无效的有效负载返回 400。
* **错误处理：**
  * 401：无效签名
  * 400：无效有效负载
  * 500：验证期间的内部错误
* **事件路由：** 根据有效负载类型调用相应的事件处理器。

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

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

***

## LLM 提示

```

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

The @dodopayments/astro adapter provides route handlers for Dodo Payments' Checkout, Customer Portal, and Webhook functionalities, designed for the Astro App Router.

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/astro

Here's how you should structure your response:

    Ask the user which functionalities they want to integrate.

"Which parts of the @dodopayments/astro 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 redirects users to the Dodo Payments checkout page.
File Creation: Create a new file at app/checkout/route.ts in your Astro project.

Code Snippet:

// src/pages/api/checkout.ts
import { Checkout } from "@dodopayments/astro";

export const prerender = false;

export const GET = Checkout({
  bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
  returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
  environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "static", // optional, defaults to 'static'
});

export const POST = Checkout({
  bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
  returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
  environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "dynamic", // for dynamic checkout
});

export const POST = Checkout({
  bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
  returnUrl: import.meta.env.DODO_PAYMENTS_RETURN_URL,
  environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "session", // for checkout sessions
});

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.

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

Purpose: This handler redirects authenticated users to their Dodo Payments customer portal.
File Creation: Create a new file at app/customer-portal/route.ts in your Astro project.

Code Snippet:

// src/pages/api/customer-portal.ts
import { CustomerPortal } from "@dodopayments/astro";

export const GET = CustomerPortal({
  bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY,
  environment: import.meta.env.DODO_PAYMENTS_ENVIRONMENT,
});

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 app/api/webhook/dodo-payments/route.ts in your Astro project.

Code Snippet:

// src/pages/api/webhook.ts
import { Webhooks } from "@dodopayments/astro";

export const POST = Webhooks({
  webhookKey: import.meta.env.DODO_PAYMENTS_WEBHOOK_KEY,
  onPayload: async (payload) => {
    // handle the payload
  },
  // ... other event handlers for granular control
});

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 the appropriate event handler based on the payload 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>

    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 adapter functions correctly, you will need to manually set up the following environment variables in your Astro 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).

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

    DODO_PAYMENTS_WEBHOOK_SECRET: 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_ENVIRONMENT="test_mode" or "live_mode"
DODO_PAYMENTS_RETURN_URL=your-return-url

Usage in your code:

bearerToken: import.meta.env.DODO_PAYMENTS_API_KEY
webhookKey: import.meta.env.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

```
