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" />
                    
Directory.Packages.props
<PackageReference Include="Felloh" />
                    
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 Felloh --version 0.1.0
                    
#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
                    
Install as a Cake Addin
#tool nuget:?package=Felloh&version=0.1.0
                    
Install as a Cake Tool

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);
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 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