eFakt™
English

Early version, being tested on the UJP test environment

E-invoicing to UJP without the headache.

eFakt is a desktop app for the UJP electronic invoicing system. It runs on Windows, macOS and Linux, signs with your certificate and keeps outgoing and incoming documents in one place.

Everything at a glance

What you issued and received, the VAT difference, what is waiting for your decision and which buyer has not answered yet.

The eFakt Overview screen: totals of issued and received invoices, VAT difference, a daily chart, documents waiting for an answer and top buyers.
Demo mode with made-up data. The app is also available in English.

The whole life of a document, in one app

Outgoing invoices

  1. Issue

    Enter the items. The app calculates VAT and totals using the UJP code lists.

  2. Sign

    The document is signed on your computer, with your qualified certificate.

  3. Send

    The invoice goes straight to UJP. You get an EUID, a status and a QR link.

  4. Cancel or correct

    A sent invoice can't be deleted. The app prepares a cancellation or correction that references the original.

Incoming invoices

  1. Receive

    See the invoices other companies have sent you, with the PDF and the original signed document.

  2. Accept or reject

    A rejection carries a reason from the UJP code list and your comment.

  3. Allocate input VAT

    Enter the taxable base and VAT per indicator, for your right to deduct.

Also: taxpayer lookup by EDB, NBRM exchange rates, every code list, status history, and PDF and ASiC downloads.

What you need before your first invoice

The app uses the same details as the UJP portal.

  • Your company's EDB (tax number).
  • Access to the UJP e-Faktura system and your eUJP identifier.
  • A qualified e-signature certificate: a .p12 file, a USB token or a smart card.

No certificate yet? You can look up taxpayers and code lists without one.

Your signing key stays with you

Signing happens locally. The private key never leaves your computer or token, and the PIN isn't stored: it lives in memory only while the app is open.

Your data stays with you

eFakt is an application on your computer, not a web service. Without add-ons, your invoices, certificate and PIN never pass through us.

We have no access to your invoices, customers, certificates or passwords.

In your language

The app is in Macedonian, with English, Albanian, Serbian and Turkish. Switch the language from the menu, no restart needed.

For developers

The same SDK, for your software

Every call the app makes to UJP goes through our SDK: signing, sending, lists, cancellations, corrections and code lists. If you run your own ERP or accounting software, you can buy the same SDK and build it in.

SDKs for Rust, TypeScript, Python, PHP, .NET, Java, and Go — guides and examples on the developer page.

Sending an invoice with a USB token
import { UjpClient, Pkcs11Signer } from "@rid/efakt";

const signer = await Pkcs11Signer.open({
  module: "/usr/lib/opensc-pkcs11.so",
  pin,
});

const ujp = new UjpClient({
  environment: "test",
  edb, eujpId,
  signer,
});

const sent = await ujp.sendInvoice(invoice);
console.log(sent.euid, sent.qrLink);
from efakt import Environment, Pkcs11Signer, UjpClient

signer = Pkcs11Signer.open(
    module="/usr/lib/opensc-pkcs11.so",
    pin=pin,
)

ujp = UjpClient(
    environment=Environment.TEST,
    edb=edb, eujp_id=eujp_id,
    signer=signer,
)

sent = ujp.send_invoice(invoice)
print(sent.euid, sent.qr_link)
<?php
use Rid\Efakt\{Environment, Pkcs11Signer, UjpClient};

$signer = Pkcs11Signer::open(
    module: '/usr/lib/opensc-pkcs11.so',
    pin: $pin,
);

$ujp = new UjpClient(
    environment: Environment::Test,
    edb: $edb, eujpId: $eujpId,
    signer: $signer,
);

$sent = $ujp->sendInvoice($invoice);
echo $sent->euid, ' ', $sent->qrLink;
using Rid.Efakt;
using Rid.Efakt.Signing;

using var signer = Pkcs11Signer.Open(
    module: "/usr/lib/opensc-pkcs11.so",
    pin: pin);

var ujp = new UjpClient(new ClientConfig
{
    Environment = UjpEnvironment.Test,
    Edb = edb, EujpId = eujpId,
    Signer = signer,
});

var sent = await ujp.SendInvoiceAsync(invoice);
Console.WriteLine($"{sent.Euid} {sent.QrLink}");
import mk.rid.efakt.*;

var signer = Pkcs11Signer.open(
    "/usr/lib/opensc-pkcs11.so", pin);

var ujp = UjpClient.builder()
    .environment(Environment.TEST)
    .edb(edb).eujpId(eujpId)
    .signer(signer)
    .build();

var sent = ujp.sendInvoice(invoice);
System.out.println(sent.euid() + " " + sent.qrLink());
signer, err := efakt.OpenPKCS11(efakt.PKCS11{
	Module: "/usr/lib/opensc-pkcs11.so",
	PIN:    pin,
})
if err != nil {
	return err
}

ujp := efakt.NewClient(efakt.Config{
	Environment: efakt.Test,
	EDB:         edb,
	EUJPID:      eujpID,
	Signer:      signer,
})

sent, err := ujp.SendInvoice(ctx, invoice)
if err != nil {
	return err
}
fmt.Println(sent.EUID, sent.QRLink)
let signer = SignerSource::Pkcs11 {
    module: "/usr/lib/opensc-pkcs11.so".into(),
    slot_id: None,
    object_id_hex: None,
}.open(&pin)?;

let ujp = UjpClient::new(ClientConfig {
    environment: Environment::Test,
    edb, eujp_id,
    ..Default::default()
})?.with_signer(signer)?;

let sent = ujp.send_invoice(invoice).await?;
println!("{:?} {:?}", sent.euid, sent.qr_link);

Try the early version

The app is currently being tested on the UJP test environment. Write to us if you'd like to try it with your company.

  • Windows
  • macOSApple Silicon and Intel
  • Linux