Asaas.Client 0.0.3

dotnet add package Asaas.Client --version 0.0.3
                    
NuGet\Install-Package Asaas.Client -Version 0.0.3
                    
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="Asaas.Client" Version="0.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Asaas.Client" Version="0.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Asaas.Client" />
                    
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 Asaas.Client --version 0.0.3
                    
#r "nuget: Asaas.Client, 0.0.3"
                    
#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 Asaas.Client@0.0.3
                    
#: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=Asaas.Client&version=0.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Asaas.Client&version=0.0.3
                    
Install as a Cake Tool

Asaas.Client

SDK em C# para integração com o Asaas — clientes, cobranças, assinaturas, notas fiscais, webhooks, subcontas e transferências.

NuGet .NET

Sumário


Instalação

dotnet add package Asaas.Client

Configuração

Informe o ambiente, a chave de API (access_token) e o User-Agent (nome da sua aplicação, obrigatório pelo Asaas).

Ambiente URL base
AsaasEnvironment.SANDBOX https://api-sandbox.asaas.com/v3/
AsaasEnvironment.PRODUCAO https://api.asaas.com/v3/

Não versione a chave de API. Use user-secrets, variável de ambiente ou um cofre de segredos.

Uso direto

using Asaas.Client;
using Asaas.Client.Models.Options;

// Ambiente e credenciais
var client = new AsaasClient(AsaasEnvironment.SANDBOX, "minha-api-key", "MinhaAplicacao");

// A partir das opções
var client = new AsaasClient(new AsaasOptions()
{
    Environment = AsaasEnvironment.SANDBOX,
    AccessToken = "minha-api-key",
    UserAgent = "MinhaAplicacao"
});

// A partir da configuração (seção "Asaas")
var client = new AsaasClient(configuration.GetAsaasOptions());

// Com log das requisições (passe um ILogger e ligue enableLogging)
var client = new AsaasClient(AsaasEnvironment.SANDBOX, "minha-api-key", "MinhaAplicacao", enableLogging: true, logger: meuLogger);

Injeção de dependência

// Program.cs ou Startup.cs
builder.Services.AddAsaas(AsaasEnvironment.PRODUCAO, "minha-api-key", "MinhaAplicacao");

// Com log das requisições
builder.Services.AddAsaas(AsaasEnvironment.PRODUCAO, "minha-api-key", "MinhaAplicacao", enableLogging: true);

// Com token do webhook
builder.Services.AddAsaas(AsaasEnvironment.PRODUCAO, "minha-api-key", "MinhaAplicacao", webhookToken: "token-secreto-do-webhook-com-32-caracteres");

// Ou via Options pattern
builder.Services.AddAsaas(options =>
{
    options.Environment = AsaasEnvironment.PRODUCAO;
    options.AccessToken = "minha-api-key";
    options.UserAgent = "MinhaAplicacao";
    options.WebhookToken = "token-secreto-do-webhook-com-32-caracteres";
    options.EnableLogging = true;
});

// Ou a partir da configuração (seção "Asaas")
builder.Services.AddAsaas(builder.Configuration);
// No seu serviço ou controller
public class MeuServico(IAsaasClient client)
{
    // use client.Cliente, client.Cobranca, client.Assinatura, client.Webhooks, client.Subconta, client.Transferencia
}

Configuração via appsettings.json

As opções (AsaasOptions) podem vir de qualquer fonte do IConfiguration: appsettings.json, user-secrets, variáveis de ambiente, cofre de segredos etc.

Chave Tipo Obrigatória Descrição
Environment AsaasEnvironment Não SANDBOX ou PRODUCAO. Padrão SANDBOX
AccessToken string Sim Chave de API, enviada no header access_token
UserAgent string Sim Nome da aplicação, enviado no header User-Agent
WebhookToken string Não Token esperado no header asaas-access-token (mesmo valor de AuthToken)
EnableLogging bool Não Liga o log de requisições e respostas. Padrão false

Environment aceita o nome do enum sem diferenciar maiúsculas ("PRODUCAO", "producao") ou o número (0 = SANDBOX, 1 = PRODUCAO). Valor inválido lança InvalidOperationException no bind. Chave ausente → SANDBOX.

