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

> Integrasikan Dodo Payments ke dalam aplikasi Go Anda dengan SDK yang idiomatik dan berkinerja tinggi

SDK Go menyediakan antarmuka Go yang bersih dan idiomatik untuk mengintegrasikan Dodo Payments ke dalam aplikasi Anda. Ini menawarkan dukungan konteks, respons yang terketik dengan kuat, kemampuan middleware, dan aman untuk digunakan secara bersamaan.

## Instalasi

Instal SDK menggunakan modul Go:

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

Atau untuk mengunci ke versi tertentu:

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

<Info>
  SDK memerlukan Go 1.22 atau versi lebih baru, memanfaatkan fitur Go modern untuk kinerja optimal.
</Info>

## Memulai dengan Cepat

Inisialisasi klien dan buat sesi checkout pertama Anda:

```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>
  Selalu simpan kunci API Anda dengan aman menggunakan variabel lingkungan. Jangan pernah menuliskannya secara langsung (hardcode) dalam kode sumber Anda.
</Warning>

## Fitur Utama

<CardGroup cols={2}>
  <Card title="Context Support" icon="clock">
    Dukungan penuh untuk context.Context untuk pembatalan dan batas waktu
  </Card>

  <Card title="Strong Typing" icon="shield-check">
    Permintaan dan respons yang sangat bertipe untuk keamanan waktu kompilasi
  </Card>

  <Card title="Middleware" icon="layer-group">
    Dukungan middleware yang dapat diperluas untuk pencatatan (logging), metrik, dan logika kustom
  </Card>

  <Card title="Goroutine Safe" icon="bolt">
    Klien thread-safe yang dirancang untuk operasi bersamaan
  </Card>
</CardGroup>

## Konfigurasi

### Konteks dan Batas Waktu

Manfaatkan konteks Go untuk batas waktu dan pembatalan:

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

### Konfigurasi Ulang

Konfigurasi perilaku ulang otomatis:

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

## Operasi Umum

### Buat Sesi Checkout

Hasilkan sesi 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)
```

### Kelola Pelanggan

Buat dan ambil informasi pelanggan:

```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)
```

### Tangani Langganan

Buat dan kelola langganan berulang:

```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` memerlukan kode `Country` ISO dua huruf minimal. `Customer` adalah `CustomerRequestUnionParam` — gunakan `AttachExistingCustomerParam{CustomerID: ...}` untuk pelanggan yang ada atau `NewCustomerParam{Email: ..., Name: ...}` untuk pelanggan baru. `ProductPrice` adalah dalam denominasi mata uang terendah.
</Info>

## Penagihan Berbasis Penggunaan

### Memasukkan Peristiwa Penggunaan

Lacak peristiwa kustom:

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

### Daftar Peristiwa Penggunaan

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

## Penanganan Kesalahan

Ketika API mengembalikan kode status non-sukses, SDK akan mengembalikan kesalahan tipe `*dodopayments.Error`. Ini mengekspos `StatusCode`, `*http.Request` yang mendasari, dan `*http.Response`, serta JSON dari badan kesalahan. Gunakan pola `errors.As` untuk memeriksanya, dan bercabang pada `StatusCode` untuk menangani kasus khusus.

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

Tambahkan middleware kustom untuk logging atau metrik:

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

## Konkurensi

Klien aman untuk penggunaan bersamaan:

```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()
}
```

## Sumber Daya

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-go">
    Lihat kode sumber dan kontribusi
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Dokumentasi API lengkap
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    Dapatkan bantuan dan terhubung dengan pengembang
  </Card>

  <Card title="Report Issues" icon="bug" href="https://github.com/dodopayments/dodopayments-go/issues">
    Laporkan bug atau minta fitur
  </Card>
</CardGroup>

## Dukungan

Butuh bantuan dengan Go SDK?

* **Discord**: Bergabunglah dengan [server komunitas](https://discord.gg/bYqAp4ayYh) kami untuk dukungan real-time
* **Email**: Hubungi kami di [support@dodopayments.com](mailto:support@dodopayments.com)
* **GitHub**: Buat isu di [repository](https://github.com/dodopayments/dodopayments-go)

## Berkontribusi

Kami menyambut kontribusi! Periksa [panduan berkontribusi](https://github.com/dodopayments/dodopayments-go/blob/main/CONTRIBUTING.md) untuk memulai.
