Paquete NuGetCompense.Sdk
Versión1.1.0 · API v1
Destinosnet8.0 y netstandard2.0 (.NET Framework 4.6.2+, .NET 6/7/8+, Mono)
DependenciasSystem.Text.Json, Microsoft.Extensions.Http, Microsoft.Extensions.Logging.Abstractions, Microsoft.Extensions.Options.ConfigurationExtensions
RepositorioAppiasoft/compense-saas-sdk-dotnet · guías en docs/modulos/ · ejemplos en examples/ (consola y receptor de webhooks)

Instalar #

Shell
dotnet add package Compense.Sdk --version 1.1.0

Cliente #

C#
using Compense.Sdk;
using Compense.Sdk.Models;

using var client = new CompenseClient(
    Environment.GetEnvironmentVariable("COMPENSE_API_KEY")!, CompenseEnvironment.Sandbox);

// Con todas las opciones:
var configured = new CompenseClient(new CompenseClientOptions
{
    ApiKey = "cmp_...",
    Environment = CompenseEnvironment.Sandbox,  // Production (defecto) | Sandbox | Dev
    BaseUrl = null,                             // otra URL; gana sobre Environment
    Timeout = TimeSpan.FromSeconds(30),
    Retry = new RetryOptions { MaxAttempts = 3, RetryWrites = false },
    UserAgent = "horizonte-erp/2.0",
});

También new CompenseClient(httpClient, options) con tu propio HttpClient (el SDK no lo desecha e ignora su BaseAddress).

ASP.NET Core #

C#
// Program.cs
builder.Services.AddCompense(builder.Configuration.GetSection("Compense"));
// o: 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());
JSON
{
  "Compense": {
    "Environment": "Sandbox",
    "Timeout": "00:00:30",
    "Retry": { "MaxAttempts": 3, "RetryWrites": false }
  }
}

La llave, por variable de entorno (Compense__ApiKey=cmp_...) o secreto de usuario. AddCompense registra un cliente tipado con IHttpClientFactory (handlers en pool, refresco de DNS) y devuelve el IHttpClientBuilder para añadir tus propios handlers (por ejemplo, telemetría o la firma de alto valor). Los avisos de deprecación van a ILogger (categoría Compense.Sdk).

Convenciones #

  • Métodos PascalCase con sufijo Async, CancellationToken en todos y anotaciones de nulos: client.Wallet.Bills.PayAsync(document, billerCode, reference, amount, idempotencyKey: "...").
  • Escrituras → Transaction (Data es un JsonObject); lecturas → modelos (Balance, Resolution, Page, OffsetPage…) o JsonObject; todo modelo guarda el cuerpo en .Raw. Para mapear a tu tipo: tx.Data.Deserialize<MiDto>(CompenseJson.SerializerOptions).
  • Montos: Amount, con conversión implícita desde int, long, decimal o string.
  • Decisiones: Decisions.Approve / Decisions.Reject. Afiliados: new AffiliateRef("CC", "1032456789").
  • Campos libres: IReadOnlyDictionary<string, object?> (valores de texto, números, Amount, JsonNode, diccionarios u objetos, serializados en snake_case).

Errores #

CompenseException › CompenseConfigException y CompenseApiException › AuthException, NotFoundException, IdempotencyConflictException, ValidationException (Errors), RateLimitException (RetryAfter como TimeSpan?), UpstreamException, ServerException. Propiedades: Status, Title, Detail, TraceId, Problem. Los fallos de red son los habituales HttpRequestException / TaskCanceledException.

Paginación #

Cada lista paginada tiene un gemelo …AutoPagingAsync que devuelve IAsyncEnumerable<JsonObject> y pide las páginas a demanda:

C#
await foreach (var delivery in client.Webhooks.Deliveries.ListAutoPagingAsync(status: "failed"))
{
    await client.Webhooks.Deliveries.ReplayAsync((string)delivery["id"]!);
}

Webhooks #

C#
using Compense.Sdk.Webhooks;

WebhookEvent evt = CompenseWebhooks.Verify(rawBodyBytes, request.Headers, new[] { newSecret, oldSecret });
// evt.EventId, evt.Event, evt.Resource, evt.IsTest

Acepta el cuerpo como byte[] (preferido) o string, cabeceras de ASP.NET Core (IHeaderDictionary), HttpHeaders o pares clave-valor, y uno o varios secretos. Receptor completo con minimal API en Verificar la firma.

Pruebas #

Pasa un HttpMessageHandler falso en CompenseClientOptions.HttpMessageHandler, o un HttpClient construido sobre él, y comprueba las peticiones que recibe. El repositorio trae la misma técnica en tests/Compense.Sdk.Tests.