{
  "Asaas": {
    "Environment": "PRODUCAO",
    "AccessToken": "minha-api-key",
    "UserAgent": "MinhaAplicacao",
    "WebhookToken": "token-secreto-do-webhook-com-32-caracteres",
    "EnableLogging": false
  }
}

A seção padrão é Asaas. Os dois métodos aceitam o parâmetro opcional section para ler de outra seção:

Método Uso
services.AddAsaas(configuration, section = "Asaas") Registra o IAsaasClient no DI
configuration.GetAsaasOptions(section = "Asaas") Retorna um AsaasOptions preenchido (sem DI)
// Injeção de dependência — seção padrão "Asaas"
builder.Services.AddAsaas(builder.Configuration);

// Injeção de dependência — outra seção
builder.Services.AddAsaas(builder.Configuration, "Pagamentos:Asaas");

// Sem DI — seção padrão "Asaas"
var options = configuration.GetAsaasOptions();
var client = new AsaasClient(options);

// Sem DI — outra seção
var options = configuration.GetAsaasOptions("Pagamentos:Asaas");

Seção aninhada usa : como separador. Ex: "Pagamentos:Asaas" lê:

{
  "Pagamentos": {
    "Asaas": {
      "Environment": "SANDBOX",
      "AccessToken": "minha-api-key",
      "UserAgent": "MinhaAplicacao"
    }
  }
}

Variáveis de ambiente usam __ como separador:

Asaas__Environment=PRODUCAO
Asaas__AccessToken=minha-api-key
Asaas__UserAgent=MinhaAplicacao
Asaas__WebhookToken=token-secreto-do-webhook-com-32-caracteres

Ler as opções já registradas (ex: WebhookToken no endpoint do webhook):

public class WebhookController(IOptions<AsaasOptions> options)
{
    private readonly string webhookToken = options.Value.WebhookToken;
}

GetAsaasOptions retorna um AsaasOptions vazio quando a seção não existe. AccessToken e UserAgent são validados ao criar o AsaasClient.

Logging das requisições

Quando EnableLogging está ligado (e há um ILogger disponível — automático no DI), todas as requisições e respostas são logadas: método, URL, corpo, status HTTP e tempo de resposta.

info: Asaas.Client.AsaasClient[0]
      Asaas -> POST https://api-sandbox.asaas.com/v3/customers
      {"name":"Fulano","cpfCnpj":"12345678909"}
info: Asaas.Client.AsaasClient[0]
      Asaas <- 200 POST https://api-sandbox.asaas.com/v3/customers (243ms)
      {"object":"customer","id":"cus_000005219613",...}
  • Request e resposta de sucesso → nível Information; falhas (status ≥ 400) → Warning.
  • EnableLogging = false (padrão) → nenhum log e zero overhead (os corpos nem são lidos).
  • Os corpos contêm dados pessoais (CPF, e-mail) — ligue só quando necessário.

Serviços Disponíveis

Serviço Endpoint Descrição
client.Cliente /v3/customers Clientes
client.Cobranca /v3/payments Cobranças e QR Code Pix
client.Assinatura /v3/subscriptions Assinaturas e cobranças geradas
client.Assinatura.NotaFiscal /v3/subscriptions/{id}/invoiceSettings Configuração de nota fiscal
client.Webhooks /v3/webhooks Configuração de webhooks
client.Subconta /v3/accounts, /v3/myAccount Subcontas e situação cadastral
client.Subconta.ChaveApi /v3/accounts/{id}/accessTokens Chaves de API das subcontas
client.Subconta.DadosComerciais /v3/myAccount/commercialInfo Dados comerciais
client.Subconta.Documento /v3/myAccount/documents Documentos da análise cadastral
client.Transferencia /v3/transfers, /v3/finance/balance Saques e saldo

Convenções

  • Métodos: Criar, Buscar, Listar, Atualizar, Excluir, nessa ordem, seguidos dos métodos específicos (QrCodePix, Status, Cancelar...).
  • Parâmetros: id → request → filtros → offset/limit → apiKey (sempre por último).
  • Excluir devolve ExclusaoResponse (Deleted, Id).
  • Listas devolvem ListResponse<T> (Data, HasMore, TotalCount, Limit, Offset); limit padrão 10, máx 100.
  • Campos nulos não são enviados. Na atualização parcial, preencha só o que deve mudar.
  • Atualização parcial: assinatura, nota fiscal e webhook têm request própria (AtualizarAssinaturaRequest, AtualizarNotaFiscalAssinaturaRequest, AtualizarWebhooksRequest).
  • apiKey: métodos de subconta, documentos, dados comerciais e transferências aceitam a chave de API da subconta para agir em nome dela. Sem apiKey, usam a chave configurada no cliente (conta raiz).

