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

# Rust

> Tích hợp Dodo Payments vào ứng dụng Rust của bạn với SDK định kiểu mạnh mẽ, ưu tiên bất đồng bộ, được xây dựng trên Tokio và reqwest

Rust SDK cung cấp khả năng truy cập tiện lợi, ưu tiên bất đồng bộ đến REST API của Dodo Payments từ các ứng dụng viết bằng Rust. Nó cung cấp các yêu cầu và phản hồi định kiểu mạnh mẽ, công cụ phân trang tích hợp sẵn, và khả năng cấu hình thời gian chờ và môi trường.

## Cài đặt

Thêm SDK vào dự án của bạn với Cargo:

```bash theme={null}
cargo add dodopayments
```

Hoặc thêm nó vào `Cargo.toml` của bạn thủ công:

```toml theme={null}
[dependencies]
dodopayments = "1.106.0"
tokio = { version = "1", features = ["full"] }
serde_json = "1"
futures = "0.3" # required for streaming paginated results
```

<Info>
  SDK yêu cầu Rust 1.75 hoặc mới hơn, tận dụng các tính năng bất đồng bộ hiện đại để đạt hiệu suất tối ưu.
</Info>

## Bắt đầu nhanh

Client đọc khóa API của bạn từ biến môi trường `DODO_PAYMENTS_API_KEY` theo mặc định. Khởi tạo client và tạo phiên checkout đầu tiên của bạn:

```rust theme={null}
use dodopayments::Client;

#[tokio::main]
async fn main() -> dodopayments::Result<()> {
    let client = Client::from_env()?;

    let result = client
        .checkout_sessions()
        .create()
        .body(dodopayments::models::CheckoutSessionsCreateParams {
            product_cart: Some(vec![dodopayments::models::ProductItemReq {
                product_id: "product_id".to_string(),
                quantity: 1,
                addons: None,
                amount: None,
                credit_entitlements: None,
            }]),
            ..Default::default()
        })
        .await?;

    println!("{result:?}");
    Ok(())
}
```

<Warning>
  Luôn lưu trữ khóa API của bạn một cách an toàn bằng cách sử dụng biến môi trường. Không bao giờ mã hóa cứng chúng trong mã nguồn của bạn.
</Warning>

## Tính năng cốt lõi

<CardGroup cols={2}>
  <Card title="Async First" icon="bolt">
    Được xây dựng trên Tokio và reqwest với hỗ trợ `async`/`await` xuyên suốt
  </Card>

  <Card title="Strong Typing" icon="shield-check">
    Yêu cầu và phản hồi định kiểu mạnh mẽ cho an toàn khi biên dịch
  </Card>

  <Card title="Auto-Pagination" icon="layer-group">
    Truyền trực tiếp mọi mục qua các trang hoặc tiến từng trang một
  </Card>

  <Card title="Configurable" icon="sliders">
    Cấu hình môi trường, thời gian chờ, và URL nền tảng theo từng client
  </Card>
</CardGroup>

## Cấu hình

### Biến môi trường

Theo mặc định, `Client::from_env()` đọc khóa API của bạn từ biến môi trường `DODO_PAYMENTS_API_KEY` và sử dụng URL nền tảng mặc định trừ khi bạn đặt `DODO_PAYMENTS_BASE_URL`:

```bash theme={null}
export DODO_PAYMENTS_API_KEY="your_api_key"
export DODO_PAYMENTS_BASE_URL="https://test.dodopayments.com" # optional
```

Bạn cũng có thể cấu hình client rõ ràng. `Client::new` trả về một `Result`, vì vậy hãy mở nó ra với `?` bên trong một hàm trả về `dodopayments::Result`:

```rust theme={null}
use dodopayments::{Client, ClientConfig};

#[tokio::main]
async fn main() -> dodopayments::Result<()> {
    let client = Client::new(
        ClientConfig::new("https://live.dodopayments.com").with_api_key("My API Key"),
    )?;
    println!("{}", client.base_url());
    Ok(())
}
```

