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

# C#

> 将 Dodo Payments 集成到您的 .NET 应用程序中，支持现代的 async/await

C# SDK提供了从使用C#编写的应用程序方便访问Dodo Payments REST API的方式。它提供了基于async Task的API，具备强类型、自动重试和全面的错误处理功能。

<Info>
  C# SDK 当前处于测试阶段。我们正在积极改进，欢迎您的反馈。
</Info>

从[NuGet](https://www.nuget.org/packages/DodoPayments.Client)安装该包：

使用 .NET CLI 安装 SDK：

<Info>
  该SDK需要.NET 8.0或更高版本。它可以与ASP.NET Core、控制台应用程序和其他.NET项目类型一起使用。
</Info>

<Info>
  该 SDK 需要 .NET Standard 2.0 或更高版本。它适用于 ASP.NET Core、控制台应用程序以及其他 .NET 项目类型。
</Info>

## 快速开始

初始化客户端并创建结账会话：

```csharp theme={null}
using System;
using DodoPayments.Client;
using DodoPayments.Client.Models.CheckoutSessions;

// Configured using the DODO_PAYMENTS_API_KEY and DODO_PAYMENTS_BASE_URL environment variables
DodoPaymentsClient client = new();

CheckoutSessionCreateParams parameters = new()
{
    ProductCart =
    [
        new()
        {
            ProductID = "product_id",
            Quantity = 1,
        },
    ],
};

var checkoutSessionResponse = await client.CheckoutSessions.Create(parameters);

Console.WriteLine(checkoutSessionResponse.SessionId);
```

<Warning>
  务必使用环境变量、用户机密或 Azure Key Vault 安全地存储您的 API 密钥。切勿将其硬编码在源代码中或提交到版本控制。
</Warning>

## 核心功能

<CardGroup cols={2}>
  <Card title="Async/Await" icon="bolt">
    适用于非阻塞操作的完整基于 Task 的异步 API
  </Card>

  <Card title="Strong Typing" icon="shield-check">
    针对瞬时错误的指数退避自动重试
  </Card>

  <Card title="Smart Retries" icon="repeat">
    内置异常层次结构以进行精确的错误管理
  </Card>

  <Card title="Configuration" icon="gear">
    通过环境变量或 appsettings.json 进行简单配置
  </Card>
</CardGroup>

## 配置

```bash .env theme={null}
DODO_PAYMENTS_API_KEY=your_api_key_here
```

```csharp theme={null}
// Automatically reads from environment variables
DodoPaymentsClient client = new();
```

| 属性            | 环境变量                        | 必需    | 默认值                               |
| ------------- | --------------------------- | ----- | --------------------------------- |
| `BearerToken` | `DODO_PAYMENTS_API_KEY`     | true  | -                                 |
| `WebhookKey`  | `DODO_PAYMENTS_WEBHOOK_KEY` | false | -                                 |
| `BaseUrl`     | `DODO_PAYMENTS_BASE_URL`    | true  | `"https://live.dodopayments.com"` |

### 手动配置

```csharp theme={null}
DodoPaymentsClient client = new() { BearerToken = "My Bearer Token" };
```

### 环境

在实时模式和测试模式之间切换：

```csharp theme={null}
using DodoPayments.Client.Core;

DodoPaymentsClient client = new() { BaseUrl = EnvironmentUrl.TestMode };
```

### 重试

SDK默认情况下会自动重试2次，并应用指数退避。它会在连接错误以及状态码408、409、429和5xx时进行重试。

```csharp theme={null}
// Custom retry count
DodoPaymentsClient client = new() { MaxRetries = 3 };
```

### 超时

请求默认在1分钟后超时。

```csharp theme={null}
DodoPaymentsClient client = new() { Timeout = TimeSpan.FromSeconds(30) };
```

### 每请求覆盖

使用`WithOptions`临时修改单个请求的配置：

```csharp theme={null}
var response = await client
    .WithOptions(options => options with
    {
        Timeout = TimeSpan.FromSeconds(10),
        MaxRetries = 5,
    })
    .CheckoutSessions.Create(parameters);
```

## 常用操作

### 创建结帐会话

```csharp theme={null}
var parameters = new CheckoutSessionCreateParams
{
    ProductCart =
    [
        new()
        {
            ProductID = "prod_123",
            Quantity = 1
        }
    ],
    ReturnUrl = "https://yourdomain.com/return"
};

var session = await client.CheckoutSessions.Create(parameters);
Console.WriteLine($"Checkout URL: {session.CheckoutUrl}");
```

### 管理客户

```csharp theme={null}
// Create a customer
var customer = await client.Customers.Create(new CustomerCreateParams
{
    Email = "customer@example.com",
    Name = "John Doe"
});

// Retrieve customer
var retrieved = await client.Customers.Retrieve("cus_123");
Console.WriteLine($"Customer: {retrieved.Name} ({retrieved.Email})");
```

### 处理订阅

```csharp theme={null}
using DodoPayments.Client.Models.Payments;
using DodoPayments.Client.Models.Subscriptions;

// Create a subscription
var subscription = await client.Subscriptions.Create(new SubscriptionCreateParams
{
    Billing = new BillingAddress
    {
        Country = "US",
        City = "San Francisco",
        State = "CA",
        Street = "1 Market St",
        Zipcode = "94105",
    },
    Customer = new AttachExistingCustomer { CustomerID = "cus_123" },
    ProductID = "pdt_456",
    Quantity = 1,
});

// Charge an on-demand subscription
// ProductPrice is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
var charge = await client.Subscriptions.Charge(
    subscription.SubscriptionId,
    new SubscriptionChargeParams { ProductPrice = 2500 }
);
```

<Info>
  `Billing` 需要至少两个字母的 ISO `Country` 代码。 使用 `AttachExistingCustomer` 来附加现有客户，或使用 `NewCustomer` 来创建一个。 `ProductPrice` 以最低货币面值表示。
</Info>

## 错误处理

SDK 根据 HTTP 状态码抛出特定异常。所有 4xx 错误都继承自 `DodoPayments4xxException`。

| 状态     | 异常                                          |
| ------ | ------------------------------------------- |
| 400    | `DodoPaymentsBadRequestException`           |
| 401    | `DodoPaymentsUnauthorizedException`         |
| 403    | `DodoPaymentsForbiddenException`            |
| 404    | `DodoPaymentsNotFoundException`             |
| 422    | `DodoPaymentsUnprocessableEntityException`  |
| 429    | `DodoPaymentsRateLimitException`            |
| 5xx    | `DodoPayments5xxException`                  |
| others | `DodoPaymentsUnexpectedStatusCodeException` |

其他异常类型:

* `DodoPaymentsIOException`: I/O 网络错误
* `DodoPaymentsInvalidDataException`: 解析数据失败
* `DodoPaymentsException`: 所有异常的基类

## 分页

### 自动分页

使用 `Paginate` 方法遍历所有页面的所有结果，该方法返回一个 `IAsyncEnumerable`:

```csharp theme={null}
var page = await client.Payments.List(parameters);
await foreach (var item in page.Paginate())
{
    Console.WriteLine(item);
}
```

### 手动分页

```csharp theme={null}
var page = await client.Payments.List();
while (true)
{
    foreach (var item in page.Items)
    {
        Console.WriteLine(item);
    }
    if (!page.HasNext())
    {
        break;
    }
    page = await page.Next();
}
```

## ASP.NET Core 集成

在你的 DI 容器中注册客户端:

```csharp Program.cs theme={null}
using DodoPayments.Client;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<DodoPaymentsClient>(sp =>
{
    var configuration = sp.GetRequiredService<IConfiguration>();
    return new DodoPaymentsClient
    {
        BearerToken = configuration["DodoPayments:ApiKey"]
    };
});

var app = builder.Build();
app.Run();
```

```json appsettings.json theme={null}
{
  "DodoPayments": {
    "ApiKey": "your_api_key_here"
  }
}
```

<Tip>
  对于开发，请使用 [用户秘密](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets) 而不是将密钥存储在 `appsettings.json` 中。

  ```bash theme={null}
  dotnet user-secrets init
  dotnet user-secrets set "DodoPayments:ApiKey" "your_api_key_here"
  ```
</Tip>

## 资源

<CardGroup cols={2}>
  <Card title="NuGet Package" icon="box" href="https://www.nuget.org/packages/DodoPayments.Client">
    在 NuGet Gallery 上查看包
  </Card>

  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-csharp">
    查看源代码并贡献
  </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>

## 支持

需要 C# SDK 帮助吗？

* **Discord**: 加入我们的[社区服务器](https://discord.gg/bYqAp4ayYh)以获得实时支持
* **Email**: 联系我们：[support@dodopayments.com](mailto:support@dodopayments.com)
* **GitHub**: 在[仓库](https://github.com/dodopayments/dodopayments-csharp)上打开问题