ClienteService (client.Cliente)

using Asaas.Client.Models.Requests;

var request = new ClienteRequest()
{
    Name = "Fulano de Tal",
    CpfCnpj = "12345678909",
    Email = "fulano@email.com",
    MobilePhone = "11999999999",
    ExternalReference = "seu-identificador",
    NotificationDisabled = true,   // padrão true: o Asaas não envia notificações; null na atualização mantém o valor atual

    PostalCode = "01310100",
    Address = "Av. Paulista",
    AddressNumber = "1000",
    Complement = "Sala 1",
    Province = "Bela Vista",

    Phone = "1133334444",                          // opcionais
    AdditionalEmails = "financeiro@empresa.com",
    Company = "Empresa LTDA",
    Observations = "Cliente VIP"
};

// Criar (guarde o Id)
var cliente = await client.Cliente.Criar(request);

// Buscar
var dados = await client.Cliente.Buscar(cliente.Id);

// Atualizar (campos nulos não são enviados; NotificationDisabled = null mantém o valor atual)
await client.Cliente.Atualizar(cliente.Id, new ClienteRequest()
{
    Email = "novo@email.com",
    NotificationDisabled = null
});

// Excluir
var exclusao = await client.Cliente.Excluir(cliente.Id);
// exclusao.Deleted, exclusao.Id

CobrancaService (client.Cobranca)

var request = new CobrancaRequest()
{
    Customer = cliente.Id,
    BillingType = AsaasBillingType.PIX,
    Value = 99.90,
    DueDate = DateTime.Today.AddDays(3),
    Description = "Pedido 123",
    ExternalReference = "123",
    Discount = new DescontoRequest() { Value = 5, DueDateLimitDays = 0, Type = AsaasValueType.PERCENTAGE },   // opcional
    Interest = new JurosRequest() { Value = 1 },                                                            // opcional: 1% ao mês
    Fine = new MultaRequest() { Value = 2, Type = AsaasValueType.PERCENTAGE }                                // opcional
    // InstallmentCount = 3, InstallmentValue = 33.30                                                       // parcelado (apenas criação)
};

// Criar
var cobranca = await client.Cobranca.Criar(request);
// cobranca.Id, cobranca.Status, cobranca.InvoiceUrl (fatura), cobranca.BankSlipUrl (boleto), cobranca.NetValue

// QR Code Pix
var pix = await client.Cobranca.QrCodePix(cobranca.Id);
// pix.EncodedImage (imagem base64), pix.Payload (copia e cola), pix.ExpirationDate

// Buscar
var dados = await client.Cobranca.Buscar(cobranca.Id);

// Atualizar (BillingType, Value e DueDate são obrigatórios; Customer e parcelamento são ignorados)
request.Value = 120.00;
await client.Cobranca.Atualizar(cobranca.Id, request);

// Excluir
var exclusao = await client.Cobranca.Excluir(cobranca.Id);
// exclusao.Deleted, exclusao.Id
Campo Uso
Discount Desconto até DueDateLimitDays dias antes do vencimento (0 = até o vencimento)
Interest Juros ao mês após o vencimento (percentual)
Fine Multa após o vencimento (FIXED ou PERCENTAGE)
InstallmentCount + InstallmentValue ou TotalValue Cobrança parcelada (só na criação; gera uma cobrança por parcela)
Callback Redireciona o pagador após o pagamento

Split de pagamento

Divide o valor recebido com outras contas Asaas (ex: subcontas), pelo WalletId. Vale também para AssinaturaRequest.

var request = new CobrancaRequest()
{
    Customer = cliente.Id,
    BillingType = AsaasBillingType.PIX,
    Value = 100.00,
    DueDate = DateTime.Today.AddDays(3),
    Split =
    [
        new SplitRequest() { WalletId = subconta.WalletId, PercentualValue = 90 },   // 90% do valor líquido
        new SplitRequest() { WalletId = "outra-carteira", FixedValue = 5.00 }        // ou valor fixo
    ]
};

