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

> 비동기 우선, 강력한 타입의 SDK를 Tokio와 reqwest를 기반으로 하여 Rust 애플리케이션에 Dodo Payments를 통합합니다.

Rust SDK는 Rust로 작성된 애플리케이션에서 Dodo Payments REST API에 편리하고 비동기 우선 접근을 제공합니다. 강력한 타입의 요청 및 응답, 내장 페이지네이션 도우미, 그리고 구성 가능한 타임아웃 및 환경 설정 기능을 제공합니다.

## 설치

SDK를 Cargo로 프로젝트에 추가하세요:

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

또는 수동으로 이를 `Cargo.toml`에 추가하세요:

```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는 최적의 성능을 위해 최신 비동기 기능을 활용하며, Rust 1.75 이상이 필요합니다.
</Info>

## 빠른 시작

클라이언트는 기본적으로 API 키를 `DODO_PAYMENTS_API_KEY` 환경 변수에서 읽습니다. 클라이언트를 초기화하고 첫 체크아웃 세션을 만드세요:

```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>
  항상 환경 변수를 사용하여 API 키를 안전하게 저장하세요. 소스 코드에 하드코딩하지 마세요.
</Warning>

## 핵심 기능

<CardGroup cols={2}>
  <Card title="Async First" icon="bolt">
    Tokio 및 reqwest 기반으로 하여 `async`/`await` 전반의 지원 제공
  </Card>

  <Card title="Strong Typing" icon="shield-check">
    컴파일 타임 안전성을 위한 강력한 타입의 요청 및 응답
  </Card>

  <Card title="Auto-Pagination" icon="layer-group">
    페이지별로 모든 항목을 스트림하거나 한 페이지씩 진행
  </Card>

  <Card title="Configurable" icon="sliders">
    클라이언트별로 환경, 타임아웃, 기본 URL 설정 가능
  </Card>
</CardGroup>

## 구성

### 환경 변수

기본적으로, `Client::from_env()`는 API 키를 `DODO_PAYMENTS_API_KEY` 환경 변수에서 읽고, `DODO_PAYMENTS_BASE_URL`를 설정하지 않으면 기본 기본 URL을 사용합니다:

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

클라이언트를 명시적으로 구성할 수도 있습니다. `Client::new`는 `Result`를 반환하므로 `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(())
}
```

### 환경

| 이름          | 기본 URL                          |
| ----------- | ------------------------------- |
| `live_mode` | `https://live.dodopayments.com` |
| `test_mode` | `https://test.dodopayments.com` |

기본 기본 URL은 `https://live.dodopayments.com`입니다. 하드코딩된 URL 대신 `Environment` enum을 사용하여 다른 환경을 선택하세요:

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

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

기본이 아닌 환경을 목표로 하는 동안 `DODO_PAYMENTS_API_KEY`를 통해 API 키를 계속 읽도록 하려면 설정에서 이를 재정의하세요:

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

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

### 타임아웃

기본 요청 타임아웃은 30초입니다. 클라이언트별로 이를 재정의하세요:

```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)),
)?;
```

## 일반 작업

### 체크아웃 세션 생성

체크아웃 세션을 생성하세요:

```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:?}");
```

### 고객 관리

고객 정보를 생성하고 검색하세요:

```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:?}");
```

### 구독 관리

정기 구독을 생성 및 관리하세요:

```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`는 최소한 두 글자의 ISO `country` 코드가 필요합니다. `customer`는 `CustomerRequest` enum이며, 기존 고객의 경우 `AttachExisting`를, 새 고객의 경우 `New`를 전달하세요. `product_price` 같은 금액 필드는 최저 통화 단위로 작성됩니다. (예: `2500` = \$25.00 USD)
</Info>

## 사용량 기반 청구

### 사용량 이벤트 수집

사용자 정의 이벤트 추적:

```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:?}");
```

### 사용량 이벤트 목록

```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:?}");
}
```

## 페이지네이션

목록 엔드포인트는 `items` 필드에 현재 페이지의 결과를 보유한 유형 페이지를 반환합니다. `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:?}");
}
```

또는 `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,
    }
}
```

## 오류 처리

모든 메서드는 `dodopayments::Result<T>`를 반환합니다. 실패는 `dodopayments::Error` enum으로 표현됩니다. 이를 일치시켜 API 오류를 전송 오류와 구별하여 처리하세요:

```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}"),
}
```

## 문서화되지 않은 엔드포인트

아직 유형 메서드로 노출되지 않은 엔드포인트를 호출하려면 인증 및 기본 URL을 적용하는 저수준의 `request` 빌더를 사용하세요:

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

## 리소스

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-rust">
    소스 코드 보기 및 기여
  </Card>

  <Card title="Crates.io" icon="cube" href="https://crates.io/crates/dodopayments">
    게시된 크레이트와 버전 보기
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    전체 API 문서
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    도움 받기 및 개발자와 연결
  </Card>
</CardGroup>

## 지원

Rust SDK에 도움이 필요하십니까?

* **Discord**: 실시간 지원을 위해 [커뮤니티 서버](https://discord.gg/bYqAp4ayYh)에 참여하세요
* **Email**: [support@dodopayments.com](mailto:support@dodopayments.com)으로 문의하세요
* **GitHub**: [저장소](https://github.com/dodopayments/dodopayments-rust/issues)에서 이슈를 열어주세요

## 기여

기여를 환영합니다! [기여 가이드라인](https://github.com/dodopayments/dodopayments-rust/blob/main/CONTRIBUTING.md)을 확인하여 시작하세요.
