FluvPay 1.0.0
dotnet add package FluvPay --version 1.0.0
NuGet\Install-Package FluvPay -Version 1.0.0
<PackageReference Include="FluvPay" Version="1.0.0" />
<PackageVersion Include="FluvPay" Version="1.0.0" />
<PackageReference Include="FluvPay" />
paket add FluvPay --version 1.0.0
#r "nuget: FluvPay, 1.0.0"
#:package FluvPay@1.0.0
#addin nuget:?package=FluvPay&version=1.0.0
#tool nuget:?package=FluvPay&version=1.0.0
FluvPay SDK para .NET
SDK oficial da FluvPay para .NET. Cobranças PIX, saques, transferências internas
e verificação de webhooks, com tipagem forte e zero dependência de runtime (usa
HttpClient e System.Text.Json da própria plataforma).
Instalação
Requisitos: .NET 8.0 ou superior.
O SDK ainda não está publicado no NuGet (a publicação no registry depende de uma conta que será criada em breve). Até lá, instale a partir do código-fonte. As duas formas abaixo funcionam hoje.
A partir do código-fonte (recomendado hoje)
Clone o repositório e adicione uma ProjectReference ao FluvPay.csproj no seu
projeto:
git clone https://github.com/fluvpay/fluvpay-dotnet.git
dotnet add SeuProjeto.csproj reference ./fluvpay-dotnet/src/FluvPay/FluvPay.csproj
Isso adiciona a seguinte entrada ao seu .csproj (você pode editar à mão se
preferir, ajustando o caminho relativo até onde clonou o repositório):
<ItemGroup>
<ProjectReference Include="..\fluvpay-dotnet\src\FluvPay\FluvPay.csproj" />
</ItemGroup>
Pacote local com dotnet pack
Como alternativa, empacote o SDK localmente e instale o .nupkg gerado a partir
de uma pasta no seu disco:
git clone https://github.com/fluvpay/fluvpay-dotnet.git
dotnet pack ./fluvpay-dotnet/src/FluvPay/FluvPay.csproj -c Release -o ./pacotes-locais
dotnet add SeuProjeto.csproj package FluvPay --source ./pacotes-locais
Via NuGet (em breve, quando publicado no NuGet)
Quando o pacote estiver publicado no registry, a instalação será um único comando. Ainda não funciona, não use até o anúncio oficial:
dotnet add package FluvPay
Configuração
A API Key define o modo de operação pelo prefixo: fluv_live_ para produção e
fluv_test_ para o sandbox. Você só precisa passar a chave; o SDK cuida do
resto.
using FluvPay;
var client = new FluvPayClient("fluv_live_sua_chave");
// Ou com opções explícitas:
var client = new FluvPayClient(new FluvPayClientOptions
{
ApiKey = Environment.GetEnvironmentVariable("FLUVPAY_API_KEY")!,
// BaseUrl = "https://api.fluvpay.com/api/v1", // padrão
// Timeout = TimeSpan.FromSeconds(30), // padrão
// MaxRetries = 2, // padrão (0 desliga)
});
Console.WriteLine(client.IsTestKey()); // true se a chave for fluv_test_
O FluvPayClient implementa IDisposable. Reaproveite a mesma instância pela
vida útil da aplicação em vez de criar uma por requisição.
Criar uma cobrança PIX
A criação de cobrança aceita apenas os campos do contrato. Não envie currency
nem method: a moeda e o método (PIX) são implícitos, e a API rejeita campos
extras com erro de validação.
var charge = await client.Charges.CreateAsync(new ChargeCreateParams
{
AmountCents = 2500, // R$ 25,00 (mínimo 100, máximo 100000)
Description = "Pedido #1042",
Customer = new ChargeCustomer { Name = "Cliente Exemplo", Email = "cliente@exemplo.com" },
PassFeeToPayer = true,
Metadata = new Dictionary<string, object?> { ["pedido_id"] = "1042" },
});
Console.WriteLine(charge.Id);
Console.WriteLine(charge.Status); // pending | paid | expired | cancelled | refunded
Console.WriteLine(charge.PixCopyPaste); // código copia-e-cola
Console.WriteLine(charge.PixQrCode); // imagem do QR em base64
A Idempotency-Key é gerada automaticamente (UUIDv4) se você não informar uma.
Para controlar a chave (por exemplo, reusar entre tentativas do seu lado), passe
pelas opções de escrita:
var charge = await client.Charges.CreateAsync(
new ChargeCreateParams { AmountCents = 2500 },
new WriteOptions { IdempotencyKey = "pedido-1042-tentativa-1" });
Recuperar e listar
var charge = await client.Charges.RetrieveAsync("chg_...");
var page = await client.Charges.ListAsync(new ChargeListParams
{
Status = "paid",
Page = 1,
PerPage = 20,
Sort = "-created_at",
});
Console.WriteLine(page.Data.Count); // ChargeListItem
Console.WriteLine(page.HasNext); // paginação por page/per_page
Saques e transferências internas
Estas operações são live-only: chaves fluv_test_ recebem 403.
var withdrawal = await client.Withdrawals.CreateAsync(new WithdrawalCreateParams
{
AmountCents = 5000,
PixKey = "chave@exemplo.com",
PixKeyType = "email", // cpf | cnpj | email | phone | evp
});
var withdrawalsPage = await client.Withdrawals.ListAsync(new WithdrawalListParams { Limit = 20, Offset = 0 });
Console.WriteLine(withdrawalsPage.Total); // paginação por limit/offset
var transfer = await client.InternalTransfers.CreateAsync(new InternalTransferCreateParams
{
AmountCents = 1000,
RecipientEmail = "destino@exemplo.com", // ou RecipientMerchantId
});
Extrato (transactions)
var txPage = await client.Transactions.ListAsync(new TransactionListParams { Page = 1, PerPage = 50 });
var tx = await client.Transactions.RetrieveAsync("tx_...");
Sandbox
Disponível apenas com chave fluv_test_.
var scenarios = await client.Sandbox.ScenariosAsync();
var reset = await client.Sandbox.ResetAsync();
Verificação de webhooks
A FluvPay assina cada entrega. Verifique a assinatura usando o corpo CRU da
requisição (nunca re-serialize o JSON, pois isso muda os bytes e invalida a
assinatura). O cálculo é HMAC_SHA256(secret, timestamp + "." + rawBody) em
hex, e o header X-FluvPay-Signature vem no formato v1=<hex>.
Exemplo com ASP.NET Core, lendo o corpo cru:
using FluvPay;
app.MapPost("/webhooks/fluvpay", async (HttpRequest request) =>
{
using var ms = new MemoryStream();
await request.Body.CopyToAsync(ms);
byte[] rawBody = ms.ToArray();
try
{
var evt = Webhooks.VerifySignature(
payload: rawBody,
signatureHeader: request.Headers["X-FluvPay-Signature"]!,
timestamp: request.Headers["X-FluvPay-Timestamp"]!,
secret: Environment.GetEnvironmentVariable("FLUVPAY_WEBHOOK_SECRET")!, // whsec_...
toleranceSeconds: 300);
switch (evt.Type)
{
case "charge.paid":
// processar pagamento confirmado
break;
case "payout.completed":
// processar saque concluído
break;
}
return Results.Ok();
}
catch (FluvPaySignatureVerificationException)
{
return Results.BadRequest();
}
});
Eventos disponíveis: charge.created, charge.paid, charge.expired,
charge.cancelled, charge.refunded, payout.created, payout.completed e
payout.failed.
Tratamento de erros
Cada falha vira uma exceção tipada. Todas herdam de FluvPayException e carregam
Code, Message, Details, TraceId e StatusCode.
try
{
await client.Charges.CreateAsync(new ChargeCreateParams { AmountCents = 1 });
}
catch (FluvPayValidationException ex)
{
Console.Error.WriteLine($"{ex.Code}: {ex.Details.Count} detalhe(s)");
}
catch (FluvPayRateLimitException ex)
{
Console.Error.WriteLine($"aguardar {ex.RetryAfter} segundos");
}
Mapeamento: 400/422 para FluvPayValidationException, 401 para
FluvPayAuthenticationException, 403 para FluvPayPermissionException, 404 para
FluvPayNotFoundException, 409 para FluvPayConflictException (inclui
IDEMPOTENCY_CONFLICT), 429 para FluvPayRateLimitException (lê Retry-After),
5xx para FluvPayServerException, e falha de rede ou timeout para
FluvPayConnectionException.
Retentativas
O SDK retenta automaticamente (padrão 2 tentativas, backoff exponencial com
jitter) apenas em situações seguras: requisições GET e POSTs que carregam
Idempotency-Key, nos casos de 429 e 5xx ou falha de conexão. O header
Retry-After é respeitado. Para desligar, use MaxRetries = 0.
Desenvolvimento
dotnet build
dotnet test # unit + webhook (sem rede)
O smoke no sandbox roda somente se a variável FLUVPAY_TEST_KEY (prefixo
fluv_test_) estiver presente; caso contrário, é ignorado.
Licença
MIT.
| Product | Versions 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 was computed. 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. |
-
net8.0
- No dependencies.
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.0 | 145 | 6/8/2026 |