var cobranca = await client.Cobranca.Criar(request);
// cobranca.Split: Status (PENDING, DONE, CANCELLED...), TotalValue, CancellationReason

O WalletId vem de client.Subconta.Criar (subconta.WalletId). Acompanhe a liquidação pelo evento PAYMENT_SPLIT_DONE (ver WEBHOOK.md).

AssinaturaService (client.Assinatura)

var request = new AssinaturaRequest()
{
    Customer = cliente.Id,
    BillingType = AsaasBillingType.PIX,
    Value = 49.90,
    Cycle = AsaasCycle.MONTHLY,
    NextDueDate = DateTime.Today.AddDays(1),   // vencimento da primeira cobrança
    Description = "Plano mensal",
    EndDate = DateTime.Today.AddYears(1),      // opcional
    MaxPayments = 12,                          // opcional
    ExternalReference = "assinatura-123",
    Split = [new SplitRequest() { WalletId = subconta.WalletId, PercentualValue = 10 }],   // opcional
    Callback = new CallbackRequest()           // opcional
    {
        SuccessUrl = "https://meu-sistema.com/obrigado",
        AutoRedirect = true
    }
};

// Criar
var assinatura = await client.Assinatura.Criar(request);

// Buscar
var dados = await client.Assinatura.Buscar(assinatura.Id);
// dados.Status: ACTIVE, INACTIVE ou EXPIRED

// Cobranças geradas pela assinatura (paginadas; limit padrão 10, máx 100)
var cobrancas = await client.Assinatura.ListarCobrancas(assinatura.Id, offset: 0, limit: 10, status: "PENDING");
// cobrancas.Data, cobrancas.HasMore, cobrancas.TotalCount

// Atualizar (parcial: só os campos informados mudam; por padrão, só as cobranças futuras)
await client.Assinatura.Atualizar(assinatura.Id, new AtualizarAssinaturaRequest()
{
    Value = 59.90,
    UpdatePendingPayments = true   // aplica também às cobranças pendentes
});

// Suspender / reativar
await client.Assinatura.Atualizar(assinatura.Id, new AtualizarAssinaturaRequest() { Status = AsaasSubscriptionStatus.INACTIVE });
await client.Assinatura.Atualizar(assinatura.Id, new AtualizarAssinaturaRequest() { Status = AsaasSubscriptionStatus.ACTIVE, NextDueDate = DateTime.Today.AddDays(1) });

// Excluir
await client.Assinatura.Excluir(assinatura.Id);

Nota fiscal da assinatura (client.Assinatura.NotaFiscal)

var request = new NotaFiscalAssinaturaRequest()
{
    MunicipalServiceId = "55021",
    MunicipalServiceName = "Análise e desenvolvimento de sistemas.",
    EffectiveDatePeriod = AsaasEffectiveDatePeriod.ON_PAYMENT_CONFIRMATION,
    ReceivedOnly = true,          // emite apenas para cobranças pagas (padrão do SDK true; do Asaas, false)
    UpdatePayment = false,        // true: desconta os impostos do valor da cobrança
    Observations = "Mensalidade",
    Taxes = new Taxes()           // todas as alíquotas são obrigatórias (padrão 0)
    {
        ISS = 2,
        PIS = 0.65,
        COFINS = 3,
        CSLL = 0,
        INSS = 0,
        IR = 0,
        RetainIss = false
    }
};

// Criar
await client.Assinatura.NotaFiscal.Criar(assinatura.Id, request);

// Buscar
var config = await client.Assinatura.NotaFiscal.Buscar(assinatura.Id);

// Atualizar (ex: emitir 5 dias antes do vencimento; Taxes é obrigatório e substituído por inteiro)
await client.Assinatura.NotaFiscal.Atualizar(assinatura.Id, new AtualizarNotaFiscalAssinaturaRequest()
{
    EffectiveDatePeriod = AsaasEffectiveDatePeriod.BEFORE_PAYMENT_DUE_DATE,
    DaysBeforeDueDate = 5,   // 5, 10, 15, 30 ou 60
    Taxes = request.Taxes
});

