Felloh 0.1.0
dotnet add package Felloh --version 0.1.0
NuGet\Install-Package Felloh -Version 0.1.0
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="Felloh" Version="0.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Felloh" Version="0.1.0" />
<PackageReference Include="Felloh" />
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 Felloh --version 0.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Felloh, 0.1.0"
#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 Felloh@0.1.0
#: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=Felloh&version=0.1.0
#tool nuget:?package=Felloh&version=0.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Felloh C# SDK
Official C# SDK for the Felloh payment API.
Installation
dotnet add package Felloh
Quick Start
using Felloh;
var client = new FellohClient(new FellohConfig
{
PublicKey = "your-public-key",
PrivateKey = "your-private-key",
});
var bookings = await client.Bookings.ListAsync(new ListBookingsParams
{
Organisation = "your-org-id",
});
Configuration
var client = new FellohClient(new FellohConfig
{
PublicKey = "your-public-key", // Required
PrivateKey = "your-private-key", // Required
BaseUrl = "https://api.felloh.com", // Default
Timeout = 30000, // Request timeout in ms (default: 30000)
MaxRetries = 2, // Retries on 5xx/network errors (default: 2)
TokenRefreshBuffer = 60, // Seconds before token expiry to refresh (default: 60)
Logger = entry => Console.WriteLine( // Optional request logger
$"{entry.Method} {entry.Url} {entry.StatusCode} {entry.DurationMs}ms"),
});
Resources
| Resource | Property | Endpoints |
|---|---|---|
| Organisations | client.Organisations |
list |
| Bookings | client.Bookings |
list, listAll, get, create, update, delete, updateReference |
| Booking Components | client.BookingComponents |
create, delete |
| Transactions | client.Transactions |
list, listAll, get, refund, complete, reverse, reassign |
| Customers | client.Customers |
list, listAll, create |
| Payment Links | client.PaymentLinks |
list, listAll, get, create, delete, assign |
| Ecommerce | client.Ecommerce |
list, listAll, get, create, delete, assign |
| Refunds | client.Refunds |
list, listAll, authorise, decline |
| Charges | client.Charges |
list, listAll |
| Chargebacks | client.Chargebacks |
list, listAll |
| Credit Notes | client.CreditNotes |
list, listAll, get, create, assign |
| Suppliers | client.Suppliers |
list, listAll, create |
| Beneficiaries | client.Beneficiaries |
list, listAll, create, activate |
| Disbursements | client.Disbursements |
list, listAll, get |
| Ledger | client.Ledger |
list, listAll |
| Batches | client.Batches |
list, listAll, get |
| API Keys | client.ApiKeys |
list, create, delete |
| Audit | client.Audit |
list, listAll |
| AISP | client.Aisp |
accounts, transactions, statistics |
| Scheduled Payments | client.ScheduledPayments |
list, listAll, availableTokens, createPayment, approvalLink, delete |
| Enums | client.Enums |
list |
Usage
List bookings
var response = await client.Bookings.ListAsync(new ListBookingsParams
{
Organisation = "org-id",
Skip = 0,
Take = 20,
});
foreach (var booking in response.Data)
{
Console.WriteLine($"{booking.Id} - {booking.BookingReference}");
}
Create a booking
var response = await client.Bookings.CreateAsync(new CreateBookingParams
{
Organisation = "org-id",
BookingReference = "REF-001",
CustomerName = "John Smith",
Email = "john@example.com",
Currency = "GBP",
GrossAmount = 150000, // amounts in lowest denomination (pence)
});
Get a single booking
var response = await client.Bookings.GetAsync("booking-id");
Console.WriteLine(response.Data.CustomerName);
Create a payment link
var response = await client.PaymentLinks.CreateAsync(new CreatePaymentLinkParams
{
Organisation = "org-id",
CustomerName = "John Smith",
Email = "john@example.com",
Amount = 50000,
Type = "payment",
OpenBankingEnabled = true,
CardEnabled = true,
});
Refund a transaction
var response = await client.Transactions.RefundAsync("transaction-id", new RefundTransactionParams
{
Amount = 5000,
Description = "Customer requested refund",
});
Pagination
Manual pagination
var page = await client.Bookings.ListAsync(new ListBookingsParams
{
Organisation = "org-id",
Skip = 0,
Take = 25,
});
Console.WriteLine($"Total: {page.Meta.Count}");
Console.WriteLine($"Page items: {page.Data.Count}");
Auto-pagination
Use ListAllAsync() to automatically iterate through all pages:
await foreach (var booking in client.Bookings.ListAllAsync(new ListBookingsParams
{
Organisation = "org-id",
}))
{
Console.WriteLine(booking.BookingReference);
}
Or collect all items into a list:
var allBookings = await Paginator.ToListAsync(
client.Bookings.ListAllAsync(new ListBookingsParams { Organisation = "org-id" }));
Webhook Verification
Verify webhook signatures using HMAC-SHA256 with timing-safe comparison:
using Felloh;
// Returns bool
var isValid = WebhookVerifier.VerifySignature(
payload: requestBody,
signature: request.Headers["X-Signature"],
secret: "your-webhook-secret"
);
// Throws FellohWebhookSignatureException if invalid
WebhookVerifier.AssertSignature(
payload: requestBody,
signature: request.Headers["X-Signature"],
secret: "your-webhook-secret"
);
Error Handling
The SDK throws typed exceptions for different error scenarios:
using Felloh.Errors;
try
{
await client.Bookings.GetAsync("nonexistent-id");
}
catch (FellohNotFoundException ex)
{
Console.WriteLine($"Not found: {ex.Message}");
Console.WriteLine($"Request ID: {ex.Meta?.RequestId}");
}
catch (FellohValidationException ex)
{
foreach (var error in ex.Errors)
{
Console.WriteLine($"{error.Code}: {error.Message}");
}
}
catch (FellohAuthenticationException)
{
// Invalid or expired credentials (401)
}
catch (FellohForbiddenException)
{
// Insufficient permissions (403)
}
catch (FellohRateLimitException)
{
// Rate limit exceeded (429)
}
catch (FellohServerException)
{
// Server error (5xx) - automatically retried
}
catch (FellohNetworkException ex)
{
// Network failure - automatically retried
Console.WriteLine($"Network error: {ex.InnerException?.Message}");
}
Exception hierarchy
| Exception | HTTP Status | Auto-retried |
|---|---|---|
FellohAuthenticationException |
401 | No (token refreshed once) |
FellohForbiddenException |
403 | No |
FellohNotFoundException |
404 | No |
FellohValidationException |
422 | No |
FellohRateLimitException |
429 | No |
FellohServerException |
5xx | Yes |
FellohNetworkException |
N/A | Yes |
Token Management
The SDK automatically manages JWT tokens:
- Acquires a token on the first API call
- Caches and reuses the token until near expiry
- Proactively refreshes before the token expires (configurable buffer)
- Force-refreshes on 401 responses (once per request)
- Thread-safe concurrent request deduplication
Development
# Build
dotnet build
# Run tests
dotnet test
# Run tests with coverage
dotnet test --collect:"XPlat Code Coverage"
# Pack for NuGet
dotnet pack src/Felloh/Felloh.csproj --configuration Release
License
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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
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 |
|---|---|---|
| 0.1.0 | 2 | 4/1/2026 |