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

# Go

> Tích hợp Dodo Payments vào các ứng dụng Go của bạn với một SDK hiệu suất cao và theo phong cách.

SDK Go cung cấp một giao diện Go sạch sẽ và theo phong cách cho việc tích hợp Dodo Payments vào các ứng dụng của bạn. Nó hỗ trợ ngữ cảnh, phản hồi kiểu mạnh, khả năng middleware và an toàn cho việc sử dụng đồng thời.

## Cài đặt

Cài đặt SDK bằng cách sử dụng Go modules:

```bash theme={null}
go get github.com/dodopayments/dodopayments-go
```

Hoặc để gán cho một phiên bản cụ thể:

```bash theme={null}
go get -u 'github.com/dodopayments/dodopayments-go@v1.97.3'
```

<Info>
  SDK yêu cầu Go 1.22 hoặc các phiên bản mới hơn, tận dụng các tính năng hiện đại của Go để đạt hiệu suất tối ưu.
</Info>

## Bắt đầu nhanh

Khởi tạo client và tạo phiên checkout đầu tiên của bạn:

```go theme={null}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/dodopayments/dodopayments-go"
	"github.com/dodopayments/dodopayments-go/option"
)

func main() {
	client := dodopayments.NewClient(
		option.WithBearerToken("My Bearer Token"), // defaults to os.LookupEnv("DODO_PAYMENTS_API_KEY")
		option.WithEnvironmentTestMode(),          // defaults to option.WithEnvironmentLiveMode()
	)
	
	checkoutSessionResponse, err := client.CheckoutSessions.New(context.TODO(), dodopayments.CheckoutSessionNewParams{
		CheckoutSessionRequest: dodopayments.CheckoutSessionRequestParam{
			ProductCart: dodopayments.F([]dodopayments.ProductItemReqParam{{
				ProductID: dodopayments.F("product_id"),
				Quantity:  dodopayments.F(int64(1)),
			}}),
		},
	})
	if err != nil {
		panic(err.Error())
	}
	fmt.Printf("Session ID: %s\n", checkoutSessionResponse.SessionID)
}
```

<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.
</Warning>

## Tính năng chính

<CardGroup cols={2}>
  <Card title="Context Support" icon="clock">
    Hỗ trợ đầy đủ context.Context cho việc hủy bỏ và giới hạn thời gian
  </Card>

  <Card title="Strong Typing" icon="shield-check">
    Các yêu cầu và phản hồi kiểu mạnh để đảm bảo an toàn tại thời gian biên dịch
  </Card>

  <Card title="Middleware" icon="layer-group">
    Hỗ trợ middleware mở rộng cho ghi nhật ký, số liệu và logic tùy chỉnh
  </Card>

  <Card title="Goroutine Safe" icon="bolt">
    Client an toàn luồng được thiết kế cho các thao tác đồng thời
  </Card>
</CardGroup>

## Cấu hình

### Context và Thời gian chờ

Tận dụng context của Go cho thời gian chờ và hủy bỏ:

```go theme={null}
import (
	"context"
	"time"
	
	"github.com/dodopayments/dodopayments-go"
	"github.com/dodopayments/dodopayments-go/option"
)

// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

payment, err := client.Payments.New(ctx, dodopayments.PaymentNewParams{
	Billing: dodopayments.F(dodopayments.BillingAddressParam{
		Country: dodopayments.F(dodopayments.CountryCodeUs),
		City:    dodopayments.F("San Francisco"),
		State:   dodopayments.F("CA"),
		Street:  dodopayments.F("1 Market St"),
		Zipcode: dodopayments.F("94105"),
	}),
	Customer: dodopayments.F[dodopayments.CustomerRequestUnionParam](
		dodopayments.AttachExistingCustomerParam{
			CustomerID: dodopayments.F("cus_123"),
		},
	),
	ProductCart: dodopayments.F([]dodopayments.OneTimeProductCartItemParam{{
		ProductID: dodopayments.F("pdt_456"),
		Quantity:  dodopayments.F(int64(1)),
	}}),
})
if err != nil {
	if ctx.Err() == context.DeadlineExceeded {
		log.Println("Request timed out")
	} else {
		log.Fatal(err)
	}
}
```

### Cấu hình Retry

Cấu hình hành vi tự động thử lại:

```go theme={null}
// Configure default for all requests (default is 2)
client := dodopayments.NewClient(
	option.WithMaxRetries(0), // disable retries
)

// Override per-request
client.CheckoutSessions.New(
	context.TODO(),
	dodopayments.CheckoutSessionNewParams{
		CheckoutSessionRequest: dodopayments.CheckoutSessionRequestParam{
			ProductCart: dodopayments.F([]dodopayments.ProductItemReqParam{{
				ProductID: dodopayments.F("product_id"),
				Quantity:  dodopayments.F(int64(0)),
			}}),
		},
	},
	option.WithMaxRetries(5),
)
```