// Excluir
await client.Assinatura.NotaFiscal.Excluir(assinatura.Id);

WebhooksService (client.Webhooks)

var request = new WebhooksRequest()
{
    Name = "Principal",
    Url = "https://meu-sistema.com/webhook/asaas",
    Email = "dev@meu-sistema.com",
    AuthToken = "token-secreto-do-webhook-com-32-caracteres",   // enviado no header asaas-access-token
    SendType = AsaasSendType.SEQUENTIALLY,
    Events = [AsaasWebhookEvent.PAYMENT_RECEIVED, AsaasWebhookEvent.PAYMENT_CONFIRMED, AsaasWebhookEvent.PAYMENT_OVERDUE]
};

// Criar
var webhook = await client.Webhooks.Criar(request);

// Buscar
var dados = await client.Webhooks.Buscar(webhook.Id);
// dados.Enabled, dados.Interrupted, dados.HasAuthToken, dados.PenalizedRequestsCount

// Listar
var webhooks = await client.Webhooks.Listar(offset: 0, limit: 10);

// Atualizar (parcial: só os campos informados mudam)
await client.Webhooks.Atualizar(webhook.Id, new AtualizarWebhooksRequest()
{
    Interrupted = false   // retoma a fila interrompida
});

// Remover penalização (retoma entregas atrasadas)
await client.Webhooks.RemoverPenalizacao(webhook.Id);

// Excluir
var exclusao = await client.Webhooks.Excluir(webhook.Id);
// exclusao.Deleted, exclusao.Id

AuthToken: 32 a 255 caracteres, sem espaços, diferente da chave de API. Limite de 10 webhooks por conta.

Recebimento e validação dos eventos: ver WEBHOOK.md.

SubcontaService (client.Subconta)

A conta raiz precisa ser pessoa jurídica. O corpo da criação é o mesmo nos dois modelos:

Modelo Habilitação Onboarding
Normal Padrão Asaas envia e-mail de ativação; titular envia documentos pela interface do Asaas
BaaS Gerente de contas habilita na conta raiz Asaas não se comunica com o titular; sua plataforma conduz o envio (client.Subconta.Documento)
var request = new SubcontaRequest()
{
    Name = "Loja do Fulano",
    Email = "fulano@email.com",
    CpfCnpj = "12345678000199",
    CompanyType = AsaasCompanyType.LIMITED,   // pessoa jurídica
    // BirthDate = new DateTime(1990, 1, 1),  // pessoa física
    MobilePhone = "11999999999",
    IncomeValue = 25000,
    Address = "Av. Paulista",
    AddressNumber = "1000",
    Province = "Bela Vista",
    PostalCode = "01310100",
    Webhooks =                                 // opcional
    [
        new WebhooksRequest()
        {
            Name = "Subconta",
            Url = "https://meu-sistema.com/webhook/asaas",
            Email = "dev@meu-sistema.com",
            AuthToken = "token-secreto-do-webhook-com-32-caracteres",
            Events = [AsaasWebhookEvent.ACCOUNT_STATUS_GENERAL_APPROVAL_APPROVED, AsaasWebhookEvent.TRANSFER_DONE]
        }
    ]
};

// Criar — guarde ApiKey e WalletId: a chave não é retornada novamente
var subconta = await client.Subconta.Criar(request);
// subconta.Id, subconta.WalletId, subconta.ApiKey, subconta.AccountNumber

// Buscar / listar
var dados = await client.Subconta.Buscar(subconta.Id);
var subcontas = await client.Subconta.Listar(cpfCnpj: "12345678000199", offset: 0, limit: 10);

Situação da conta

Consultas em /v3/myAccount usam a chave de API da subconta (sem chave → própria conta do cliente).

var status = await client.Subconta.Status(subconta.ApiKey);
// status.CommercialInfo, status.BankAccountInfo, status.Documentation, status.General
// PENDING, AWAITING_APPROVAL, APPROVED ou REJECTED

if (status.Aprovada)   // General == APPROVED
{
    // conta liberada
}

Para acompanhar sem consultar, use os eventos ACCOUNT_STATUS_* do webhook (ex: ACCOUNT_STATUS_GENERAL_APPROVAL_APPROVED).

