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

# Go SDK：KYC、AML 与交易监控

> Didit 官方 Go SDK 快速入门：仅用标准库即可类型化调用服务端 API，并支持 Webhook 验证与 token 校验。

这是 Didit 官方提供的 Go 模块。它需要 Go 1.22 或更高版本，并且只使用标准库。各 SDK 的共同内容请参阅[服务端 SDK 概述](https://docs.didit.me/zh/integration/server-sdks/overview.md)。

## 安装

```bash theme={null}
go get github.com/didit-protocol/sdk-go
```

该模块位于 [pkg.go.dev 上的 `github.com/didit-protocol/sdk-go`](https://pkg.go.dev/github.com/didit-protocol/sdk-go)。源代码和更新日志位于 GitHub 上的 [didit-protocol/sdk-go](https://github.com/didit-protocol/sdk-go)。

包名为 `didit`。Webhook 位于 `github.com/didit-protocol/sdk-go/webhook`，Authentication 位于 `.../authentication`，客户端选项位于 `.../option`。

每个 [API 参考](https://docs.didit.me/zh/api-reference/overview.md)页面上的示例都是一个函数体：它使用标准库中的 `context`、`fmt` 和 `log`，以及本模块。

## 配置客户端

`didit.NewClient()` 会从环境变量中读取 `DIDIT_API_KEY`。您可以传入选项来覆盖它，或设置组织和应用 ID，这是应用级调用（案件、网络、监管报告）所需的。任何选项也可用于单次调用。

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/didit-protocol/sdk-go"
	"github.com/didit-protocol/sdk-go/option"
)

func main() {
	client := didit.NewClient(
		option.WithAPIKey(os.Getenv("DIDIT_API_KEY")),
		option.WithOrganizationID(os.Getenv("DIDIT_ORGANIZATION_ID")),
		option.WithApplicationID(os.Getenv("DIDIT_APPLICATION_ID")),
		option.WithTimeout(30*time.Second),
		option.WithMaxRetries(2),
	)

	// Options for a single call.
	decision, err := client.Sessions.RetrieveDecision(context.Background(), "11111111-2222-3333-4444-555555555555",
		didit.SessionsRetrieveDecisionParams{}, option.WithTimeout(5*time.Second))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(decision.Status)
}
```

可选的请求字段是 `didit.Opt` 值：使用 `didit.String`、`didit.Int`、`didit.Bool`、`didit.Float` 或 `didit.Some` 进行设置；不设置则不会发送任何内容。

## 创建会话

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

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/didit-protocol/sdk-go"
)

func main() {
	client := didit.NewClient()

	session, err := client.Sessions.Create(context.Background(), didit.SessionsCreateParams{
		WorkflowID: "11111111-2222-3333-4444-555555555555",
		VendorData: didit.String("user-123"),
		Callback:   didit.String("https://example.com/verification/done"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(session.URL)
}
```

## 读取决策

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

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/didit-protocol/sdk-go"
)

func main() {
	client := didit.NewClient()

	decision, err := client.Sessions.RetrieveDecision(context.Background(), "11111111-2222-3333-4444-555555555555",
		didit.SessionsRetrieveDecisionParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(decision.Status)
	for _, verification := range decision.IDVerifications {
		fmt.Println(verification.Status)
	}
}
```

## 验证 Webhook

传入原始请求体字节和请求头。对于任何不是有效且在有效期内的投递，`webhook.Verify` 都会返回 `*didit.WebhookVerificationError`；否则返回类型化的事件。

```go theme={null}
package main

import (
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	"github.com/didit-protocol/sdk-go"
	"github.com/didit-protocol/sdk-go/webhook"
)

func main() {
	secret := os.Getenv("DIDIT_WEBHOOK_SECRET")
	http.HandleFunc("POST /webhooks/didit", func(w http.ResponseWriter, r *http.Request) {
		body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 1<<20))
		if err != nil {
			http.Error(w, "bad body", http.StatusBadRequest)
			return
		}
		event, err := webhook.Verify(body, r.Header, secret)
		var invalid *didit.WebhookVerificationError
		if errors.As(err, &invalid) {
			http.Error(w, string(invalid.Reason), http.StatusBadRequest)
			return
		} else if err != nil {
			http.Error(w, "error", http.StatusInternalServerError)
			return
		}
		if e, ok := event.(*webhook.StatusUpdatedEvent); ok {
			fmt.Println(e.SessionID, e.Status)
		}
		w.WriteHeader(http.StatusOK)
	})
	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

轮换密钥期间，可使用 `webhook.WithSecrets` 添加旧密钥。事件和签名方案请参阅 [Webhook](https://docs.didit.me/zh/integration/webhooks.md)。

## 筛查交易

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

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/didit-protocol/sdk-go"
)

func main() {
	client := didit.NewClient()

	transaction, err := client.Transactions.Create(context.Background(), didit.TransactionsCreateParams{
		TransactionID:       "txn-1001",
		TransactionCategory: "finance",
		TransactionDetails: didit.TransactionsCreateParamsTransactionDetails{
			Direction: "outbound",
			Amount:    1500,
			Currency:  "EUR",
		},
		Subject: didit.TransactionsCreateParamsSubject{
			EntityType: didit.String("individual"),
			VendorData: "user-123",
			FullName:   "Maria Garcia",
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(transaction.Status, transaction.Score)
}
```

## 验证 Authentication token

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

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

```go theme={null}
package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	"github.com/didit-protocol/sdk-go"
	"github.com/didit-protocol/sdk-go/authentication"
)

func main() {
	// The publishable key (pk_live_... or pk_test_...) carries your issuer URL.
	auth, err := authentication.NewFromPublishableKey("pk_live_...", authentication.WithClientID("your-application-id"))
	if err != nil {
		log.Fatal(err)
	}

	claims, err := auth.VerifyAccessToken(context.Background(), "the bearer token")
	var invalid *didit.TokenVerificationError
	if errors.As(err, &invalid) {
		fmt.Println("rejected:", invalid.Reason)
		return
	} else if err != nil {
		log.Fatal(err)
	}
	fmt.Println(claims.Subject)
}
```

## 错误

```go theme={null}
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/didit-protocol/sdk-go"
)

func main() {
	client := didit.NewClient()

	_, err := client.Sessions.RetrieveDecision(context.Background(), "11111111-2222-3333-4444-555555555555",
		didit.SessionsRetrieveDecisionParams{})
	var notFound *didit.NotFoundError
	var status *didit.APIStatusError
	switch {
	case errors.As(err, &notFound):
		fmt.Println("no such session")
	case errors.As(err, &status):
		fmt.Println(status.StatusCode, status.RequestID, status.Body)
	case err != nil:
		fmt.Println("no response:", err)
	}
}
```

## 列表与文件

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/didit-protocol/sdk-go"
)

func main() {
	ctx := context.Background()
	client := didit.NewClient()

	// Lists page through every result.
	iter := client.Sessions.ListAutoPaging(ctx, didit.SessionsListParams{Status: didit.String("Approved")})
	for iter.Next() {
		fmt.Println(iter.Current().SessionID)
	}
	if err := iter.Err(); err != nil {
		log.Fatal(err)
	}

	// Uploads take didit.FileFromPath, FileFromBytes or FileFromReader.
	result, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{
		FrontImage: didit.FileFromPath("id-front.jpg"),
		BackImage:  didit.Some(didit.FileFromPath("id-back.jpg")),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.IDVerification.Status)
}
```

## Go SDK 尚未支持的端点

Go 1.0.1 是在这些端点加入 API 之前生成的，因此它没有对应的方法，这些端点的页面也没有 Go 示例：

* [验证地址](https://docs.didit.me/zh/standalone-apis/address-validation.md)
* [批量删除交易](https://docs.didit.me/zh/management-api/transactions/delete.md)
* Travel Rule 网络：[获取网络](https://docs.didit.me/zh/management-api/travel-rule/get-networks.md)、[申请访问网络](https://docs.didit.me/zh/management-api/travel-rule/request-network.md)，以及[获取](https://docs.didit.me/zh/management-api/travel-rule/get-network-questionnaire.md)、[保存](https://docs.didit.me/zh/management-api/travel-rule/update-network-questionnaire.md)或[提交](https://docs.didit.me/zh/management-api/travel-rule/submit-network-questionnaire.md)网络问卷
* Travel Rule 钱包证明：[列出截图形式的钱包证明](https://docs.didit.me/zh/management-api/travel-rule/list-wallet-proofs.md)，以及[批准或拒绝其中一项](https://docs.didit.me/zh/management-api/travel-rule/decide-wallet-proof.md)
* Google Wallet（目前没有任何 1.0.1 版本提供）：[发起 Google Wallet 验证](https://docs.didit.me/zh/api-reference/digital-id-wallets/google-wallet.md)和[提交钱包响应](https://docs.didit.me/zh/standalone-apis/digital-id-wallet-response.md)

它也无法发送以下较新的请求字段：

* 在[创建会话](https://docs.didit.me/zh/sessions-api/create-session.md)时使用的 `biometric_consent`、`tags` 和 `user_state`
* 在[更新 Webhook 配置](https://docs.didit.me/zh/management-api/webhook/update-config.md)时使用的 `biometric_consent_mode`
* 在[更新 Travel Rule 转账](https://docs.didit.me/zh/management-api/travel-rule/update-transfer.md)时使用的 `beneficiary_vasp`
* [删除已定稿报告](https://docs.didit.me/zh/management-api/regulatory-reports/delete.md)所需的 `confirm_delete`
* 没有任何 1.0.1 版本包含的 16 个较新的数据库核验字段

在更高版本的 Go SDK 添加这些功能之前，请按照每个页面的 cURL 请求示例，通过 HTTP 调用这些端点。[API 参考](https://docs.didit.me/zh/api-reference/overview.md)中其他每个服务端端点页面都为其操作提供了 Go 示例。


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