Skip to content

VladSh77/l10n-pl-ksef-margin

Repository files navigation

Odoo 17 KSeF Integration — VAT Marża Edition

Odoo Version Python KSeF License Status

Developed by Fayna Digital for CampScout Author: Volodymyr Shevchenko


Professional integration between Odoo 17 Community and the Polish National e-Invoicing System (KSeF 2.0).

Built specifically to support VAT Marża (tourist margin scheme) — a procedure critical for travel agencies in Poland, missing from standard EDI solutions.


Features

  • KSeF 2.0 API — full compliance with the latest Polish e-invoicing standard
  • FA(3) XML — generates structured invoices per schema http://crd.gov.pl/wzor/2025/06/25/13775/
  • VAT Marża — automatic detection and tagging (P_PMarzy + P_PMarzy_3_3 for travel agencies)
  • Secure Auth — RSA-OAEP token encryption + AES-256-CBC invoice encryption via ksef-client SDK
  • Outbound — send customer invoices to KSeF directly from Odoo invoice form
  • Inbound Buffer — sync incoming vendor invoices from KSeF into an isolated buffer (no accounting clutter)
  • Test & Production environments configurable per company

Architecture

l10n_pl_ksef_margin/
├── models/
│   ├── account_move.py       # Outbound: FA(3) XML generation + KSeF send
│   ├── ksef_vendor_buffer.py # Inbound: sync & buffer for vendor invoices
│   └── res_company.py        # Company fields: KSeF token + environment
├── views/
│   ├── account_move_views.xml        # KSeF tab on invoice form
│   └── ksef_vendor_buffer_views.xml  # Tree/form + menu + sync action
└── security/
    └── ir.model.access.csv

Tech Stack

Component Technology
ERP Framework Odoo 17.0 Community
KSeF API KSeF 2.0 (api-test.ksef.mf.gov.pl, api.ksef.mf.gov.pl)
Python SDK ksef-client 0.8.0
Encryption RSA-OAEP (auth) + AES-256-CBC (invoice) — automatic
Invoice Schema FA(3) — crd.gov.pl/wzor/2025/06/25/13775
VAT Margin P_PMarzy + P_PMarzy_3_3 (biura podróży)

Installation

1. Install Python dependency

pip install ksef-client

Note: ksef-client installs cryptography 46.x. If you have an older Odoo stack, upgrade dependencies first:

pip install --upgrade pyOpenSSL urllib3 requests

2. Add module to addons path

# Clone the repository
git clone https://github.com/VladSh77/odoo17-l10n_pl_ksef_margin.git /opt/odoo/addons/odoo17-l10n_pl_ksef_margin

Add to odoo.conf:

addons_path = ...,/opt/odoo/addons/odoo17-l10n_pl_ksef_margin

3. Install via Odoo UI

Apps → Update Apps List → search ksef → Install

4. Restart Odoo

docker restart <odoo_container_name>
# or
systemctl restart odoo

Configuration

Step 1 — Generate KSeF Token

  1. Go to ksef.mf.gov.pl (or ksef-test.mf.gov.pl for testing)
  2. Log in with Profil Zaufany or qualified electronic signature
  3. Navigate to Tokeny → Generuj token
  4. Select required permissions:
    • wystawianie faktur (InvoiceWrite) — for sending invoices
    • przeglądanie faktur (InvoiceRead) — for syncing incoming invoices
  5. Copy the generated token

Step 2 — Configure in Odoo

Settings → Companies → [your company] → General Information

Field Value
KSeF API Token paste token from ksef.mf.gov.pl
KSeF Environment Test or Production

Usage

Send invoice to KSeF (outbound)

  1. Accounting → Invoices — open a posted customer invoice
  2. Go to tab KSeF
  3. Click Wyślij do KSeF
  4. Status changes: Not SentWaitingAccepted
  5. KSeF Reference Number (KSeF ID) is saved on the invoice

Sync incoming invoices (inbound)

  1. Accounting → KSeF → Faktury Przychodzące
  2. Click Synchronizuj z KSeF
  3. New vendor invoices from KSeF appear in the buffer list
  4. Review and process as needed (buffer is isolated — does not affect accounting until manually processed)

VAT Marża — How It Works

For invoices with the margin scheme (travel agencies, tourist services):

  • The module detects margin-type tax lines automatically
  • Adds <P_PMarzy>1</P_PMarzy> to the FA(3) XML
  • For travel agencies (biura podróży): also adds <P_PMarzy_3_3>1</P_PMarzy_3_3>
  • These flags are required by KSeF for correct classification under Art. 119 of the VAT Act

KSeF 2.0 Auth Flow (technical)

1. GET /auth/challenge/{nip}         → challenge token
2. Encrypt: RSA-OAEP(token|timestamp, KSeF_public_key)
3. POST /auth/initialise             → session reference
4. GET /auth/status/{reference}      → poll until Authorised
5. GET /auth/token/{reference}       → redeem accessToken

All handled automatically by ksef-client SDK via AuthCoordinator.authenticate_with_ksef_token().


KSeF 2.0 Send Flow (technical)

1. GET /common/publicKey             → fetch KSeF RSA public certificate
2. POST /online/Session/InitUpload   → open session (AES-256-CBC key encrypted with RSA)
3. POST /online/Invoice/Send         → send AES-encrypted FA(3) XML invoice
4. POST /online/Session/Terminate    → close session

All handled automatically by OnlineSessionWorkflow.


Local Development (Docker)

# Clone and start
git clone https://github.com/VladSh77/odoo17-l10n_pl_ksef_margin.git
cd odoo17-l10n_pl_ksef_margin
docker-compose up

# Open http://localhost:8070
# Install ksef-client inside container:
docker exec -u root <container_id> pip install ksef-client

# Restart to apply
docker restart <container_id>

Then in Odoo: Apps → Update Apps List → search ksef → Install


Troubleshooting

Error Cause Fix
ValueError: Wrong value for ir.module.module.license Old Odoo cached manifest docker restart <odoo_container> then Update Apps List
AttributeError: module 'cryptography.utils' has no attribute 'Buffer' pyksef incompatible with cryptography≥42 Module uses ksef-client instead — ensure no old pyksef installed
ImportError: lxml.html.clean lxml 6.x installed Rebuild container: docker-compose down && docker-compose up
500 Internal Server Error after pip install ksef-client cryptography 46.x breaks pyOpenSSL 21 pip install --upgrade pyOpenSSL urllib3 requests
ParseError: attrs not used since 17.0 Views written for Odoo 16 syntax Use invisible="..." instead of attrs="{'invisible':...}"
Module not visible in Apps addons_path not configured Add module path to odoo.confaddons_path

Accountant Access

To give an accountant access to KSeF features:

  1. Settings → Users → [accountant user]
  2. Ensure role: Accounting / Accountant (or higher)
  3. The KSeF menu (Faktury Przychodzące) and KSeF tab on invoices are visible to all users with Accounting access
  4. Only users with Accounting / Administrator can modify KSeF token settings

License

Apache 2.0 — see LICENSE


Developed by Fayna Digital · Volodymyr Shevchenko

About

Odoo 17 integration with Polish KSeF 2.0 e-invoicing — FA(3) XML, VAT Marża, RSA/AES encryption

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors