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

# Mẫu FastAPI

> Bắt đầu nhanh chóng với mẫu FastAPI của chúng tôi để tích hợp Dodo Payments vào các ứng dụng backend Python của bạn

<Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/fastapi-boilerplate">
  Hoàn thiện mã mẫu FastAPI + Dodo Payments
</Card>

## Tổng quan

Mẫu FastAPI cung cấp một điểm khởi đầu sẵn sàng cho sản xuất để tích hợp Dodo Payments với backend Python của bạn. Mẫu này bao gồm xử lý phiên thanh toán, xác minh webhook, tích hợp cổng khách hàng và các mẫu API bất đồng bộ để giúp bạn bắt đầu chấp nhận thanh toán nhanh chóng.

<Info>
  Mã mẫu này sử dụng FastAPI với các mẫu async/await, Pydantic để xác thực và SDK Python `dodopayments` nhằm tích hợp API một cách liền mạch.
</Info>

### Tính năng

* **Cài đặt nhanh** - Bắt đầu trong chưa đầy 5 phút
* **Hỗ trợ bất đồng bộ** - Được xây dựng với các mẫu async/await của FastAPI
* **Phiên thanh toán** - Quy trình thanh toán được cấu hình sẵn sử dụng SDK Python
* **Xử lý Webhook** - Điểm cuối webhook an toàn với xác minh chữ ký
* **Cổng khách hàng** - Tạo phiên cổng khách hàng dễ dàng
* **An toàn kiểu** - Xác thực Pydantic đầy đủ và gợi ý kiểu
* **Cấu hình môi trường** - Cài đặt biến môi trường sẵn sàng sử dụng

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

Trước khi bắt đầu, hãy đảm bảo bạn đã có:

* **Python 3.9+** (khuyến nghị: Python 3.11+)
* **pip** hoặc **uv** để quản lý gói
* **Tài khoản Dodo Payments** (để truy cập API và Webhook Keys từ bảng điều khiển)

## Bắt đầu nhanh

