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

# C# SDK

> Official Zentra library for .NET applications

The Zentra C# SDK provides convenient access to the Zentra API from .NET applications.

<Note>
  The checked-in C# wrapper currently exposes transfers, payments, virtual accounts, logs, and webhook verification. Cards, identity, customers, and wallet helpers are not exposed in the package shown in this repo.
</Note>

<CodeGroup>
  ```bash NuGet theme={null}
  dotnet add package Zentra
  ```

  ```bash Package Manager theme={null}
  Install-Package Zentra
  ```
</CodeGroup>

## Configuration

Initialize the client with your API key:

```csharp theme={null}
using Zentra;

var client = new ZentraClient(
    Environment.GetEnvironmentVariable("ZENTRA_SECRET_KEY")
);
```

## Resources

The checked-in C# package currently exposes:

* `client.Transfers`: Bank transfers
* `client.Payments`: Reviewed public charges, refunds, and saved payment tokens
* `client.VirtualAccounts`: Virtual bank accounts
* `client.Logs`: API request logs
* `client.Webhooks`: Webhook signature verification

## Examples

### Create a Transfer

```csharp theme={null}
try
{
    dynamic transfer = await client.Transfers.CreateAsync(new
    {
        amount = 500000,
        recipient_bank_code = "058",
        recipient_account_number = "0123456789",
        recipient_account_name = "Vendor Settlement Account",
        narration = "Vendor payout",
        reference = "TRF_12345",
        currency = "NGN"
    }, idempotencyKey: "idem_transfer_123");

    Console.WriteLine($"Queued transfer: {transfer.reference}");
}
catch (ZentraException e)
{
    Console.WriteLine($"Error: {e.Message}");
}
```

### Create Charge

```csharp theme={null}
dynamic charge = await client.Payments.ChargeAsync(new
{
    amount_minor = 500000, // ₦5,000.00
    currency = "NGN",
    email = "user@example.com",
    reference = "ORD_12345",
    capture_mode = "customer_action_required"
}, idempotencyKey: "idem_charge_123");

dynamic verified = await client.Payments.VerifyAsync((string)charge.reference);
Console.WriteLine($"Status: {verified.status}");
```

### Verify Webhook Signature (ASP.NET Core)

```csharp theme={null}
[HttpPost("/webhooks")]
public IActionResult HandleWebhook()
{
    using var reader = new StreamReader(Request.Body);
    var payload = reader.ReadToEnd();
    var signature = Request.Headers["X-Zentra-Signature"];

    if (client.Webhooks.VerifySignature(payload, signature, webhookSecret))
    {
        // Process webhook
        return Ok("Verified");
    }

    return BadRequest("Invalid signature");
}
```

## Error Handling

The SDK throws typed exceptions for API errors:

```csharp theme={null}
using Zentra.Exceptions;

try
{
    await client.Payments.VerifyAsync("INVALID_REF");
}
catch (ValidationException e)
{
    Console.WriteLine($"Bad request: {e.Message}");
}
catch (AuthenticationException)
{
    Console.WriteLine("Check your API key");
}
catch (ZentraException e)
{
    Console.WriteLine($"API error: {e.Message}");
}
```

## Dependency Injection

For ASP.NET Core, register the client in `Program.cs`:

```csharp theme={null}
builder.Services.AddSingleton(sp =>
    new ZentraClient(
        builder.Configuration["Zentra:ApiKey"],
        builder.Environment.IsProduction()
            ? "https://api.usezentra.com"
            : "https://sandbox.api.usezentra.com"
    )
);
```

## Source Code

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

  <Card title="NuGet" icon="microsoft" href="https://www.nuget.org/packages/Zentra">
    Download package
  </Card>
</CardGroup>
