> For the complete documentation index, see [llms.txt](https://docs-sdk.crypto-chief.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-sdk.crypto-chief.com/processing/dotnet/authentication.md).

# Authentication

How the Crypto Chief .NET SDK authenticates and signs every request.

Every request to the Crypto Processing API is authenticated with two HTTP headers. **The SDK builds and sets them for you** — you only provide your Merchant ID and API key.

```
Merchant:  <your Merchant ID>
Signature: hex(md5(base64(canonicalJSON(body)) + API_KEY))
```

## Credentials

Both values come from your dashboard → **Integration** tab:

* **Merchant ID** — identifies your project.
* **API key** — the **signing secret**. It never leaves your server; the SDK uses it to compute the `Signature` and to verify incoming webhooks.

{% hint style="warning" %}
Treat the API key like a password. Load it from configuration / an environment variable and keep it server-side — never commit it or ship it in client apps.
{% endhint %}

## Initialize the client

Direct construction with credentials — simplest for console apps and tests:

```csharp
using CryptoChief.Processing;

var client = new CryptoChiefClient(
    Environment.GetEnvironmentVariable("MERCHANT_ID")!,
    Environment.GetEnvironmentVariable("API_KEY")!);
```

`CryptoChiefClient` is safe for concurrent use — create one and share it across the app.

## DI / ASP.NET Core

For ASP.NET Core, Worker Service, and any host with `IServiceCollection`, register the client so it gets a pooled `HttpClient` from `IHttpClientFactory`:

```csharp
using Microsoft.Extensions.DependencyInjection;

builder.Services.AddCryptoChief(o =>
{
    o.MerchantId = builder.Configuration["CryptoChief:MerchantId"]!;
    o.ApiKey     = builder.Configuration["CryptoChief:ApiKey"]!;
});
```

Or bind directly from a configuration section:

```csharp
builder.Services.AddCryptoChief(builder.Configuration.GetSection("CryptoChief"));
```

Then inject `CryptoChiefClient` wherever you need it:

```csharp
public class CheckoutService(CryptoChiefClient cryptoChief) { /* ... */ }
```

## Configuration options

```csharp
var options = new CryptoChiefClientOptions
{
    MerchantId        = "...",
    ApiKey            = "...",
    BaseUrl           = "https://api-processing.crypto-chief.com", // default
    Timeout           = TimeSpan.FromSeconds(60),
    MaxRetries        = 3,                                          // retry 5xx + transport
    InitialRetryDelay = TimeSpan.FromMilliseconds(200),
    MaxRetryDelay     = TimeSpan.FromSeconds(5),
    UserAgent         = "my-service/1.0",
};
options.LoadRsaPrivateKeyFromFile("./rsa_private.pem");              // optional — wallet decryption

var client = new CryptoChiefClient(options);
```

Every async method accepts a `CancellationToken` to abort the request and its retries:

```csharp
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await client.Payouts.InfoAsync(uuid, cts.Token);
```

{% hint style="info" %}
**Test mode** is a per-project toggle in the dashboard, not a separate base URL. Point a test-mode project's credentials at the same client.
{% endhint %}

## How signing works

The client canonicalizes the JSON body (recursively sorted keys, HTML-escaped `< > &`), base64-encodes it, appends your API key, and MD5-hashes the result to produce the `Signature`. The same scheme verifies [webhooks](/processing/dotnet/guides/webhooks.md), so one secret secures both directions.
