# KSeF User Guide

## What is KSeF?

KSeF (Krajowy System e-Faktur) is the Polish national e-invoicing system. It enables businesses to send and receive invoices electronically through a government platform.

This integration allows you to:

- Upload invoices to the Polish KSeF system
- Retrieve invoices from KSeF
- Check upload and processing status
- Manage authentication tokens

## Prerequisites

Before using this integration, you need:

1. **Company Registration**
   - Valid Polish NIP (tax identification number)
   - Company registered in Polish tax system

2. **Digital Certificate**
   - XAdES-compatible certificate (podpis kwalifikowany)
   - Certificate issued by trusted certification authority
   - Certificate must match your company NIP

3. **API Access**
   - KSeF platform account
   - API credentials configured

## Foreign Currency Invoices (PLN VAT Conversion)

Per Polish law art. 106e ust. 11, when an invoice is issued in a foreign currency (not PLN), VAT amounts must also be shown in PLN using the previous business day exchange rate.

### How It Works

1. System detects invoice currency is not PLN
2. Fetches previous business day exchange rate from currency import plugin
3. Converts each VAT rate amount to PLN
4. Adds PLN VAT fields to XML (`P_14_1W`, `P_14_2W`, `P_14_3W`, `P_14_4W`, `KursWalutyZ`)

### VAT Rate Category Mapping

KSeF uses rate **categories** (not percentages). The mapping is configurable in `rec.json`:

| KSeF Category | Description | Current Rates | XML Tags |
|---------------|-------------|---------------|----------|
| 1 | Basic rate | 23%, 22% | P_13_1, P_14_1, P_14_1W |
| 2 | Reduced rate 1 | 8%, 7% | P_13_2, P_14_2, P_14_2W |
| 3 | Reduced rate 2 | 5%, 4% | P_13_3, P_14_3, P_14_3W |
| 4 | Taxi lump sum | - | P_13_4, P_14_4, P_14_4W |

When Poland changes VAT rates, only the mapping in `rec.json` needs updating - no code changes.

### Other KSeF VAT Fields (no PLN conversion)

| Field | Description |
|-------|-------------|
| P_13_5 | Special procedure (section XII chapter 6a) |
| P_13_6_1 | 0% rate (excl. WDT and export) |
| P_13_6_2 | 0% intra-community supply (WDT) |
| P_13_6_3 | 0% export |
| P_13_7 | Exempt from tax (zwolnione) |
| P_13_8 | Services outside Poland territory |
| P_13_9 | Services per art. 100 |
| P_13_10 | Reverse charge procedure |
| P_13_11 | Margin procedure (art. 119, 120) |

### Configuration

In `form/nc/erp-sync/ksef/rec.json`:

```text
vat_percent_to_ksef:
  "23": 1, "22": 1   # basic rate
  "8": 2, "7": 2     # reduced rate 1
  "5": 3, "4": 3     # reduced rate 2
```

If an invoice has a VAT rate not in this mapping, the export stops with an error showing the rate and order ID.

## Configuration

### Connection Settings

The KSeF integration uses these settings:

| Setting | Value |
|---------|-------|
| **System Name** | KSeF Poland |
| **Organization ID** | ksef |
| **Environment** | Test, Demo, or Production |

### KSeF Environments

KSeF provides three environments:

| Environment | Code | URL | Purpose |
|-------------|------|-----|---------|
| **Test** | TEST | `https://ksef-test.mf.gov.pl` | Development and testing |
| **Demo** | DEMO | `https://ksef-demo.mf.gov.pl` | Pre-production validation |
| **Production** | PRD | `https://ksef.mf.gov.pl` | Real invoices with legal validity |

### Adding Test and Production Accounts

To configure KSeF accounts, you need to edit the database configuration files.

#### 1. Configure Connection

Edit `preference/database/connection/rest-ksef.json`
Add to database: `"auth_preference": "database/connection/auth-ksef.json"`

#### 2. Configure Organization

Edit `preference/database/organization/ksef.json`:

```json
{
  "name": "database/organization/ksef.json",
  "organization": "ksef",
  "database": [
    {
      "show": "KSeF Test",
      "alias_id": "ksef-test",
      "connection": "database/connection/rest-ksef.json",
      "connection_name": "KSeF Poland test",
      "status": "active"
    },
    {
      "show": "KSeF Production",
      "alias_id": "ksef",
      "connection": "database/connection/rest-ksef.json",
      "connection_name": "KSeF Poland production",
      "status": "inactive"
    }
  ]
}
```