### Môi trường

| Name        | Base URL                        |
| ----------- | ------------------------------- |
| `live_mode` | `https://live.dodopayments.com` |
| `test_mode` | `https://test.dodopayments.com` |

URL nền tảng mặc định là `https://live.dodopayments.com`. Chọn một môi trường khác với enum `Environment` thay vì mã hóa URL:

```rust theme={null}
use dodopayments::{Client, ClientConfig, Environment};

let client = Client::new(
    ClientConfig::from_environment(Environment::TestMode).with_api_key("My API Key"),
)?;
```

Để tiếp tục đọc khóa API từ `DODO_PAYMENTS_API_KEY` qua `from_env()` trong khi nhắm mục tiêu đến một môi trường không mặc định, ghi đè nó trên cấu hình:

```rust theme={null}
use dodopayments::{Client, ClientConfig, Environment};

let client = Client::new(ClientConfig::from_env()?.with_environment(Environment::TestMode))?;
```

### Thời gian chờ

Thời gian chờ mặc định của yêu cầu là 30 giây. Ghi đè nó theo từng client:

```rust theme={null}
use std::time::Duration;
use dodopayments::{Client, ClientConfig};

let client = Client::new(
    ClientConfig::new("https://live.dodopayments.com")
        .with_api_key("My API Key")
        .with_timeout(Duration::from_secs(60)),
)?;
```

## Hoạt động phổ biến

### Tạo phiên Checkout

Tạo một phiên checkout:

```rust theme={null}
let session = client
    .checkout_sessions()
    .create()
    .body(dodopayments::models::CheckoutSessionsCreateParams {
        product_cart: Some(vec![dodopayments::models::ProductItemReq {
            product_id: "prod_123".to_string(),
            quantity: 1,
            addons: None,
            amount: None,
            credit_entitlements: None,
        }]),
        return_url: Some("https://yourdomain.com/return".to_string()),
        ..Default::default()
    })
    .await?;

println!("{session:?}");
```

### Quản lý Khách hàng

Tạo và lấy thông tin khách hàng:

```rust theme={null}
// Create a customer
let customer = client
    .customers()
    .create()
    .body(dodopayments::models::CustomerCreateParams {
        email: "customer@example.com".to_string(),
        name: "John Doe".to_string(),
        ..Default::default()
    })
    .await?;

// Retrieve a customer
let customer = client
    .customers()
    .retrieve("cus_123")
    .await?;

println!("{customer:?}");
```

### Xử lý Đăng ký

Tạo và quản lý đăng ký định kỳ:

```rust theme={null}
let subscription = client
    .subscriptions()
    .create()
    .body(dodopayments::models::SubscriptionCreateParams {
        billing: dodopayments::models::BillingAddress {
            country: "US".to_string(),
            city: "San Francisco".to_string(),
            state: "CA".to_string(),
            street: "1 Market St".to_string(),
            zipcode: "94105".to_string(),
        },
        customer: dodopayments::models::CustomerRequest::AttachExisting(
            dodopayments::models::AttachExistingCustomer {
                customer_id: "cus_123".to_string(),
            },
        ),
        product_id: "pdt_456".to_string(),
        quantity: 1,
        ..Default::default()
    })
    .await?;

println!("{subscription:?}");
```

<Info>
  `billing` yêu cầu tối thiểu mã ISO hai chữ `country`. `customer` là định danh `CustomerRequest` — truyền `AttachExisting` cho một khách hàng hiện có hoặc `New` cho một khách hàng mới. Các trường số lượng như `product_price` ở đơn vị tiền tệ thấp nhất (ví dụ: `2500` = \$25.00 USD).
</Info>

## Thanh toán Dựa trên Sử dụng

### Thu thập Sự kiện Sử dụng

Theo dõi các sự kiện tùy chỉnh:

