> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Didit C# 与 .NET SDK：KYC、AML 与交易集成

> Didit 官方 C# 与 .NET SDK 快速入门：异步强类型调用服务端 API，支持依赖注入、Webhook 验证与令牌校验。

Didit 官方的 C# 和 .NET 库。它面向 .NET 8 和 .NET Standard 2.0，每个 API 方法都是 `async`。在 .NET Framework 上，请使用 C# 11 或更高版本。各 SDK 的共同内容请参阅[服务端 SDK 概览](https://docs.didit.me/zh/integration/server-sdks/overview.md)。

## 安装

```bash theme={null}
dotnet add package Didit
```

如需 ASP.NET Core 依赖注入，还需添加 `Didit.Extensions.DependencyInjection`，并通过 `services.AddDidit()` 注册客户端。

这些包在 NuGet 上的名称是 [`Didit`](https://www.nuget.org/packages/Didit) 和 [`Didit.Extensions.DependencyInjection`](https://www.nuget.org/packages/Didit.Extensions.DependencyInjection)。源代码和更新日志位于 GitHub 上的 [didit-protocol/sdk-dotnet](https://github.com/didit-protocol/sdk-dotnet)。

## 配置客户端

`new DiditClient()` 会从环境变量中读取 `DIDIT_API_KEY`。如需覆盖该值，或设置应用级调用（案件、网络、监管报告）所需的组织和应用 ID，请传入 `DiditClientOptions`。请创建一个客户端并重复使用。

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient(new DiditClientOptions
{
    ApiKey = Environment.GetEnvironmentVariable("DIDIT_API_KEY"),
    OrganizationId = Environment.GetEnvironmentVariable("DIDIT_ORGANIZATION_ID"),
    ApplicationId = Environment.GetEnvironmentVariable("DIDIT_APPLICATION_ID"),
    Timeout = TimeSpan.FromSeconds(30),
    MaxRetries = 2,
});

// Options for a single call.
var decision = await client.Sessions.RetrieveDecisionAsync(
    "11111111-2222-3333-4444-555555555555",
    requestOptions: new RequestOptions { Timeout = TimeSpan.FromSeconds(5), MaxRetries = 0 });
Console.WriteLine(decision.Status);
```

必填的请求属性标有 `required`，缺少时将无法编译。您未设置的可选属性不会被发送。

## 创建会话

为某个工作流创建[验证会话](https://docs.didit.me/zh/sessions-api/create-session.md)，并将用户引导至该会话的 URL。

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient();

var session = await client.Sessions.CreateAsync(new SessionsCreateParams
{
    WorkflowId = "11111111-2222-3333-4444-555555555555",
    VendorData = "user-123",
    Callback = "https://example.com/verification/done",
});
Console.WriteLine(session.Url);
```

## 读取决策

用户完成验证后（或 Webhook 到达时），请[读取决策](https://docs.didit.me/zh/sessions-api/retrieve-session.md)。每项功能的结果都是一个列表，每个工作流节点对应一条记录。

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient();

var decision = await client.Sessions.RetrieveDecisionAsync("11111111-2222-3333-4444-555555555555");
Console.WriteLine(decision.Status);
foreach (var verification in decision.IdVerifications ?? Array.Empty<SessionDecisionIdVerifications>())
{
    Console.WriteLine(verification.Status);
}
```

## 验证 Webhook

传入未经修改的原始请求体，以及一个用于读取请求头的方法。`DiditWebhooks.Verify` 会对任何无效或过期的投递抛出 `WebhookVerificationException`，否则返回类型化的事件。

```csharp theme={null}
using System;
using Didit;

var secret = Environment.GetEnvironmentVariable("DIDIT_WEBHOOK_SECRET") ?? "";

int HandleWebhook(string rawBody, Func<string, string?> header)
{
    try
    {
        var evt = DiditWebhooks.Verify(rawBody, header, secret);
        if (evt is SessionStatusUpdatedEvent updated)
        {
            Console.WriteLine($"{updated.SessionId} {updated.Status}");
        }
        return 200;
    }
    catch (WebhookVerificationException error)
    {
        Console.WriteLine($"rejected: {error.Reason}");
        return 400;
    }
}
```

在 ASP.NET Core 最小 API 中，使用 `StreamReader` 读取请求体，并传入 `name => request.Headers[name].FirstOrDefault()`。轮换密钥期间，请同时传入两个密钥：`new[] { newSecret, oldSecret }`。事件和签名方案详见 [Webhooks](https://docs.didit.me/zh/integration/webhooks.md)。

## 交易筛查

将付款、提款或加密货币转账提交至[交易监控](https://docs.didit.me/zh/transaction-monitoring/overview.md)；响应中包含其状态和风险评分。

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient();

var transaction = await client.Transactions.CreateAsync(new TransactionsCreateParams
{
    TransactionId = "txn-1001",
    TransactionCategory = "finance",
    TransactionDetails = new()
    {
        Direction = "outbound",
        Amount = 1500,
        Currency = "EUR",
    },
    Subject = new()
    {
        EntityType = "individual",
        VendorData = "user-123",
        FullName = "Maria Garcia",
    },
});
Console.WriteLine($"{transaction.Status} {transaction.Score}");
```

## 验证 Authentication 令牌

`Authentication` 在您的后端检查您的 [Authentication](https://docs.didit.me/zh/authentication/overview.md) 签发方所签名的访问令牌，无需为每个请求调用 Didit。它还可以交换授权码、刷新令牌、检查和撤销会话，以及执行升级验证。

> [!NOTE]
>
> 令牌验证会针对您应用的签发方和签名密钥执行[在服务器上验证令牌](https://docs.didit.me/zh/authentication/tokens-and-jwks.md#在服务器上验证令牌)中的各项检查。

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Didit;

// The publishable key (pk_live_... or pk_test_...) carries your issuer URL.
var auth = Authentication.FromPublishableKey("pk_live_...");

async Task<string?> CurrentUserAsync(string accessToken)
{
    try
    {
        var claims = await auth.VerifyAccessTokenAsync(accessToken, audience: "your-application-id");
        return claims.Subject;
    }
    catch (TokenVerificationException error)
    {
        Console.WriteLine($"rejected: {error.Reason}");
        return null;
    }
}
```

## 错误

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient();

try
{
    await client.Sessions.RetrieveDecisionAsync("11111111-2222-3333-4444-555555555555");
}
catch (NotFoundException)
{
    Console.WriteLine("no such session");
}
catch (ApiStatusException error)
{
    Console.WriteLine($"{error.StatusCode} {error.RequestId}");
}
```

## 列表与文件

```csharp theme={null}
using System;
using Didit;

using var client = new DiditClient();

// Lists page through every result.
await foreach (var session in await client.Sessions.ListAsync(new SessionsListParams { Status = "Approved" }))
{
    Console.WriteLine(session.SessionId);
}

// Uploads take FileUpload.FromPath, FromBytes or FromStream.
var result = await client.IdVerification.VerifyAsync(new IdVerificationVerifyParams
{
    FrontImage = FileUpload.FromPath("id-front.jpg"),
    BackImage = FileUpload.FromPath("id-back.jpg"),
});
Console.WriteLine(result.IdVerification?.Status);
```

[API 参考](https://docs.didit.me/zh/api-reference/overview.md)中的服务端 endpoint 页面都提供了对应操作的 .NET 示例，但以下 endpoint 和字段除外：它们尚未包含在任何 1.0.1 版本中，具体列于[概览](https://docs.didit.me/zh/integration/server-sdks/overview.md)中。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.