## Các thao tác phổ biến

### Tạo một phiên Checkout

Tạo một phiên checkout:

```go theme={null}
session, err := client.CheckoutSessions.New(ctx, dodopayments.CheckoutSessionNewParams{
	CheckoutSessionRequest: dodopayments.CheckoutSessionRequestParam{
		ProductCart: dodopayments.F([]dodopayments.ProductItemReqParam{{
			ProductID: dodopayments.F("prod_123"),
			Quantity:  dodopayments.F(int64(1)),
		}}),
		ReturnURL: dodopayments.F("https://yourdomain.com/return"),
	},
})
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Checkout URL: %s\n", session.CheckoutURL)
```

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

Tạo và truy xuất thông tin khách hàng:

```go theme={null}
// Create a customer
customer, err := client.Customers.New(ctx, dodopayments.CustomerNewParams{
	Email: dodopayments.F("customer@example.com"),
	Name:  dodopayments.F("John Doe"),
	Metadata: dodopayments.F(map[string]string{
		"user_id": "12345",
	}),
})
if err != nil {
	log.Fatal(err)
}

// Retrieve customer
customer, err = client.Customers.Get(ctx, "cus_123")
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Customer: %s (%s)\n", customer.Name, customer.Email)
```

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

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

```go theme={null}
import "time"

// Create a subscription
subscription, err := client.Subscriptions.New(ctx, dodopayments.SubscriptionNewParams{
	Billing: dodopayments.F(dodopayments.BillingAddressParam{
		Country: dodopayments.F(dodopayments.CountryCodeUs),
		City:    dodopayments.F("San Francisco"),
		State:   dodopayments.F("CA"),
		Street:  dodopayments.F("1 Market St"),
		Zipcode: dodopayments.F("94105"),
	}),
	Customer: dodopayments.F[dodopayments.CustomerRequestUnionParam](
		dodopayments.AttachExistingCustomerParam{
			CustomerID: dodopayments.F("cus_123"),
		},
	),
	ProductID: dodopayments.F("pdt_456"),
	Quantity:  dodopayments.F(int64(1)),
})
if err != nil {
	log.Fatal(err)
}

// Charge an on-demand subscription
// ProductPrice is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
chargeResponse, err := client.Subscriptions.Charge(ctx, subscription.SubscriptionID,
	dodopayments.SubscriptionChargeParams{
		ProductPrice: dodopayments.F(int64(2500)),
	},
)
if err != nil {
	log.Fatal(err)
}

// Get usage history (for metered subscriptions)
usageHistory, err := client.Subscriptions.GetUsageHistory(
	ctx,
	subscription.SubscriptionID,
	dodopayments.SubscriptionGetUsageHistoryParams{
		StartDate: dodopayments.F(time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)),
		EndDate:   dodopayments.F(time.Date(2024, 3, 31, 23, 59, 59, 0, time.UTC)),
	},
)
if err != nil {
	log.Fatal(err)
}
```

<Info>
  `Billing` yêu cầu tối thiểu mã ISO hai chữ cái `Country`. `Customer` là một `CustomerRequestUnionParam` — truyền `AttachExistingCustomerParam{CustomerID: ...}` cho một khách hàng hiện tại hoặc `NewCustomerParam{Email: ..., Name: ...}` cho một khách hàng mới. `ProductPrice` là đơn vị tiền tệ mệnh giá thấp nhất.
</Info>

## Thanh Toán Dựa Trên Mức Sử Dụng

### Xử Lý Sự Kiện Sử Dụng

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

```go theme={null}
import "github.com/dodopayments/dodopayments-go"

response, err := client.UsageEvents.Ingest(ctx, dodopayments.UsageEventIngestParams{
	Events: dodopayments.F([]dodopayments.EventInputParam{{
		EventID:    dodopayments.F("api_call_12345"),
		CustomerID: dodopayments.F("cus_abc123"),
		EventName:  dodopayments.F("api_request"),
		Timestamp:  dodopayments.F(time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC)),
	}}),
})
if err != nil {
	log.Fatal(err)
}
```

### Liệt Kê Sự Kiện Sử Dụng