<Steps>
  <Step title="Clone the Repository">
    ```bash theme={null}
    git clone https://github.com/dodopayments/fastapi-boilerplate.git
    cd fastapi-boilerplate
    ```
  </Step>

  <Step title="Create Virtual Environment">
    Thiết lập môi trường Python riêng biệt:

    ```bash theme={null}
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    ```

    Hoặc sử dụng uv để quản lý phụ thuộc nhanh hơn:

    ```bash theme={null}
    uv venv
    source .venv/bin/activate
    ```
  </Step>

  <Step title="Install Dependencies">
    ```bash theme={null}
    pip install -r requirements.txt
    ```

    Hoặc với uv:

    ```bash theme={null}
    uv pip install -r requirements.txt
    ```
  </Step>

  <Step title="Get API Credentials">
    Đăng ký tại [Dodo Payments](https://dodopayments.com/) và lấy thông tin xác thực từ bảng điều khiển:

    * **API Key:** [Bảng điều khiển → Nhà phát triển → API Keys](https://app.dodopayments.com/developer/api-keys)
    * **Webhook Key:** [Bảng điều khiển → Nhà phát triển → Webhooks](https://app.dodopayments.com/developer/webhooks)

    <Tip>
      Hãy chắc chắn bạn đang ở **Chế độ Kiểm thử** khi phát triển!
    </Tip>
  </Step>

  <Step title="Configure Environment Variables">
    Tạo một tệp `.env` trong thư mục gốc:

    ```bash theme={null}
    cp .env.example .env
    ```

    Cập nhật các giá trị với thông tin xác thực Dodo Payments của bạn:

    ```bash .env theme={null}
    DODO_PAYMENTS_API_KEY=your_api_key_here
    DODO_PAYMENTS_WEBHOOK_KEY=your_webhook_signing_key_here
    DODO_PAYMENTS_ENVIRONMENT=test_mode
    ```

    <Warning>
      Không bao giờ đưa tệp `.env` vào hệ thống kiểm soát phiên bản. Nó đã được bao gồm trong `.gitignore`.
    </Warning>
  </Step>

  <Step title="Run the Development Server">
    ```bash theme={null}
    uvicorn main:app --reload
    ```

    Mở [http://localhost:8000/docs](http://localhost:8000/docs) để xem tài liệu API tương tác!

    <Check>
      Bạn sẽ thấy giao diện Swagger UI của FastAPI với tất cả các điểm cuối sẵn sàng để kiểm thử.
    </Check>
  </Step>
</Steps>

## Cấu trúc Dự án

```text theme={null}
fastapi-boilerplate/
├── main.py                 # FastAPI application entry point
├── routers/
│   ├── checkout.py         # Checkout session endpoints
│   ├── webhook.py          # Webhook handler endpoint
│   └── customer_portal.py  # Customer portal endpoints
├── config.py               # Environment configuration
├── requirements.txt        # Python dependencies
├── .env.example            # Environment template
└── README.md
```

## Các Điểm Cuối API

Mẫu này bao gồm các điểm cuối được cấu hình sẵn sau:

| Endpoint           | Method | Description                     |
| ------------------ | ------ | ------------------------------- |
| `/checkout`        | POST   | Tạo một phiên thanh toán mới    |
| `/webhook`         | POST   | Xử lý webhook của Dodo Payments |
| `/customer-portal` | POST   | Tạo URL cổng khách hàng         |

## Ví dụ Mã

### Tạo một Phiên Thanh Toán

```python theme={null}
from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class CheckoutRequest(BaseModel):
    product_id: str
    quantity: int = 1
    customer_email: str | None = None
    customer_name: str | None = None

@router.post("/checkout")
async def create_checkout(request: CheckoutRequest):
    try:
        session = await dodo.checkout_sessions.create(
            product_cart=[{
                "product_id": request.product_id,
                "quantity": request.quantity
            }],
            customer={
                "email": request.customer_email,
                "name": request.customer_name
            } if request.customer_email else None,
            return_url="http://localhost:8000/success"
        )
        return {"checkout_url": session.checkout_url, "session_id": session.session_id}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))
```

### Xử lý Webhooks

```python theme={null}
from fastapi import APIRouter, Request, HTTPException
import hmac
import hashlib
from config import settings

router = APIRouter()

def verify_webhook_signature(payload: bytes, signature: str) -> bool:
    expected = hmac.new(
        settings.DODO_PAYMENTS_WEBHOOK_KEY.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@router.post("/webhook")
async def handle_webhook(request: Request):
    payload = await request.body()
    signature = request.headers.get("webhook-signature", "")
    
    if not verify_webhook_signature(payload, signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
    
    event = await request.json()
    event_type = event.get("type")
    
    match event_type:
        case "payment.succeeded":
            # Handle successful payment
            payment_id = event["data"]["payment_id"]
            print(f"Payment succeeded: {payment_id}")
            
        case "subscription.active":
            # Handle subscription activation
            subscription_id = event["data"]["subscription_id"]
            print(f"Subscription activated: {subscription_id}")
            
        case "refund.succeeded":
            # Handle refund
            refund_id = event["data"]["refund_id"]
            print(f"Refund processed: {refund_id}")
    
    return {"status": "received"}
```

### Tích hợp Cổng Khách Hàng

```python theme={null}
from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class PortalRequest(BaseModel):
    customer_id: str

@router.post("/customer-portal")
async def create_portal_session(request: PortalRequest):
    try:
        session = await dodo.customers.customer_portal.create(
            customer_id=request.customer_id,
        )
        return {"portal_url": session.link}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))
```

## Sự Kiện Webhook

Mẫu này minh họa việc xử lý các sự kiện webhook phổ biến:

| Event                    | Description                    |
| ------------------------ | ------------------------------ |
| `payment.succeeded`      | Thanh toán hoàn tất thành công |
| `payment.failed`         | Thử thanh toán thất bại        |
| `subscription.active`    | Đăng ký hiện đang hoạt động    |
| `subscription.cancelled` | Đăng ký đã bị hủy              |
| `refund.succeeded`       | Hoàn tiền đã xử lý thành công  |

Thêm logic kinh doanh của bạn bên trong trình xử lý webhook để:

* Cập nhật quyền người dùng trong cơ sở dữ liệu của bạn
* Gửi email xác nhận
* Cung cấp quyền truy cập vào sản phẩm kỹ thuật số
* Theo dõi phân tích và số liệu

## Kiểm Tra Webhooks Tại Địa Phương

Để phát triển tại địa phương, sử dụng các công cụ như [ngrok](https://ngrok.com/) để mở rộng máy chủ địa phương của bạn:

```bash theme={null}
ngrok http 8000
```

Cập nhật URL webhook trong [Bảng điều khiển Dodo Payments](https://app.dodopayments.com/developer/webhooks):

```
https://your-ngrok-url.ngrok.io/webhook
```

## Triển Khai

### Docker

```dockerfile theme={null}
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```

Xây dựng và chạy:

```bash theme={null}
docker build -t fastapi-dodo .
docker run -p 8000:8000 --env-file .env fastapi-dodo
```

### Cân Nhắc Sản Xuất

<Warning>
  Trước khi triển khai lên môi trường production:

  * Chuyển `DODO_PAYMENTS_ENVIRONMENT` sang `live_mode`
  * Sử dụng khóa API production từ bảng điều khiển
  * Cập nhật URL webhook về miền production của bạn
  * Bật HTTPS cho tất cả các điểm cuối
</Warning>

## Khắc Phục Sự Cố

<AccordionGroup>
  <Accordion title="Import errors or missing modules">
    Hãy đảm bảo môi trường ảo đã được kích hoạt và các phụ thuộc đã được cài đặt:

    ```bash theme={null}
    source venv/bin/activate
    pip install -r requirements.txt
    ```
  </Accordion>

  <Accordion title="Checkout session creation fails">
    **Nguyên nhân phổ biến:**

    * ID sản phẩm không hợp lệ - kiểm tra xem nó có tồn tại trên bảng điều khiển Dodo của bạn không
    * Khóa API hoặc thiết lập môi trường sai trong `.env`
    * Kiểm tra nhật ký FastAPI để nắm thông báo lỗi chi tiết
  </Accordion>

  <Accordion title="Webhooks not receiving events">
    Để kiểm thử cục bộ, sử dụng [ngrok](https://ngrok.com) để mở đầu máy chủ của bạn:

    ```bash theme={null}
    ngrok http 8000
    ```

    Cập nhật URL webhook trong [bảng điều khiển Dodo của bạn](https://app.dodopayments.com/developer/webhooks) thành URL ngrok. Hãy đảm bảo cập nhật tệp `.env` với khóa xác thực webhook chính xác.
  </Accordion>

  <Accordion title="Webhook signature verification fails">
    * Đảm bảo `DODO_PAYMENTS_WEBHOOK_KEY` được thiết lập chính xác trong `.env` của bạn
    * Xác minh bạn đang sử dụng thân yêu cầu thô để kiểm tra chữ ký
    * Kiểm tra xem bạn có đang đọc đúng header `webhook-signature` không
  </Accordion>
</AccordionGroup>

## Tìm Hiểu Thêm

<CardGroup cols={2}>
  <Card title="Python SDK" icon="python" href="/developer-resources/sdks/python">
    Hoàn thiện tài liệu SDK Python với hỗ trợ async
  </Card>

  <Card title="Webhooks Documentation" icon="webhook" href="/developer-resources/webhooks">
    Tìm hiểu tất cả các sự kiện webhook và thực hành tốt nhất
  </Card>

  <Card title="Checkout Sessions" icon="credit-card" href="/developer-resources/checkout-session">
    Đi sâu vào cấu hình phiên thanh toán checkout
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Tài liệu API đầy đủ của Dodo Payments
  </Card>
</CardGroup>

## Hỗ Trợ

Cần giúp đỡ với mẫu này?

* Tham gia cộng đồng [Discord của chúng tôi](https://discord.gg/bYqAp4ayYh) để đặt câu hỏi và thảo luận
* Kiểm tra [kho lưu trữ GitHub](https://github.com/dodopayments/fastapi-boilerplate) để biết các vấn đề và cập nhật
* Liên hệ với [đội ngũ hỗ trợ của chúng tôi](mailto:support@dodopayments.com) để được trợ giúp