// Sandbox: aprova a subconta na hora (a análise não acontece sozinha)
await client.Subconta.AprovarSandbox(subconta.ApiKey);

Dados comerciais (client.Subconta.DadosComerciais)

Quando CommercialInfo for REJECTED (ou expirar), consulte e reenvie todos os dados.

var comercial = await client.Subconta.DadosComerciais.Buscar(subconta.ApiKey);
// comercial.Status, comercial.DenialReason, comercial.CommercialInfoExpiration

await client.Subconta.DadosComerciais.Atualizar(new DadosComerciaisRequest()
{
    PersonType = AsaasPersonType.JURIDICA,
    CpfCnpj = "12345678000199",
    CompanyType = AsaasCompanyType.LIMITED,
    IncomeValue = 25000,
    Email = "fulano@email.com",
    MobilePhone = "11999999999",
    PostalCode = "01310100",
    Address = "Av. Paulista",
    AddressNumber = "1000",
    Province = "Bela Vista"
}, subconta.ApiKey);

Documentos (client.Subconta.Documento)

Aguarde ao menos 15 segundos após a criação antes de consultar.

var documentos = await client.Subconta.Documento.Listar(subconta.ApiKey);

foreach (var grupo in documentos.Data.Where(x => x.Status is AsaasDocumentStatus.NOT_SENT or AsaasDocumentStatus.REJECTED))
{
    if (!string.IsNullOrWhiteSpace(grupo.OnboardingUrl))
    {
        // envie o titular ao link (documento de identificação + selfie); envio via API é recusado
        continue;
    }

    await using var arquivo = File.OpenRead("contrato-social.pdf");
    await client.Subconta.Documento.Criar(grupo.Id, grupo.Type, arquivo, "contrato-social.pdf", subconta.ApiKey);
}
// documentos.RejectReasons: motivos de reprovação

// Arquivo já enviado (Id em grupo.Documents)
var enviado = await client.Subconta.Documento.Buscar(arquivoId, subconta.ApiKey);
await client.Subconta.Documento.Atualizar(arquivoId, novoArquivo, "contrato-social.pdf", subconta.ApiKey);
await client.Subconta.Documento.Excluir(arquivoId, subconta.ApiKey);

A análise leva até 48h. No sandbox, use client.Subconta.AprovarSandbox.

Chaves de API (client.Subconta.ChaveApi)

Recupera o acesso quando a chave original foi perdida. Pré-requisitos: habilitar "Gerenciamento de Chaves de API de Subcontas" em Integrações > Chaves de API (expira em 2 horas) e ativar a lista de IPs permitidos com o IP da aplicação. Sem isso → 403.

// Listar (sem o valor da chave)
var chaves = await client.Subconta.ChaveApi.Listar(subconta.Id);

// Criar — guarde ApiKey: não é retornada novamente
var chave = await client.Subconta.ChaveApi.Criar(subconta.Id, new ChaveApiRequest()
{
    Name = "Integração",
    ExpirationDate = DateTime.Today.AddYears(1)
});

// Desativar
await client.Subconta.ChaveApi.Atualizar(subconta.Id, chave.Id, new ChaveApiRequest()
{
    Name = "Integração",
    Enabled = false,
    ExpirationDate = DateTime.Today.AddYears(1)
});

// Excluir
await client.Subconta.ChaveApi.Excluir(subconta.Id, chave.Id);

Encerrar subconta (BaaS)

Irreversível. A chave da subconta é obrigatória, para não encerrar a conta raiz por engano.

var encerramento = await client.Subconta.Encerrar("Cliente cancelou o contrato", subconta.ApiKey);

TransferenciaService (client.Transferencia)

Saque para conta bancária de outra instituição ou chave Pix, ou transferência interna para outra conta Asaas. Informe a chave de API da subconta de origem (sem chave → conta do cliente).

// Saldo disponível
var saldo = await client.Transferencia.Saldo(subconta.ApiKey);

// Saque via chave Pix
var saque = await client.Transferencia.Criar(new TransferenciaRequest()
{
    Value = 150.00,
    PixAddressKey = "fulano@email.com",
    PixAddressKeyType = AsaasPixAddressKeyType.EMAIL,
    Description = "Saque",
    ExternalReference = "saque-123"
}, subconta.ApiKey);