```go theme={null}
// List events with filters
params := dodopayments.UsageEventListParams{
	CustomerID: dodopayments.F("cus_abc123"),
	EventName:  dodopayments.F("api_request"),
}

events, err := client.UsageEvents.List(ctx, params)
if err != nil {
	log.Fatal(err)
}

for _, event := range events.Items {
	fmt.Printf("Event %s: %s at %s\n", event.EventID, event.EventName, event.Timestamp)
}
```

## Xử Lý Lỗi

Khi API trả về mã trạng thái không thành công, SDK sẽ trả về lỗi thuộc loại
`*dodopayments.Error`. Nó cung cấp
`StatusCode`, nguồn gốc
`*http.Request` và
`*http.Response`, và JSON của nội dung lỗi. Sử dụng mẫu
`errors.As` để kiểm tra và dựa vào
`StatusCode` để xử lý các trường hợp cụ thể:

```go theme={null}
payment, err := client.Payments.New(ctx, dodopayments.PaymentNewParams{
	Billing: dodopayments.F(dodopayments.BillingAddressParam{
		Country: dodopayments.F(dodopayments.CountryCodeUs),
		City:    dodopayments.F("San Francisco"),
		State:   dodopayments.F("CA"),
		Street:  dodopayments.F("1 Market St"),
		Zipcode: dodopayments.F("94105"),
	}),
	Customer: dodopayments.F[dodopayments.CustomerRequestUnionParam](
		dodopayments.AttachExistingCustomerParam{CustomerID: dodopayments.F("cus_123")},
	),
	ProductCart: dodopayments.F([]dodopayments.OneTimeProductCartItemParam{{
		ProductID: dodopayments.F("pdt_456"),
		Quantity:  dodopayments.F(int64(1)),
	}}),
})
if err != nil {
	var apiErr *dodopayments.Error
	if errors.As(err, &apiErr) {
		fmt.Printf("Status Code: %d\n", apiErr.StatusCode)
		fmt.Println(string(apiErr.DumpResponse(true))) // Serialized HTTP response

		// Handle specific status codes
		switch apiErr.StatusCode {
		case 401:
			log.Println("Authentication failed")
		case 422:
			log.Println("Invalid request parameters")
		case 429:
			log.Println("Rate limit exceeded")
		default:
			log.Printf("API error: %s", apiErr.Error())
		}
	} else {
		log.Fatal(err)
	}
}
```

## Middleware

Thêm middleware tùy chỉnh để ghi nhật ký hoặc thông số:

```go theme={null}
func Logger(req *http.Request, next option.MiddlewareNext) (res *http.Response, err error) {
	// Before the request
	start := time.Now()
	log.Printf("Request: %s %s\n", req.Method, req.URL)

	// Forward the request to the next handler
	res, err = next(req)

	// After the request
	end := time.Now()
	log.Printf("Response: %d in %v\n", res.StatusCode, end.Sub(start))

	return res, err
}

client := dodopayments.NewClient(
	option.WithMiddleware(Logger),
)
```

## Tính Đồng Thời

Khách hàng an toàn khi sử dụng đồng thời:

```go theme={null}
package main

import (
	"context"
	"sync"
	"log"

	"github.com/dodopayments/dodopayments-go"
)

func main() {
	client := dodopayments.NewClient()
	
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(idx int) {
			defer wg.Done()
			
			payment, err := client.Payments.New(context.Background(), dodopayments.PaymentNewParams{
				Billing: dodopayments.F(dodopayments.BillingAddressParam{
					Country: dodopayments.F(dodopayments.CountryCodeUs),
					City:    dodopayments.F("San Francisco"),
					State:   dodopayments.F("CA"),
					Street:  dodopayments.F("1 Market St"),
					Zipcode: dodopayments.F("94105"),
				}),
				Customer: dodopayments.F[dodopayments.CustomerRequestUnionParam](
					dodopayments.AttachExistingCustomerParam{CustomerID: dodopayments.F("cus_123")},
				),
				ProductCart: dodopayments.F([]dodopayments.OneTimeProductCartItemParam{{
					ProductID: dodopayments.F("pdt_456"),
					Quantity:  dodopayments.F(int64(1)),
				}}),
			})
			if err != nil {
				log.Printf("Failed to create payment %d: %v", idx, err)
				return
			}
			
			log.Printf("Created payment %d: %s", idx, payment.PaymentID)
		}(i)
	}
	
	wg.Wait()
}
```

## Tài Nguyên

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

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Tài liệu API đầy đủ
  </Card>

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

  <Card title="Report Issues" icon="bug" href="https://github.com/dodopayments/dodopayments-go/issues">
    Báo cáo lỗi hoặc yêu cầu tính năng
  </Card>
</CardGroup>

## Hỗ Trợ

Cần giúp đỡ với Go SDK?

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

## Đóng Góp

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