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

# Go SDK

> Official Zentra library for Go applications

The Zentra Go SDK provides convenient access to the Zentra API from Go applications.

<Note>
  The reviewed public HTTP surface for SDK integrations today is transfers, webhooks, virtual accounts, payments, cards, and tenant-enabled identity. Customers, wallets, and other higher-level helpers remain compatibility or draft surfaces unless your environment explicitly enables them.
</Note>

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

## Configuration

Initialize the client with your API key:

```go theme={null}
package main

import (
    "os"
    zentra "github.com/zentra/zentra-go"
)

func main() {
    client := zentra.NewClient(os.Getenv("ZENTRA_SECRET_KEY"))
}
```

For custom timeouts, retries, or a sandbox base URL:

```go theme={null}
client := zentra.NewClientWithConfig(zentra.Config{
    SecretKey:  os.Getenv("ZENTRA_SECRET_KEY"),
    BaseURL:    "https://sandbox.api.usezentra.com",
    Timeout:    30 * time.Second,
    MaxRetries: 3,
})
```

## Resources

Start new integrations from the reviewed resources first:

* `client.Transfers`: Bank transfers
* `client.Payments`: Reviewed public charges, refunds, and saved payment tokens
* `client.VirtualAccounts`: Virtual bank accounts
* `client.Webhooks`: Webhook handling

Compatibility helpers such as `client.Customers`, `client.Cards`, `client.Identity`, and `client.Wallets` may still exist in the package, but they should not be your default reviewed public API path unless your tenant explicitly enables them.

## Examples

### Create a Transfer

```go theme={null}
transfer, err := client.Transfers.CreateWithOptions(ctx, &zentra.CreateTransferParams{
    Amount:                 500000, // minor units
    RecipientBankCode:      "058",
    RecipientAccountNumber: "0123456789",
    RecipientAccountName:   "Vendor Settlement Account",
    Narration:              "Vendor payout",
    Reference:              "TRF_12345",
    Currency:               "NGN",
}, &zentra.MutationOptions{IdempotencyKey: "idem_transfer_123"})

if err != nil {
    log.Fatalf("Error: %v", err)
}

fmt.Printf("Queued transfer: %s (%s)\n", transfer.Reference, transfer.Status)
```

### Create Charge

```go theme={null}
charge, err := client.Payments.Charge(ctx, &zentra.CreateChargeParams{
    AmountMinor: 500000, // ₦5,000.00
    Currency:    "NGN",
    Email:       "user@example.com",
    Reference:   "ORD_12345",
    CaptureMode: zentra.ChargeCaptureModeCustomerActionRequired,
})

if err != nil {
    log.Fatalf("Error: %v", err)
}

verified, err := client.Payments.Verify(ctx, charge.Reference)
if err != nil {
    log.Fatalf("Verify error: %v", err)
}

fmt.Printf("Status: %s\n", verified.Status)
```

### Verify Webhook Signature

```go theme={null}
import "net/http"

func webhookHandler(w http.ResponseWriter, r *http.Request) {
    payload, _ := io.ReadAll(r.Body)
    signature := r.Header.Get("X-Zentra-Signature")

    if client.Webhooks.VerifySignature(payload, signature, webhookSecret) {
        // Process webhook
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("Verified"))
        return
    }

    w.WriteHeader(http.StatusBadRequest)
    w.Write([]byte("Invalid signature"))
}
```

## Error Handling

The SDK returns typed errors:

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

_, err := client.Payments.Verify(ctx, "INVALID_REF")
if err != nil {
    var apiErr *zentra.Error
    if errors.As(err, &apiErr) {
        switch apiErr.Type {
        case zentra.ErrorTypeInvalidRequest, zentra.ErrorTypeValidation:
            log.Printf("Bad request: %s", apiErr.Message)
        case zentra.ErrorTypeAuthentication:
            log.Print("Check your API key")
        default:
            log.Printf("API error: %s", apiErr.Message)
        }
    }
}
```

## Pagination

Iterate through paginated reviewed resources:

```go theme={null}
page, err := client.Transfers.List(ctx, &zentra.PaginationParams{
    Limit: 50,
})

if err != nil {
    log.Fatalf("List error: %v", err)
}

for _, transfer := range page.Data {
    fmt.Printf("Transfer: %s (%s)\n", transfer.Reference, transfer.Status)
}

if page.HasMore {
    fmt.Println("More transfers are available; pass StartingAfter to fetch the next page.")
}
```

## Source Code

<CardGroup cols={2}>
  <Card title="GitHub Repo" icon="github" href="https://github.com/zentra/zentra-go">
    View source code
  </Card>

  <Card title="pkg.go.dev" icon="golang" href="https://pkg.go.dev/github.com/zentra/zentra-go">
    Documentation
  </Card>
</CardGroup>
