How to Tame KSeF: A Case Study of a PHP Bot That Downloads Your Invoices for You
The introduction of the National e-Invoicing System (KSeF) is one of the biggest digital revolutions for Polish businesses. On one hand, it’s a step into the future. On the other, it’s a new, significant challenge. Imagine having to manually download and archive hundreds of sales and purchase invoices every month. This process is not only tedious but also carries a huge risk of errors, which can be costly in accounting.
This was the exact challenge a client brought to me. They needed a reliable way to get rid of this new, burdensome obligation. My task was to create a quiet and reliable employee—a fully automated tool in PHP that could cyclically, without any human intervention, connect to KSeF and archive all documents.
The Architectural Challenge: Flexibility is Key
The most interesting problem to solve wasn’t the API communication itself, but ensuring flexibility. The system had to work for different companies, some of which wanted to use a simpler API token, while others required a more secure, official electronic seal (a .p12 certificate).
Instead of writing two separate programs or creating complex conditional logic, I opted for a proven, elegant architectural solution—the Factory Design Pattern. I created one intelligent “factory” that reads a configuration file and, based on it, “produces” and returns a perfectly configured API client on its own—either with a token or a certificate. This approach not only made the code cleaner but also made adding another authentication method in the future trivially simple.
The Heart of the Automation: Code That Builds the Right Connection
I based the entire solution on a modern tech stack with PHP 8.1+, using Composer for dependency management and the n1ebieski/ksef-php-client library as the foundation for communication. The key, however, is the aforementioned “factory.” The following code snippet shows how, based on a single setting in the configuration, the function dynamically builds a client ready for work.
use N1ebieski\KSEFClient\Resources\ClientResource;
use N1ebieski\KSEFClient\ClientBuilder;
use N1ebieski\KSEFClient\ValueObjects\Mode;
function createKsefClient(string $nip): ClientResource
{
// ... (setting the mode: Test, Demo, Production) ...
$clientBuilder = (new ClientBuilder())
->withMode($mode)
->withNIP($nip);
// Key moment: I check the selected authentication method
$authType = strtolower($_ENV['KSEF_AUTH_TYPE'] ?? 'token');
// The "factory" decides how to build the client object
if ($authType === 'certificate') {
$clientBuilder->withCertificatePath(
$_ENV['PATH_TO_CERTIFICATE'],
$_ENV['CERTIFICATE_PASSPHRASE']
);
} else {
$clientBuilder->withApiToken($_ENV['KSEF_TOKEN']);
}
return $clientBuilder->build();
}
The Result: Time Reclaimed and 100% Certainty
The most important result of this tool is the transformation of a stressful duty into an invisible, fully automated process. Instead of hours spent manually downloading invoices, the client gained assurance that all documents are archived on time and without errors.
This directly translates into saving resources—time and money. The team that previously had to keep track of invoices can now focus on tasks that bring real business value. The system guarantees 100% data completeness, which is invaluable for accounting and reporting processes.
This project is proof that my goal is to deliver not just working code, but well-thought-out, reliable, and flexible tools. Focusing on clean architecture and good configuration resulted in a solution that is ready to be deployed and can bring measurable benefits in any business environment.
Is your company facing new requirements that generate repetitive, manual work? Do you need to automate processes related to KSeF or other systems to reclaim valuable time?
Contact me, and together we will find a solution tailored to your needs.