#### 3. Create Authentication Files

Create auth preference files (location varies by system configuration):

**Test environment** - `auth-ksef-test.json`:

```json
{
  "name": "auth-ksef-test.json",
  "certificate_path": "/path/to/test-certificate.pfx",
  "certificate_password": "test-password",
  "nip": "0000000000"
}
```

**Production environment** - `auth-ksef.json`:

```json
{
  "name": "auth-ksef.json",
  "certificate_path": "/path/to/certificate.pfx",
  "certificate_password": "your-password",
  "nip": "1234567890"
}
```

### Required Credentials

For each KSeF environment, you need:

| Field | Description | Example |
|-------|-------------|---------|
| **nip** | Tax identification number (10 digits) | `1234567890` |
| **certificate_path** | Path to XAdES certificate file | `/path/to/cert.pfx` |
| **certificate_password** | Certificate password | `your-password` |
| **token_ksef** | KSeF token (optional alternative) | `generated-token` |

### Certificate Requirements

**For Test Environment**:

- Self-signed certificates are allowed
- Use test NIP values (random 10-digit numbers)
- No validation with certification authority

**For Production Environment**:

- Qualified electronic certificate (podpis kwalifikowany)
- Certificate must contain your company NIP
- Issued by trusted certification authority
- Certificate must be valid (not expired)

### Authentication Methods

KSeF supports two authentication methods:

1. **XAdES Digital Signature** (recommended for production)
   - Uses qualified certificate
   - Certificate must match company NIP
   - Certificate is verified against OCSP/CRL services

2. **KSeF Token** (alternative)
   - Generated after initial XAdES authentication
   - Encrypted token stored securely
   - Can be used for subsequent logins

### Test Data Setup

For testing, you can use the official KSeF test endpoints to create test scenarios:

- Create test persons/companies via `/v2/testdata/person`
- Set up VAT groups via `/v2/testdata/subject`
- Configure permissions via `/v2/testdata/permissions`

Example test NIP values (from official documentation):

- `7980332920` - Test person (JDG)
- `3755747347` - Test VAT group

### Switching Between Environments

1. **To enable production**:
   - Set `status: "active"` in `ksef.json` for production entry
   - Set `status: "inactive"` for test entry

2. **To switch back to test**:
   - Reverse the status settings

3. **Restart** the application after changes

**Important**: Never use test credentials in production. Always keep test and production certificates separate.

## Using the Integration

### Tabs Overview

The integration has 4 main tabs:

| Tab | Icon | Purpose |
|-----|------|---------|
| **Invoice** | sync | Upload to and retrieve from KSeF (dual-direction) |
| **Invoice metadata** | clock | View invoice processing status |
| **Token** | key | View authentication tokens |
| **Session status** | tasks | Check upload session status |

### Tab: Invoice

**Purpose**: Upload invoices to KSeF OR retrieve invoices from KSeF

This single tab handles both operations:

- **Import (Download)**: Retrieve invoices from KSeF
- **Export (Upload)**: Send local invoices to KSeF

**Key Fields**:

| Field | Description |
|-------|-------------|
| `ord.order_id` | Local invoice identifier |
| `ord.json_data.transfer_id` | KSeF invoice number (after upload) |
| `ord.company_reference_number` | Your invoice number |
| `ord.json_data.nip` | Seller's tax identification number |
| `ord.order_date` | Invoice issue date |
| `ord.price_without_vat` | Gross amount |
| `ord.currency_id` | Invoice currency (PLN default) |
| `ord.json_data.processing_status` | Processing state |

**Actions - Import (Download)**:

1. Enter KSeF number (or your invoice number)
2. Click Import
3. System retrieves invoice data from KSeF
4. Compare with local data in dual-panel view

**Actions - Export (Upload)**:

1. Select local invoice to upload
2. Click Export
3. System will:
   - Authenticate with KSeF
   - Open upload session
   - Upload invoice data
   - Receive KSeF number
   - Update local record with KSeF number
4. Verify status in Session Status tab

**Dual-Panel View**:

- Left panel: Local invoice data (NC `order` table)
- Right panel: KSeF invoice data (from API)
- Status column shows if records match or differ

### Tab: Invoice Metadata

**Purpose**: View processing status and timestamps for uploaded invoices

**Key Fields**:

