Programming services

How to tame KSeF

A company required to use KSeF · Accounting / e-invoicing

Obraz przedstawiający dokument z symbolem pobierania, symbol API oraz robota/trybika.

The challenge

Poland's National e-Invoicing System (KSeF) is one of the biggest digital shake-ups for local companies. A step into the future on one hand – a new challenge on the other: manually downloading and archiving hundreds of invoices every month. Tedious, and prone to errors that can be costly in accounting.

There was a second catch. The KSeF integration was offered by ready-made accounting software – but to use it, you had to buy that software and lock yourself into someone else's ecosystem. This client had their own systems, tailored to their needs. They did not want to overpay for yet another program just to get one feature. My job was to build an integration straight into their environment – a quiet, automatic “worker” in PHP that periodically connects to KSeF and archives documents where the company actually needs them.

What I did

The most interesting problem was not the API communication itself, but flexibility. The tool had to work for different setups: some firms prefer a simpler API token, others the more secure electronic seal (a .p12 certificate).

Instead of writing two separate programs or tangling myself in conditional logic, I reached for an elegant design pattern – the Factory Pattern. One smart “factory” reads a config file and “produces” a perfectly configured API client on its own – with a token or a certificate. The code stays clean, and adding another authentication method in the future will be trivial.

I built it on a modern PHP 8.1+ stack, with Composer and the n1ebieski/ksef-php-client library as the foundation for communication:

use N1ebieskiKSEFClientResourcesClientResource;
use N1ebieskiKSEFClientClientBuilder;

function createKsefClient(string $nip): ClientResource
{
    $clientBuilder = (new ClientBuilder())
        ->withMode($mode)
        ->withNIP($nip);
    // Fabryka sprawdza wybraną metodę uwierzytelniania
    $authType = strtolower($_ENV['KSEF_AUTH_TYPE'] ?? 'token');
    if ($authType === 'certificate') {
        $clientBuilder->withCertificatePath(
            $_ENV['PATH_TO_CERTIFICATE'],
            $_ENV['CERTIFICATE_PASSPHRASE']
        );
    } else {
        $clientBuilder->withApiToken($_ENV['KSEF_TOKEN']);
    }
    return $clientBuilder->build();
}

The result

A stressful obligation turned into an invisible, automatic process. Instead of hours of manually downloading invoices – the certainty that every document is archived on time, error-free, and inside the company's own systems rather than someone else's program. The system guarantees 100% data completeness, which is invaluable for accounting and reporting.

Most importantly: the company did not have to buy another piece of software just to meet a single requirement. They got an integration tailored to their environment – cheaper to maintain and fully under their control. Because sometimes the best solution is not another off-the-shelf program, but a tool built exactly around what you already have.

Back to work

Got a project to talk about?

Just tell me what you need - it does not have to be technical, that is my job. I will get back to you and tell you straight whether and how I can help.