SDK · Compense.Sdk
.NET
Compense.Sdk 1.1.0: installation, client, ASP.NET Core and IHttpClientFactory integration, configuration, errors, pagination with IAsyncEnumerable, webhook verification and testing.
On this page
| NuGet package | Compense.Sdk |
| Version | 1.1.0 · API v1 |
| Targets | net8.0 and netstandard2.0 (.NET Framework 4.6.2+, .NET 6/7/8+, Mono) |
| Dependencies | System.Text.Json, Microsoft.Extensions.Http, Microsoft.Extensions.Logging.Abstractions, Microsoft.Extensions.Options.ConfigurationExtensions |
| Repository | Appiasoft/compense-saas-sdk-dotnet · guides in docs/modulos/ · examples in examples/ (console and webhook receiver) |
Install #
dotnet add package Compense.Sdk --version 1.1.0Client #
using Compense.Sdk;
using Compense.Sdk.Models;
using var client = new CompenseClient(
Environment.GetEnvironmentVariable("COMPENSE_API_KEY")!, CompenseEnvironment.Sandbox);
// With every option:
var configured = new CompenseClient(new CompenseClientOptions
{
ApiKey = "cmp_...",
Environment = CompenseEnvironment.Sandbox, // Production (default) | Sandbox | Dev
BaseUrl = null, // another URL; takes precedence over Environment
Timeout = TimeSpan.FromSeconds(30),
Retry = new RetryOptions { MaxAttempts = 3, RetryWrites = false },
UserAgent = "horizonte-erp/2.0",
});You can also use new CompenseClient(httpClient, options) with your own HttpClient (the SDK doesn’t
dispose it and ignores its BaseAddress).
ASP.NET Core #
// Program.cs
builder.Services.AddCompense(builder.Configuration.GetSection("Compense"));
// or: builder.Services.AddCompense(o => { o.ApiKey = "..."; o.Environment = CompenseEnvironment.Sandbox; });
app.MapGet("/saldo/{document}", async (string document, CompenseClient compense) =>
(await compense.Wallet.BalanceAsync(document)).Available.ToString());{
"Compense": {
"Environment": "Sandbox",
"Timeout": "00:00:30",
"Retry": { "MaxAttempts": 3, "RetryWrites": false }
}
}Provide the key through an environment variable (Compense__ApiKey=cmp_...) or a user secret.
AddCompense registers a typed client with IHttpClientFactory (pooled handlers, DNS refresh) and
returns the IHttpClientBuilder so you can add your own handlers (for example, telemetry or
high-value signing). Deprecation warnings go to ILogger (category Compense.Sdk).
Conventions #
PascalCasemethods with theAsyncsuffix, aCancellationTokenon all of them and nullable annotations:client.Wallet.Bills.PayAsync(document, billerCode, reference, amount, idempotencyKey: "...").- Writes →
Transaction(Datais aJsonObject); reads → models (Balance,Resolution,Page,OffsetPage…) orJsonObject; every model keeps the body in.Raw. To map to your own type:tx.Data.Deserialize<MiDto>(CompenseJson.SerializerOptions). - Amounts:
Amount, with implicit conversion fromint,long,decimalorstring. - Decisions:
Decisions.Approve/Decisions.Reject. Affiliates:new AffiliateRef("CC", "1032456789"). - Free-form fields:
IReadOnlyDictionary<string, object?>(text values, numbers,Amount,JsonNode, dictionaries or objects, serialized insnake_case).
Errors #
CompenseException › CompenseConfigException and CompenseApiException › AuthException,
NotFoundException, IdempotencyConflictException, ValidationException (Errors),
RateLimitException (RetryAfter as TimeSpan?), UpstreamException, ServerException.
Properties: Status, Title, Detail, TraceId, Problem. Network failures are the usual
HttpRequestException / TaskCanceledException.
Pagination #
Every paginated list has an …AutoPagingAsync twin that returns IAsyncEnumerable<JsonObject> and
fetches pages on demand:
await foreach (var delivery in client.Webhooks.Deliveries.ListAutoPagingAsync(status: "failed"))
{
await client.Webhooks.Deliveries.ReplayAsync((string)delivery["id"]!);
}Webhooks #
using Compense.Sdk.Webhooks;
WebhookEvent evt = CompenseWebhooks.Verify(rawBodyBytes, request.Headers, new[] { newSecret, oldSecret });
// evt.EventId, evt.Event, evt.Resource, evt.IsTestIt accepts the body as byte[] (preferred) or string, ASP.NET Core headers (IHeaderDictionary),
HttpHeaders or key-value pairs, and one or more secrets. A complete minimal API receiver is in
Verifying the signature.
Testing #
Pass a fake HttpMessageHandler in CompenseClientOptions.HttpMessageHandler, or an HttpClient
built on top of it, and check the requests it receives. The repository uses the same technique in
tests/Compense.Sdk.Tests.