| Field | Description |
|-------|-------------|
| `ord.json_data.transfer_id` | KSeF invoice number |
| `ord.json_data.processing_status` | Current processing state |
| `ord.json_data.receipt_timestamp` | When KSeF received the invoice |
| `ord.json_data.upload_timestamp` | Upload completion time |
| `ord.json_data.verification_timestamp` | Verification completion time |
| `ord.json_data.modification_timestamp` | Last modification time |

**Processing Status Values**:

- `NEW` - New upload, not yet processed
- `PROCESSING` - Being processed by KSeF
- `COMPLETED` - Successfully processed
- `ERROR` - Processing failed

**Usage**:

- Check status after uploading invoices
- Monitor processing progress
- Verify successful uploads
- Audit trail with timestamps

### Tab: Token

**Purpose**: View authentication tokens

**Key Fields**:

| Field | Description |
|-------|-------------|
| `prf.name_id` | Token identifier |
| `prf.json_data.transfer_id` | Token ID from KSeF |
| `prf.json_data.nip` | NIP of token issuer |
| `prf.json_data.active` | Whether token is active |
| `prf.json_data.expiry_time` | Token expiration date |

**Note**: Tokens are managed automatically by the system.

### Tab: Session Status

**Purpose**: Check upload session status

**Key Fields**:

| Field | Description |
|-------|-------------|
| `prf.name_id` | Session identifier |
| `prf.json_data.reference_number` | KSeF reference number |
| `prf.json_data.session_status` | Session state |
| `prf.json_data.processing_status` | Upload processing status |

**Session Status Values**:

- `OPEN` - Session ready for upload
- `CLOSED` - Session completed
- `ERROR` - Session failed

## Workflow Examples

### Uploading an Invoice to KSeF

1. **Navigate to Invoice tab**
2. **Select local invoice** to upload
3. **Click Export**
4. **System will:**
   - Authenticate with KSeF
   - Open upload session
   - Upload invoice data
   - Receive KSeF number
   - Update `ord.json_data.transfer_id` with KSeF number
   - Close session
5. **Verify status** in Session Status tab
6. **Check metadata** to confirm processing

### Retrieving an Invoice from KSeF

1. **Navigate to Invoice tab**
2. **Enter KSeF number** (or your invoice number)
3. **Click Import**
4. **System retrieves** invoice data from KSeF
5. **View comparison** in dual-panel grid:
   - Left: Local data
   - Right: KSeF data

### Checking Upload Status

1. **After upload**, go to Session Status tab
2. **Find your session** by reference number
3. **Check status**:
   - `PROCESSING` - Still being processed
   - `COMPLETED` - Successfully uploaded
   - `ERROR` - Upload failed
4. **Check Invoice Metadata tab** for detailed timestamps

## Data Storage

All KSeF data is stored in standard NC tables:

| KSeF Data Type | NC Table | Record Type | Key Fields |
|----------------|----------|-------------|------------|
| Invoice headers | `order` | `invoice` | `ord.json_data.transfer_id` |
| Invoice rows | `order_row` | `invoice` | `ordr.order_row_id` |
| Customers | `company` | `customer` | `co.company_id` |
| Products | `product` | (empty) | `pr.product_id` |
| Payment terms | `terms_of_payment` | (empty) | `top.terms_of_payment_id` |
| Tokens/Sessions | `preference` | `ksef` | `prf.name_id` |

## Security Notes

- Certificates are stored securely
- Tokens are managed automatically
- Never share certificate private keys
- Use test environment for development
- Monitor for unauthorized access

## Support

For issues with:

- **Integration**: Contact your system administrator
- **KSeF Platform**: Visit <https://www.podatki.gov.pl/ksef/>
- **Certificates**: Contact your certification authority

## Data Retention

- Uploaded invoices remain in KSeF system
- Local records are kept according to your retention policy
- Tokens expire and are renewed automatically

## Best Practices

1. **Always start in test environment** before using production
2. **Verify uploads** by checking session status
3. **Keep certificates valid** - renew before expiry
4. **Monitor processing status** after uploads
5. **Backup local data** regularly
6. **Use unique invoice numbers** to avoid conflicts

## Glossary

| Term | Meaning |
|------|---------|
| **KSeF** | Krajowy System e-Faktur (Polish e-invoicing system) |
| **NIP** | Numer Identyfikacji Podatkowej (Tax ID) |
| **XAdES** | XML Advanced Electronic Signature |
| **KSeF Number** | System-assigned invoice identifier |
| **Session** | Temporary connection for uploading invoices |
| **Transfer ID** | KSeF reference number stored in `json_data.transfer_id` |