// Saque para conta bancária (Pix quando o banco participa, senão TED)
var saqueConta = await client.Transferencia.Criar(new TransferenciaRequest()
{
    Value = 150.00,
    OperationType = AsaasTransferOperationType.TED,   // opcional
    BankAccount = new ContaBancariaRequest()
    {
        Bank = new BancoRequest() { Code = "237" },
        OwnerName = "Fulano de Tal",
        CpfCnpj = "12345678000199",
        Agency = "0001",
        Account = "123456",
        AccountDigit = "7",
        BankAccountType = AsaasBankAccountType.CONTA_CORRENTE
    }
}, subconta.ApiKey);
// saque.Id, saque.Status (PENDING, BANK_PROCESSING, DONE, CANCELLED, FAILED), saque.TransferFee, saque.Authorized

// Transferência interna (ex: da conta raiz para a subconta)
var interna = await client.Transferencia.Criar(new TransferenciaRequest()
{
    Value = 50.00,
    WalletId = subconta.WalletId
});

// Buscar
var dados = await client.Transferencia.Buscar(saque.Id, subconta.ApiKey);

// Listar (filtros opcionais)
var transferencias = await client.Transferencia.Listar(dateCreatedStart: DateTime.Today.AddDays(-30), dateCreatedEnd: DateTime.Today, offset: 0, limit: 10, apiKey: subconta.ApiKey);

// Cancelar (apenas PENDING)
if (dados.Cancelavel)
{
    await client.Transferencia.Cancelar(saque.Id, subconta.ApiKey);
}
Destino Preencha
Chave Pix PixAddressKey + PixAddressKeyType
Conta bancária BankAccount (Pix se o banco participar, senão TED; force com OperationType)
Outra conta Asaas WalletId (transferência interna)
  • ScheduleDate agenda a transferência; sem ela, é imediata.
  • Authorized = false indica que o saque aguarda autorização por token (SMS/app).
  • Acompanhe pelos eventos TRANSFER_* do webhook.

Fluxo completo de subconta

// 1. Criar a subconta (normal ou BaaS, conforme a conta raiz) e guardar Id, WalletId e ApiKey
var subconta = await client.Subconta.Criar(request);

// 2. BaaS: aguardar 15s e conduzir os documentos
await Task.Delay(TimeSpan.FromSeconds(15));
var documentos = await client.Subconta.Documento.Listar(subconta.ApiKey);
// OnboardingUrl → enviar o titular ao link; sem link → client.Subconta.Documento.Criar(...)

// 3. Acompanhar a aprovação (webhook ACCOUNT_STATUS_GENERAL_APPROVAL_APPROVED ou consulta)
var status = await client.Subconta.Status(subconta.ApiKey);

// 4. Receber: cobranças com split para a subconta
await client.Cobranca.Criar(new CobrancaRequest()
{
    Customer = cliente.Id,
    BillingType = AsaasBillingType.PIX,
    Value = 100.00,
    DueDate = DateTime.Today.AddDays(3),
    Split = [new SplitRequest() { WalletId = subconta.WalletId, PercentualValue = 90 }]
});

// 5. Sacar: saldo e transferência em nome da subconta
var saldo = await client.Transferencia.Saldo(subconta.ApiKey);

if (status.Aprovada && saldo.Balance > 0)
{
    await client.Transferencia.Criar(new TransferenciaRequest()
    {
        Value = saldo.Balance,
        PixAddressKey = "12345678000199",
        PixAddressKeyType = AsaasPixAddressKeyType.CNPJ
    }, subconta.ApiKey);
}

Enums

