# 如何使用 Dodo Payments 为 Django SaaS 应用添加支付

> 分步介绍如何使用 Dodo Payments 将支付、订阅和许可证密钥集成到 Django SaaS 应用中。
- **Author**: Ayush Agarwal
- **Published**: 2026-04-05
- **Modified**: 2026-04-07
- **Category**: Integration, Django, How-To
- **URL**: https://dodopayments.com/blogs/zh/accept-payments-django-app

---

Django 为 SaaS 企业提供支持已有十多年。它自带身份验证、ORM、管理面板和成熟的生态系统，但没有内置支付层。正是这一缺口，让大多数 Django SaaS 项目白白耗费数周工程时间：团队忙于处理 Webhook、订阅状态机和税务合规，而不是构建产品。

本指南将从零开始，介绍如何将 [Dodo Payments](https://dodopayments.com) 集成到 Django SaaS 应用中。你将完成 Python SDK 的配置，创建产品，生成支付链接，处理 Webhook，管理订阅，并验证许可证密钥。所有代码示例都可用于生产环境，并遵循 Django 惯例。如果你使用的是 Next.js 或 Laravel，同样的概念也适用于 [add payments Next.js](https://dodopayments.com/blogs/add-payments-nextjs-app) 和 [add payments Laravel](https://dodopayments.com/blogs/add-payments-laravel-saas) 指南。

## 为什么 Django SaaS 支付比看起来更难

在开始编写代码前，先了解一下：与添加一个简单的结账按钮相比，为什么 Django 支付集成实际上要复杂得多。

典型的 SaaS 计费层需要处理：

- 一次性购买（终身优惠、预付额度包）
- 带试用期和套餐变更的周期性订阅
- 为桌面端或 API 产品交付许可证密钥
- 跨数十个司法管辖区计算税费
- Webhook 的可靠性，也就是说，事件可能乱序到达、重复到达，或在网络故障后才到达
- 失败支付恢复和催收邮件

大多数支付网关只提供底层 API，然后让你自行解决剩下的问题。[Dodo Payments](https://dodopayments.com) 正是为这套技术栈打造的。它负责 MoR（名义商户）的职责，因此你无需处理 VAT、GST 或销售税合规。它还提供一流的订阅管理、许可证密钥生成能力，以及与 Django 模式自然契合的 Python SDK。

## 集成架构

下面是各个组件如何连接的高层视图：

```mermaid
graph TD
    User["User Browser"] -->|1. Click upgrade| Django["Django App"]
    Django -->|2. Create payment link| DodoAPI["Dodo Payments API"]
    DodoAPI -->|3. Return checkout URL| Django
    Django -->|4. Redirect to checkout| Checkout["Dodo Hosted Checkout"]
    Checkout -->|5. User pays| DodoAPI
    DodoAPI -->|6. POST webhook event| WebhookView["Django Webhook View"]
    WebhookView -->|7. Verify signature| Django
    WebhookView -->|8. Update subscription model| DB["PostgreSQL"]
    DB -->|9. Grant access| User
```

流程很简单。你的 Django 应用向 Dodo API 请求支付链接。用户在托管结账页面完成支付。随后，Dodo 会向你的服务器发送带签名的 Webhook，你验证该 Webhook 后，用它更新本地数据库。你的应用再从数据库读取信息，以控制功能访问权限。

## 第 1 步：设置项目

先创建一个标准的 Django 项目。如果你要将 Dodo Payments 添加到现有应用中，可以跳到第 2 步。

```bash
python -m venv venv
source venv/bin/activate
pip install django dodopayments python-dotenv
django-admin startproject myapp .
python manage.py startapp billing
```

在 `settings.py` 的 `INSTALLED_APPS` 中添加 `billing`：

```python
INSTALLED_APPS = [
    # ... default apps
    "billing",
]
```

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

```bash
DODO_PAYMENTS_API_KEY=your_live_or_test_api_key
DODO_WEBHOOK_SECRET=your_webhook_signing_secret
```

在 `settings.py` 中加载这些变量：

```python
import os
from dotenv import load_dotenv

load_dotenv()

DODO_PAYMENTS_API_KEY = os.environ["DODO_PAYMENTS_API_KEY"]
DODO_WEBHOOK_SECRET = os.environ["DODO_WEBHOOK_SECRET"]
```

这两个值都可以在你的 [Dodo Payments](https://dodopayments.com) 控制台中找到。有关安装详情和 SDK 更新日志，请参阅 [Dodo Payments SDKs](https://docs.dodopayments.com/developer-resources/dodo-payments-sdks) 页面。

## 第 2 步：安装并初始化 Python SDK

Dodo Python SDK 为 [API reference](https://docs.dodopayments.com/api-reference/introduction) 提供了类型化响应和自动重试机制。安装 SDK 后，创建一个共享客户端模块。

```bash
pip install dodopayments
```

创建 `billing/client.py`：

```python
import os
import dodopayments

client = dodopayments.DodoPayments(
    bearer_token=os.environ["DODO_PAYMENTS_API_KEY"]
)
```

在任何需要调用 API 的地方，从该模块导入 `client`。将客户端保留为模块级单例，可以避免每次请求都重新实例化。

> 我们设计 Python SDK 时，希望它能让 Django 开发者感到自然熟悉。客户端是无状态且线程安全的，因此你只需在模块级别初始化一次，就可以像使用其他 Django 服务一样传递它。不需要按请求设置，也不需要中间件。
>
> - Ayush Agarwal，Dodo Payments 联合创始人兼 CPTO

## 第 3 步：定义计费模型

你需要使用本地模型来跟踪订阅状态、支付历史和许可证密钥。这些数据是应用执行访问控制时读取的事实来源。

创建 `billing/models.py`：

```python
[代码保持不变]
```

运行迁移：

```bash
python manage.py makemigrations billing
python manage.py migrate
```

## 第 4 步：在控制台中创建产品

在生成支付链接前，先在 Dodo Payments 控制台中创建产品。你可以创建一次性产品、订阅产品和许可证密钥产品。每个产品都会获得唯一的 `product_id`，你需要将它保存到 `Plan` 模型中。

完整的控制台产品创建流程，请参阅 [integration guide](https://docs.dodopayments.com/developer-resources/integration-guide)。

你也可以通过管理命令使用 SDK 创建产品：

```python
[代码保持不变]
```

# billing/management/commands/create_plan.py

[代码保持不变]

## 第 5 步：生成支付链接

支付链接是 Django 支付网关集成的核心。当用户点击"升级"时，你的视图会创建结账会话，并将用户重定向到托管支付页面。

创建 `billing/views.py`：

```python
[代码保持不变]
```

`metadata` 字段非常重要。Dodo Payments 会在 Webhook 负载中将它原样传回，因此你可以将支付匹配到特定用户，而不必仅依赖客户邮箱。

如果你希望打造完全嵌入式的结账体验，让用户始终留在你的域名下，请参阅 [overlay checkout](https://docs.dodopayments.com/developer-resources/overlay-checkout) 文档。它使用轻量级 JavaScript 代码片段，在模态窗口中渲染 Dodo 结账页面，而不是进行页面重定向。

## 第 6 步：处理 Webhook

Webhook 是可靠 Django SaaS 支付的基础。每当发生重要事件时，Dodo Payments 都会向你的服务器发送带签名的 POST 请求，例如订阅激活、支付失败或订阅取消。

最重要的规则是：在处理任何内容之前，先验证 Webhook 签名。Dodo 会使用你的 Webhook 密钥为每个请求签名，而处理未经验证的事件会造成严重的安全漏洞。

在 `billing/views.py` 中创建 Webhook 视图：

```python
[代码保持不变]
```

`PaymentEvent` 模型提供了幂等性。如果 Dodo 因你的服务器返回非 200 响应而重试 Webhook，第二次投递将不会执行任何操作。这种模式对于生产环境的可靠性至关重要。

> Webhook 幂等性是支付集成中最容易被低估的部分。在 Django 中，ORM 让你可以轻松地在处理前检查重复事件。我们发现，团队只要在处理逻辑运行前加入这一行存在性检查，生产环境问题就会大幅减少。
>
> - Ayush Agarwal，Dodo Payments 联合创始人兼 CPTO

如需查看所有可用事件类型和重试策略，请参阅完整的 [webhooks](https://docs.dodopayments.com/developer-resources/webhooks) 文档。

## 第 7 步：配置 URL

创建 `billing/urls.py`：

```python
[代码保持不变]
```

在项目主 `urls.py` 中引入这些 URL：

```python
[代码保持不变]
```

你的 Webhook URL 将是 `https://yourdomain.com/billing/webhook/`。在 Dodo Payments 控制台中注册此端点，即可开始接收事件。

## 第 8 步：订阅管理

用户拥有活跃订阅后，你需要为其提供管理订阅的方式：查看套餐、取消订阅或更改计费周期。[subscription management](https://docs.dodopayments.com/features/subscription) 文档涵盖了所有可用的订阅操作。

将以下视图添加到 `billing/views.py`：

```python
[代码保持不变]
```

如需查看完整的订阅更新选项列表，请参阅 [API reference](https://docs.dodopayments.com/api-reference/introduction)。

## 第 9 步：验证许可证密钥

如果你销售的是桌面应用、CLI 工具或按席位授权的 API，用户成功购买后，Dodo Payments 会自动交付[许可证密钥](https://docs.dodopayments.com/features/license-keys)。你的 Webhook 处理程序已经将它们保存到 `LicenseKey` 模型中。现在，你需要创建一个用于验证许可证密钥的端点。

将验证视图添加到 `billing/views.py`：

```python
[代码保持不变]
```

将 URL 添加到 `billing/urls.py`：

```python
path("validate-license/", views.validate_license, name="validate_license"),
```

你的桌面端或 CLI 客户端可以调用 `GET /billing/validate-license/?key=XXXX&instance_id=YYYY`，在启动时验证许可证。结合本地数据库查询和实时 Dodo API 验证，你可以同时获得速度与准确性。

## 第 10 步：在视图中控制访问权限

有了本地跟踪的订阅状态，控制访问权限就很简单了。在 `billing/decorators.py` 中创建一个装饰器：

```python
[代码保持不变]
```

将它应用到所有需要活跃订阅的视图：

```python
[代码保持不变]
```

## 定价与后续步骤

[Dodo Payments pricing](https://dodopayments.com/pricing) 简单透明：每笔交易按固定比例收取费用，不收取月度平台费。没有设置费，没有额外币种的隐藏费用，也不会对许可证密钥或订阅管理等功能额外收费。对于早期 SaaS 产品而言，这种模式能让成本直接与收入挂钩。

如果你正在评估 Dodo 如何融入更广泛的支付技术栈，[best payment platform for AI startups](https://dodopayments.com/blogs/best-payment-platform-ai-startups) 文章将详细介绍整个市场。

集成上线后，可以考虑以下后续步骤：

- 设置 [overlay checkout](https://docs.dodopayments.com/developer-resources/overlay-checkout)，让用户在结账期间始终留在你的域名下
- 添加 Celery 任务，在将订阅标记为逾期前重试失败的订阅续费
- 在一次性支付 API 之上构建按用量计费层，用于预付费计费产品
- 在 Dodo 控制台中启用催收邮件，自动挽回失败支付

完整的 [Dodo Payments SDKs](https://docs.dodopayments.com/developer-resources/dodo-payments-sdks) 页面列出了最新 SDK 版本、更新日志和 TypeScript 类型；如果你将 Django 与 TypeScript 前端结合使用，也可以参考该页面。

---

## 常见问题

### 向 Django 应用添加支付最简单的方法是什么？

最简单的方式是在 Dodo Payments 控制台中创建产品，然后按照 [integration guide](https://docs.dodopayments.com/developer-resources/integration-guide) 生成支付链接。你只需将链接作为标准锚点标签粘贴到模板中。不需要 SDK、Webhook 或服务器端代码。当你需要更多控制能力时，再添加上文介绍的 Python SDK 和 Webhook 处理程序即可。

### 在 Django 开发期间，如何在本地测试 Webhook？

使用 ngrok 等隧道工具，将本地服务器暴露到互联网。运行 `ngrok http 8000`，然后复制它提供的 HTTPS URL。在 Dodo Payments 控制台中，将该 URL 注册为 Webhook 端点。在 `.env` 文件中设置测试 API 密钥和 Webhook 密钥。Dodo 控制台还提供 Webhook 重放功能，可以将过去的事件重新发送到你的端点。

### 我可以在同一个应用中同时使用 Dodo Payments 处理订阅和一次性购买吗？

可以。`client.payments.create()` 调用中的 `product_cart` 字段可以接受任意组合的产品类型。你可以在同一次结账中同时放入订阅产品和一次性附加产品。Dodo 会分别处理每种商品类型的计费逻辑。订阅事件和支付事件会作为独立的 Webhook 到达，因此你的处理程序可以保持清晰。

### 如何处理失败的订阅支付？

当续费支付失败时，Dodo Payments 会发送 `subscription.on_hold` Webhook 事件。你的 Webhook 处理程序会将本地订阅状态更新为 `on_hold`。随后，你可以在应用中显示横幅，提示用户更新支付方式；也可以在订阅恢复前阻止其访问付费功能。Dodo 还提供内置催收系统，可按照可配置的时间表自动重试失败的扣款。

### 对于基于 Django 的 SaaS，Dodo Payments 适合用于向全球客户销售吗？

Dodo Payments 以 MoR（名义商户）的身份运营，这意味着它会在客户付款所在的每个司法管辖区处理 VAT、GST、销售税和合规事务。你的 Django 应用无需编写任何税费计算逻辑。客户可以看到本地化支付方式，Dodo 则负责申报税款。对于希望在全球销售、却不想雇用财务团队的独立创始人和小型团队来说，这一点尤其有价值。[subscription management](https://docs.dodopayments.com/features/subscription) 和 [license keys](https://docs.dodopayments.com/features/license-keys) 功能适用于所有受支持的国家和地区，无需额外配置。
---
- [More Integration articles](https://dodopayments.com/blogs/category/integration)
- [All articles](https://dodopayments.com/blogs)