RomaniaEFacturaLibrary 2.0.0
dotnet add package RomaniaEFacturaLibrary --version 2.0.0
NuGet\Install-Package RomaniaEFacturaLibrary -Version 2.0.0
<PackageReference Include="RomaniaEFacturaLibrary" Version="2.0.0" />
<PackageVersion Include="RomaniaEFacturaLibrary" Version="2.0.0" />
<PackageReference Include="RomaniaEFacturaLibrary" />
paket add RomaniaEFacturaLibrary --version 2.0.0
#r "nuget: RomaniaEFacturaLibrary, 2.0.0"
#:package RomaniaEFacturaLibrary@2.0.0
#addin nuget:?package=RomaniaEFacturaLibrary&version=2.0.0
#tool nuget:?package=RomaniaEFacturaLibrary&version=2.0.0
Romania EFactura Library v2.0.0
A comprehensive C# library for integrating with the Romanian EFactura (SPV - Spatiu Privat Virtual) system from ANAF. Now with flexible token storage and enhanced security features.
๐ What's New in v2.0.0
- ๐ Flexible Token Storage: Choose between MemoryCache, Cookie, or custom storage
- ๐ CIF as Parameters: CIF is now passed as method parameters instead of configuration
- ๐ก๏ธ Enhanced Security: Secure cookie options and automatic token cleanup
- ๏ฟฝ Comprehensive Examples: Complete controller examples for all operations
- ๐ง Better API Design: Internal API client, cleaner public interface
- ๐งช Extensive Testing: Comprehensive unit test coverage
๐ Quick Links
- ๐ Token Storage Guide - Complete token management guide
- โ๏ธ Configuration Guide - All configuration options
- ๐ฆ Publishing Guide - NuGet publishing instructions
- ๐ Project Summary - Complete project overview
- ๐ Example Controllers - Ready-to-use API controllers
Overview
This library provides a complete solution for:
- ๐ OAuth2 Authentication with flexible token storage (MemoryCache/Cookie)
- ๐ UBL 2.1 XML invoice creation and validation
- ๐ API Integration with ANAF test and production environments
- ๐ Invoice Management (upload, download, status tracking, bulk operations)
- ๐ XML Processing with proper namespace handling and validation
- ๐ก๏ธ Security Features with automatic token refresh and secure storage
๐ Repository Structure
RomaniaEFacturaLibrary/
- Main library with all EFactura functionalityServices/TokenStorage/
- Flexible token storage implementationsServices/Api/
- Internal ANAF API client (now internal)Services/
- Public EFactura client and services
Examples/Controllers/
- Complete controller examplesAuthenticationController.cs
- OAuth2 authentication flowInvoiceController.cs
- Invoice validation and uploadInvoiceManagementController.cs
- Download and management
RomaniaEFacturaLibrary.Tests/
- Comprehensive test suiteTokenStorage/
- Token storage service testsServices/
- Client and service tests
RomaniaEFacturaConsole/
- Interactive console application- Documentation:
TokenStorageGuide.md
- Complete token storage guideIMPLEMENTATION_GUIDE.md
- Step-by-step implementationCONFIGURATION_GUIDE.md
- Configuration reference
โจ Features
๐ Authentication & Token Management
- OAuth2 Authorization Flow with ANAF
- Flexible Token Storage:
- MemoryCache (server-side, fast)
- Cookie (client-side, persistent)
- Custom storage (database, Redis, etc.)
- Automatic Token Refresh with 5-minute buffer
- User-Isolated Storage based on HttpContext
- Secure Cookie Options (HttpOnly, Secure, SameSite)
๐ UBL 2.1 XML Support
- Complete UBL 2.1 invoice models
- Proper XML serialization/deserialization
- Romanian EFactura-specific customizations
- XML validation and formatting
- PDF conversion support
๐ ANAF API Integration
- Upload Invoices to ANAF SPV with validation
- Download Invoices in multiple formats (XML, PDF, raw ZIP)
- Status Tracking with real-time monitoring
- Bulk Operations for multiple invoice management
- Search and Filter invoices by criteria
- Support for test and production environments
๐ง Developer Experience
- Comprehensive Examples with ready-to-use controllers
- Extensive Documentation and usage guides
- Unit Test Coverage for all major components
- Dependency Injection support with multiple configuration options
- Internal API Design - clean public interface
- List recent invoices with filtering
๐ Quick Start
1. Installation
Install via NuGet Package Manager:
<PackageReference Include="RomaniaEFacturaLibrary" Version="2.0.0" />
Or via Package Manager Console:
Install-Package RomaniaEFacturaLibrary -Version 2.0.0
2. Configuration
Configure in appsettings.json
:
{
"EFactura": {
"BaseUrl": "https://api.anaf.ro/prod/FCTEL/rest",
"ClientId": "your-anaf-client-id",
"ClientSecret": "your-anaf-client-secret",
"RedirectUri": "https://yourapp.com/auth/callback",
"Scope": "efactura"
}
}
3. Service Registration
Choose your preferred token storage method:
Option A: MemoryCache Storage (Default)
// In Program.cs
builder.Services.AddEFacturaServices(builder.Configuration);
// or
builder.Services.AddEFacturaServicesWithMemoryCache(config =>
{
config.BaseUrl = "https://api.anaf.ro/prod/FCTEL/rest";
config.ClientId = "your-client-id";
config.ClientSecret = "your-client-secret";
config.RedirectUri = "https://yourapp.com/auth/callback";
});
Option B: Cookie Storage
// In Program.cs
builder.Services.AddEFacturaServicesWithCookieStorage(builder.Configuration);
Option C: Custom Storage
// Implement your own storage
public class DatabaseTokenStorage : ITokenStorageService
{
// Your implementation...
}
// Register in DI
builder.Services.AddEFacturaServicesWithCustomStorage<DatabaseTokenStorage>(config =>
{
// Configuration...
});
4. Basic Usage
Note: In v2.0.0, CIF is now passed as a parameter to methods instead of configuration.
Authentication Flow
[ApiController]
public class AuthController : ControllerBase
{
private readonly IAuthenticationService _authService;
public AuthController(IAuthenticationService authService)
{
_authService = authService;
}
[HttpGet("login")]
public IActionResult Login()
{
var authUrl = _authService.GetAuthorizationUrl(
clientId: "your-client-id",
redirectUri: "https://yourapp.com/auth/callback",
scope: "efactura"
);
return Redirect(authUrl);
}
[HttpGet("callback")]
public async Task<IActionResult> Callback(string code)
{
var token = await _authService.GetAccessTokenAsync(
code: code,
clientId: "your-client-id",
clientSecret: "your-client-secret",
redirectUri: "https://yourapp.com/auth/callback"
);
// Token is automatically stored
return Ok("Authentication successful");
}
}
Invoice Operations
[ApiController]
[Authorize]
public class InvoiceController : ControllerBase
{
private readonly IEFacturaClient _eFacturaClient;
public InvoiceController(IEFacturaClient eFacturaClient)
{
_eFacturaClient = eFacturaClient;
}
[HttpPost("validate")]
public async Task<IActionResult> ValidateInvoice([FromBody] ValidateRequest request)
{
var result = await _eFacturaClient.ValidateInvoiceAsync(
invoice: request.Invoice,
cif: request.Cif // CIF now required as parameter
);
return Ok(result);
}
[HttpPost("upload")]
public async Task<IActionResult> UploadInvoice([FromBody] UploadRequest request)
{
var result = await _eFacturaClient.UploadInvoiceAsync(
invoice: request.Invoice,
cif: request.Cif,
environment: "prod" // Optional: "test" or "prod"
);
return Ok(result);
}
[HttpGet("messages")]
public async Task<IActionResult> GetMessages([FromQuery] string cif)
{
var messages = await _eFacturaClient.GetInvoicesAsync(
cif: cif,
from: DateTime.UtcNow.AddDays(-30),
to: DateTime.UtcNow
);
return Ok(messages);
}
[HttpGet("download/{messageId}")]
public async Task<IActionResult> DownloadInvoice(string messageId)
{
var invoice = await _eFacturaClient.DownloadInvoiceAsync(messageId);
return Ok(invoice);
}
[HttpGet("download/{messageId}/pdf")]
public async Task<IActionResult> DownloadPdf(string messageId)
{
var invoice = await _eFacturaClient.DownloadInvoiceAsync(messageId);
var pdfData = await _eFacturaClient.ConvertToPdfAsync(invoice);
return File(pdfData, "application/pdf", $"invoice_{messageId}.pdf");
}
}
public class AuthController : ControllerBase
{
private readonly IAuthenticationService _authService;
public AuthController(IAuthenticationService authService)
{
_authService = authService;
}
[HttpGet("login")]
public IActionResult Login()
{
// Step 1: Get authorization URL for ANAF OAuth
var authUrl = _authService.GetAuthorizationUrl("efactura", "unique-state");
return Redirect(authUrl);
}
[HttpGet("callback")]
public async Task<IActionResult> Callback(string code, string state)
{
// Step 2: Exchange authorization code for access token
var token = await _authService.ExchangeCodeForTokenAsync(code);
if (token != null)
{
// Store token securely (session, database, etc.)
_authService.SetToken(token);
return Ok("Authentication successful");
}
return BadRequest("Authentication failed");
}
}
public class InvoiceController : ControllerBase
{
private readonly IEFacturaClient _eFacturaClient;
public InvoiceController(IEFacturaClient eFacturaClient)
{
_eFacturaClient = eFacturaClient;
}
[HttpPost("upload")]
public async Task<IActionResult> UploadInvoice([FromBody] UblInvoice invoice)
{
// Upload to ANAF (token will be automatically used)
var result = await _eFacturaClient.UploadInvoiceAsync(invoice);
if (result.IsSuccess)
{
return Ok(new { UploadId = result.UploadId });
}
return BadRequest(result.Errors);
}
}
Testing
Run the test suite:
dotnet test RomaniaEFacturaLibrary.Tests
Use the console application for interactive testing:
cd RomaniaEFacturaConsole
dotnet run
Requirements
- .NET 9.0 or later
- ANAF Application Registration (ClientId and ClientSecret)
- Registered Redirect URI with ANAF for OAuth callback
Key Dependencies
Microsoft.Extensions.DependencyInjection
- Dependency injectionMicrosoft.Extensions.Logging
- Logging frameworkMicrosoft.Extensions.Http
- HTTP client factorySystem.Security.Cryptography.X509Certificates
- Certificate handlingSystem.Text.Json
- JSON serialization
Build Status
โ
Solution builds successfully
โ
All 29 unit tests pass
โ
Release configuration ready
โ
Multi-target support (.NET 8.0 and .NET 9.0)
โ
NuGet package ready
๐ Repository Information
- GitHub Repository: https://github.com/lucianbumb/RomaniaEFacturaSolution
- Package ID:
RomaniaEFacturaLibrary
- Current Version:
1.0.0
- License: MIT
Contributing
This library follows Romanian EFactura specifications and UBL 2.1 standards.
License
This project is provided as-is for educational and development purposes. Please ensure compliance with ANAF regulations and Romanian law when using in production.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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 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. |
-
net9.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Caching.Memory (>= 9.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Http (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Logging.Console (>= 9.0.0)
- Microsoft.Extensions.Logging.Debug (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.0)
- System.Security.Cryptography.X509Certificates (>= 4.3.2)
- System.Text.Json (>= 9.0.0)
- System.Xml.XmlSerializer (>= 4.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version 2.0.0: Major update with flexible token storage system (MemoryCache/Cookie), CIF parameters instead of configuration, comprehensive example controllers, enhanced security, and improved API design. Breaking changes: CIF now required as method parameters.