```rust theme={null}
let response = client
    .usage_events()
    .ingest()
    .body(dodopayments::models::UsageEventsIngestParams {
        events: vec![dodopayments::models::EventInput {
            event_id: "api_call_12345".to_string(),
            customer_id: "cus_abc123".to_string(),
            event_name: "api_request".to_string(),
            ..Default::default()
        }],
    })
    .await?;

println!("{response:?}");
```

### Danh sách Sự kiện Sử dụng

```rust theme={null}
let events = client
    .usage_events()
    .list()
    .query(serde_json::json!({
        "customer_id": "cus_abc123",
        "event_name": "api_request",
    }))
    .await?;

for event in &events.items {
    println!("{event:?}");
}
```

## Phân trang

List endpoints trả về một trang có kiểu mà trường `items` giữ trang kết quả hiện tại. Truyền trực tiếp mọi mục qua tất cả các trang với `into_stream`:

```rust theme={null}
use futures::StreamExt;

let mut items = Box::pin(
    client
        .payments()
        .list()
        .query(serde_json::json!({}))
        .await?
        .into_stream(),
);

while let Some(item) = items.next().await {
    let item = item?;
    println!("{item:?}");
}
```

Hoặc tiến từng trang một với `get_next_page`:

```rust theme={null}
let mut page = client
    .payments()
    .list()
    .query(serde_json::json!({}))
    .await?;

loop {
    for item in &page.items {
        println!("{item:?}");
    }
    match page.get_next_page().await? {
        Some(next) => page = next,
        None => break,
    }
}
```

## Xử lý Lỗi

Mỗi phương thức trả về một `dodopayments::Result<T>`. Các thất bại được đại diện bởi enum `dodopayments::Error`. Kiểm tra nó để xử lý lỗi API tách biệt khỏi lỗi truyền tải:

```rust theme={null}
let result = client
    .checkout_sessions()
    .create()
    .body(dodopayments::models::CheckoutSessionsCreateParams {
        product_cart: Some(vec![dodopayments::models::ProductItemReq {
            product_id: "product_id".to_string(),
            quantity: 1,
            addons: None,
            amount: None,
            credit_entitlements: None,
        }]),
        ..Default::default()
    })
    .await;

match result {
    Ok(value) => println!("{value:?}"),
    Err(dodopayments::Error::Api { status, message }) => {
        eprintln!("API returned {status}: {message}");
    }
    Err(err) => eprintln!("request failed: {err}"),
}
```

## Endpoint không Tài liệu

Để gọi một endpoint chưa được lộ ra dưới dạng phương thức có kiểu, sử dụng builder thấp `request`, áp dụng xác thực và URL nền tảng:

```rust theme={null}
let response = client
    .request(reqwest::Method::GET, "/some/path")
    .send()
    .await?;
```

## Tài nguyên

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-rust">
    Xem mã nguồn và đóng góp
  </Card>

  <Card title="Crates.io" icon="cube" href="https://crates.io/crates/dodopayments">
    Xem crate và các phiên bản đã công bố
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Tài liệu API hoàn chỉnh
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    Nhận trợ giúp và kết nối với các nhà phát triển
  </Card>
</CardGroup>

## Hỗ trợ

Cần hỗ trợ với Rust SDK?

* **Discord**: Tham gia [máy chủ cộng đồng](https://discord.gg/bYqAp4ayYh) của chúng tôi để được hỗ trợ thực tế
* **Email**: Liên hệ với chúng tôi tại [support@dodopayments.com](mailto:support@dodopayments.com)
* **GitHub**: Mở một issue trên [kho lưu trữ](https://github.com/dodopayments/dodopayments-rust/issues)

## Đóng góp

Chúng tôi hoan nghênh các đóng góp! Kiểm tra [hướng dẫn đóng góp](https://github.com/dodopayments/dodopayments-rust/blob/main/CONTRIBUTING.md) để bắt đầu.
