qs.Cobranca.Pack 1.0.1

dotnet add package qs.Cobranca.Pack --version 1.0.1
                    
NuGet\Install-Package qs.Cobranca.Pack -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="qs.Cobranca.Pack" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="qs.Cobranca.Pack" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="qs.Cobranca.Pack" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add qs.Cobranca.Pack --version 1.0.1
                    
#r "nuget: qs.Cobranca.Pack, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package qs.Cobranca.Pack@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=qs.Cobranca.Pack&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=qs.Cobranca.Pack&version=1.0.1
                    
Install as a Cake Tool

qs.Cobranca.Pack

Cliente .NET da API qsse.Cobranca (SaaS multitenant/multibanco de boletos da suíte QSSE). Abstrai emissão, consulta, PDF, baixa, alteração, linha do tempo, totalizadores, emissão em lote e resolução da conta emissora por CNPJ, resolvendo autenticação, idempotência, paginação, retry de transientes e tradução de erros.

Instalação

dotnet add package qs.Cobranca.Pack

Registro (DI)

builder.Services.AddQsCobranca(o =>
{
    o.BaseAddress = new Uri("https://cobranca.qsse.com.br");
    o.ApiKey = builder.Configuration["Cobranca:ApiKey"];   // header X-Api-Key
});

Com JWT do qsAccount em vez de API key:

builder.Services.AddQsCobranca(o =>
{
    o.BaseAddress = new Uri("https://cobranca.qsse.com.br");
    o.TokenProvider = async ct => await tokenCache.GetAccessTokenAsync(ct);
});

AddQsCobranca devolve o IHttpClientBuilder do client nomeado — encadeie políticas próprias (AddStandardResilienceHandler, logging, proxy) se precisar.

Sem container de DI (console, Windows Service legado):

ICobrancaClient cobranca = CobrancaClient.Create(o =>
{
    o.BaseAddress = new Uri("https://cobranca.qsse.com.br");
    o.ApiKey = "...";
});

Guarde a instância como singleton: ela é dona do HttpClient.

Multiempresa: achar a conta emissora pelo CNPJ

Um cliente pode ter várias contas bancárias, cada uma de uma empresa beneficiária (CNPJ) diferente. O ERP conhece o CNPJ que está faturando, não o GUID da conta:

var conta = await cobranca.Contas.ObterPorCnpjAsync(empresa.Cnpj)
            ?? throw new InvalidOperationException($"Sem conta ativa para o CNPJ {empresa.Cnpj}.");

// ... e vai em BankConfigId na emissão

ObterPorCnpjAsync compara só dígitos e considera apenas conta ativa; havendo mais de uma para o mesmo CNPJ, a padrão do cliente desempata. ListarAsync() devolve todas as contas com banco, agência/conta/carteira, status, validade do certificado e beneficiário.

Omitir BankConfigId na emissão usa a conta padrão do cliente — em cenário multiempresa isso emite no CNPJ errado sem avisar. .Contas é somente leitura: cadastrar conta e enviar credenciais/certificado é ato de usuário no Portal.

Emitir

var boleto = await cobranca.Boletos.EmitirAsync(
    new EmitirBoletoRequest(
        Valor: 1500.00m,
        Vencimento: DateOnly.FromDateTime(DateTime.Today.AddDays(10)),
        Pagador: new PagadorInput("ACME LTDA", "12345678000199", "87300-000", Numero: 100),
        Encargos: new EncargosInput(MultaPercentual: 2, JurosMesPercentual: 1),
        SeuNumero: "FAT-2026-000123"),
    idempotencyKey: "FAT-2026-000123");   // estável: reexecutar a rotina não emite duas vezes

Console.WriteLine(boleto.LinhaDigitavel);

A chave de idempotência é o ponto de atenção da integração: passe um valor derivado do documento de origem. Sem ela o pacote gera uma chave nova a cada chamada (AutoIdempotencyKey), o que protege apenas contra o retry interno desta chamada — não contra o ERP rodando a rotina de novo.

Consultar, listar e conciliar

var atual = await cobranca.Boletos.ObterAsync(boleto.Id);

var pagina = await cobranca.Boletos.ListarAsync(
    new BoletoFiltro(Status: BoletoStatus.Vencido, VencimentoAte: DateOnly.FromDateTime(DateTime.Today)),
    page: 1, pageSize: 100);

// Percorre todas as páginas
await foreach (var b in cobranca.Boletos.ListarTodosAsync(new BoletoFiltro(SeuNumero: "FAT-2026-000123")))
    Conciliar(b);

byte[] pdf = await cobranca.Boletos.ObterPdfAsync(boleto.Id);
var eventos = await cobranca.Boletos.ListarEventosAsync(boleto.Id);
var resumo  = await cobranca.Boletos.ObterResumoAsync();

Baixar e alterar

await cobranca.Boletos.BaixarAsync(boleto.Id, "Pago em espécie no caixa");
await cobranca.Boletos.AlterarAsync(boleto.Id, new AlterarBoletoRequest(
    NovoVencimento: DateOnly.FromDateTime(DateTime.Today.AddDays(30))));

Lote

var itens = faturas.Select(f => new LoteItemInput(
    f.Valor, f.Vencimento, new PagadorInput(f.Nome, f.Documento, f.Cep), SeuNumero: f.Numero)).ToList();

// Fatia em lotes de 50 (teto da API) e envia todos
var aceites = await cobranca.Lotes.EmitirFatiadoAsync(itens);

// Em rotina batch, dá para esperar o processamento terminar
var lote = await cobranca.Lotes.AguardarConclusaoAsync(aceites[0].LoteId);
foreach (var item in lote.Itens.Where(i => i.ErrorCode is not null))
    Log(item.SeuNumero, item.ErrorCode, item.ErrorMessage);

Quando IdempotencyKey do item não é informada, o pacote usa o SeuNumero — reprocessar o mesmo lote não reemite os títulos.

Em serviços que já recebem webhook, prefira reagir ao evento lote.concluido em vez de manter uma thread em AguardarConclusaoAsync.

Erros

Falha de negócio vira exceção tipada, com o slug da API preservado em Code:

Exceção HTTP Situação
CobrancaValidationException 400/422 dados rejeitados (invalid_cep, invalid_valor, …)
CobrancaNotFoundException 404 boleto/lote inexistente ou de outro cliente
CobrancaConflictException 409 estado incompatível (bank_config_missing, invalid_state)
CobrancaAuthException 401/403 credencial inválida, sem escopo ou cliente suspenso
CobrancaRateLimitException 429 limite de requisições do cliente
CobrancaBankUnavailableException 503 banco emissor fora do ar — transitório, o título não foi registrado
CobrancaApiException demais erro genérico, com RawBody para diagnóstico
try
{
    await cobranca.Boletos.EmitirAsync(request, idempotencyKey: fatura.Numero);
}
catch (CobrancaBankUnavailableException ex)
{
    agendador.Reagendar(fatura, ex.RetryAfter ?? TimeSpan.FromMinutes(1));
}
catch (CobrancaValidationException ex)
{
    foreach (var e in ex.Errors)
        Log(e.Code, e.Description);
}

Retry

408/429/5xx e falhas de conexão são repetidos com backoff exponencial + jitter, respeitando Retry-After (MaxAttempts, padrão 3). POST só é repetido quando carrega Idempotency-Key — sem a chave, repetir um timeout que na verdade chegou ao banco cobraria o pagador duas vezes.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 105 9/23/2026
1.0.0 117 8/27/2026