Enum Valores
AsaasEnvironment SANDBOX, PRODUCAO
AsaasBillingType UNDEFINED (pagador escolhe), BOLETO, CREDIT_CARD, PIX; só no retorno: DEBIT_CARD, TRANSFER, DEPOSIT
AsaasCycle WEEKLY, BIWEEKLY, MONTHLY, BIMONTHLY, QUARTERLY, SEMIANNUALLY, YEARLY
AsaasEffectiveDatePeriod ON_PAYMENT_CONFIRMATION, ON_PAYMENT_DUE_DATE, BEFORE_PAYMENT_DUE_DATE, ON_DUE_DATE_MONTH, ON_NEXT_MONTH
AsaasSendType SEQUENTIALLY (preserva a ordem), NON_SEQUENTIALLY (paralelo)
AsaasWebhookEvent Eventos do webhook — ver WEBHOOK.md
AsaasPersonType FISICA, JURIDICA
AsaasCompanyType MEI, LIMITED, INDIVIDUAL, ASSOCIATION
AsaasTaxRegime MEI, NATIONAL_SIMPLE, NORMAL_REGIME, UNKNOWN
AsaasAccountStatus PENDING, AWAITING_APPROVAL, APPROVED, REJECTED
AsaasDocumentType IDENTIFICATION, IDENTIFICATION_SELFIE, SOCIAL_CONTRACT, MEI_CERTIFICATE, ENTREPRENEUR_REQUIREMENT, ...
AsaasDocumentStatus NOT_SENT, PENDING, APPROVED, REJECTED, IGNORED
AsaasTransferOperationType PIX, TED
AsaasPixAddressKeyType CPF, CNPJ, EMAIL, PHONE, EVP
AsaasBankAccountType CONTA_CORRENTE, CONTA_POUPANCA
AsaasValueType FIXED, PERCENTAGE (desconto e multa)
AsaasSubscriptionStatus ACTIVE, INACTIVE (atualização de assinatura)

Compatibilidade

Mudanças em relação à versão 0.0.2:

Mudança Impacto
Assinatura.Atualizar, Assinatura.NotaFiscal.Atualizar e Webhooks.Atualizar recebem request própria de atualização A sobrecarga antiga continua funcionando, marcada como [Obsolete]. Atualizar(id, new() { ... }) sem o nome da classe fica ambíguo: informe a classe
Excluir devolve ExclusaoResponse .Id continua funcionando
ClienteRequest.NotificationDisabled e AssinaturaRequest.UpdatePendingPayments viraram bool? Atribuição igual; leitura como bool precisa de ajuste
Taxes (request): alíquotas viraram double (padrão 0) Todas são obrigatórias no Asaas
Deductions virou double? Aceita decimal
NotaFiscalAssinaturaResponse.EffectiveDatePeriod virou nulável e passou a ler invoiceCreationPeriod Antes vinha sempre ON_PAYMENT_CONFIRMATION
AsaasBillingType ganhou DEBIT_CARD, TRANSFER, DEPOSIT Só retorno; evita erro de leitura
WebhookValidator.TryParse não lança exceção Retorna false para corpo inválido

Tratamento de erros

Status HTTP de erro lança AsaasErrorException:

try
{
    await client.Cobranca.Criar(request);
}
catch (AsaasErrorException ex) when (ex.StatusCode == HttpStatusCode.TooManyRequests)
{
    // limite de requisições atingido
    await Task.Delay(ex.RetryAfter ?? TimeSpan.FromSeconds(60));
}
catch (AsaasErrorException ex)
{
    // ex.StatusCode  → HttpStatusCode
    // ex.Code        → código do primeiro erro (ex: "invalid_value")
    // ex.Message     → descrições dos erros
    // ex.Errors      → lista completa (Code + Description)
    // ex.RawBody     → corpo bruto da resposta
    // ex.RetryAfter  → tempo até liberar o limite (header RateLimit-Reset) em respostas 429

    foreach (var erro in ex.Errors)
    {
        Console.WriteLine($"{erro.Code}: {erro.Description}");
    }
}
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 is compatible.  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
0.0.3 0 9/29/2026
0.0.2 69 9/24/2026
0.0.1 67 9/24/2026
0.0.1-preview.15 99 3/3/2026
0.0.1-preview.14 240 8/27/2025
0.0.1-preview.13 169 7/17/2025
0.0.1-preview.12 164 7/16/2025
0.0.1-preview.11 117 7/4/2025
0.0.1-preview.10 177 7/3/2025
0.0.1-preview.9 170 7/3/2025
0.0.1-preview.8 174 7/2/2025
0.0.1-preview.7 191 7/2/2025
0.0.1-preview.6 181 6/19/2025
0.0.1-preview.5 188 5/22/2025
0.0.1-preview.4 169 5/22/2025
0.0.1-preview.3 170 5/22/2025
0.0.1-preview.2 186 5/22/2025
0.0.1-preview.1 181 5/22/2025