PHPackages                             developeritsme/fiscal-service - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. developeritsme/fiscal-service

ActiveLibrary

developeritsme/fiscal-service
=============================

Montenegro Fiscal Service

0.8.0(2mo ago)0452↓50%MITPHPPHP ^8.0

Since May 22Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/developeritsme/fiscal-service)[ Packagist](https://packagist.org/packages/developeritsme/fiscal-service)[ RSS](/packages/developeritsme-fiscal-service/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (9)Dependencies (4)Versions (12)Used By (0)

Montenegro Fiscal Service
=========================

[](#montenegro-fiscal-service)

PHP library for integrating with Montenegro's fiscal service (Poreska Uprava). Handles invoice registration, cash deposits, and terminal code (TCR) management.

Requirements
------------

[](#requirements)

- PHP 8.0 or higher
- Extensions: `xmlwriter`, `dom`, `openssl`, `curl`
- PKCS12 certificate from Montenegro Tax Authority

Installation
------------

[](#installation)

```
composer require developeritsme/fiscal-service
```

Usage
-----

[](#usage)

### Initialize the Fiscal Service

[](#initialize-the-fiscal-service)

```
use DeveloperItsMe\FiscalService\Fiscal;
use DeveloperItsMe\FiscalService\Certificate;

// From file (production)
$fiscal = Fiscal::fromFile('/path/to/certificate.pfx', 'certificate-password');

// From file (test environment)
$fiscal = Fiscal::fromFile('/path/to/certificate.pfx', 'certificate-password', true);

// From raw PKCS12 content
$fiscal = Fiscal::fromContent($pkcs12Content, 'certificate-password', true);

// From a pre-built Certificate instance
$certificate = Certificate::fromFile('/path/to/certificate.pfx', 'certificate-password');
$fiscal = Fiscal::fromCertificate($certificate, true);

// Check certificate expiration date
$expiresAt = $fiscal->certificate()->expiresAt(); // Returns DateTimeImmutable
```

### Register an Invoice

[](#register-an-invoice)

```
use DeveloperItsMe\FiscalService\Models\Invoice;
use DeveloperItsMe\FiscalService\Models\Item;
use DeveloperItsMe\FiscalService\Models\Seller;
use DeveloperItsMe\FiscalService\Models\Buyer;
use DeveloperItsMe\FiscalService\Models\PaymentMethod;
use DeveloperItsMe\FiscalService\Requests\RegisterInvoice;

// Create seller
$seller = new Seller('Company Name', '12345678', true); // name, TIN, isVAT
$seller->setAddress('Street Address')
    ->setTown('Podgorica');

// Create invoice (parameter: decimal precision for items, default 2)
$invoice = (new Invoice(4))
    ->setNumber(1)
    ->setEnu('ab123cd456')           // TCR code (format: xx000xx000)
    ->setBusinessUnitCode('bu123bu123') // format: xx000xx000
    ->setSoftwareCode('sw123sw456')     // format: xx000xx000
    ->setOperatorCode('op123op789')     // format: xx000xx000
    ->setSeller($seller);

// Add buyer (optional, required for non-cash invoices)
$buyer = new Buyer('Buyer Name', '87654321');
$buyer->setAddress('Buyer Street')
    ->setTown('Budva')
    ->setCountry('MNE');
$invoice->setBuyer($buyer);

// Add items
$item = (new Item())
    ->setName('Product Name')
    ->setCode('1234567890123') // barcode/SKU (optional)
    ->setUnit('pcs')
    ->setQuantity(2)
    ->setUnitPrice(10.00)
    ->setVatRate(21); // 0, 7, 15, or 21

$invoice->addItem($item);

// Add payment method
$total = 20.00;
$invoice->addPaymentMethod(new PaymentMethod($total, PaymentMethod::TYPE_BANKNOTE));

// Send to fiscal service
$request = new RegisterInvoice($invoice);
$response = $fiscal->request($request)->send();

if ($response->ok()) {
    $data = $response->data();
    // $data['ikof']   - Invoice identification code (IIC)
    // $data['jikr']   - Fiscal identification code (FIC)
    // $data['url']    - QR code verification URL
    // $data['number'] - Invoice number
}

// Access raw request/response XML
$xmlRequest = $response->request();
$xmlResponse = $response->body();
```

### Register a TCR (Terminal/Cash Register)

[](#register-a-tcr-terminalcash-register)

Register a TCR once through your application. Once registered, you receive an ENU code that can be used for all subsequent invoice requests.

```
use DeveloperItsMe\FiscalService\Models\BusinessUnit;
use DeveloperItsMe\FiscalService\Requests\RegisterTCR;

$businessUnit = (new BusinessUnit())
    ->setIdNumber('12345678')
    ->setUnitCode('bu123bu123')       // format: xx000xx000
    ->setSoftwareCode('sw123sw456')   // format: xx000xx000
    ->setMaintainerCode('mt123mt456') // format: xx000xx000
    ->setInternalId('internal-1');

$request = new RegisterTCR($businessUnit);
$response = $fiscal->request($request)->send();

if ($response->ok()) {
    $data = $response->data();
    // $data['code'] - Registered TCR code (ENU)
}
```

### Register a Cash Deposit

[](#register-a-cash-deposit)

Must be registered once per day before sending invoices.

```
use DeveloperItsMe\FiscalService\Models\CashDeposit;
use DeveloperItsMe\FiscalService\Requests\RegisterCashDeposit;
use Carbon\Carbon;

$cashDeposit = (new CashDeposit())
    ->setDate(Carbon::now())
    ->setIdNumber('12345678')
    ->setAmount(0) // initial amount in register
    ->setEnu('TCR-CODE')
    ->setOperation(CashDeposit::OPERATION_INITIAL);

$request = new RegisterCashDeposit($cashDeposit);
$response = $fiscal->request($request)->send();

if ($response->ok()) {
    $data = $response->data();
    // $data['fcdc'] - Fiscal cash deposit code
}
```

### Corrective Invoice

[](#corrective-invoice)

To correct a previously sent invoice:

```
use DeveloperItsMe\FiscalService\Models\CorrectiveInvoice;

// Reference the original invoice
$corrective = new CorrectiveInvoice(
    $originalIkof,           // IKOF of original invoice
    $originalDateTime        // DateTime of original invoice
);

$invoice = (new Invoice())
    // ... set other invoice properties
    ->setCorrectiveInvoice($corrective);

// Add items with negative quantities to reverse
$item = (new Item())
    ->setName('Product Name')
    ->setQuantity(-1) // negative to reverse
    ->setUnitPrice(10.00)
    ->setVatRate(21);

$invoice->addItem($item);
```

### Supply and Tax Periods

[](#supply-and-tax-periods)

For invoices covering a specific period:

```
// Supply period (for services/goods delivered over time)
$invoice->setSupplyPeriod('2025-01-01', '2025-01-31');

// Or single date
$invoice->setSupplyPeriod('2025-01-15');

// Tax period (format: MM/YYYY)
$invoice->setTaxPeriod('01/2025');
```

### Invoice Types

[](#invoice-types)

```
// Cash vs Non-cash (TypeOfInv)
$invoice->setMethod(Invoice::TYPE_CASH);     // Default
$invoice->setMethod(Invoice::TYPE_NONCASH);

// Invoice types (InvType)
$invoice->setInvoiceType(Invoice::TYPE_INVOICE);      // Regular invoice
$invoice->setInvoiceType(Invoice::TYPE_CORRECTIVE);   // Corrective invoice
$invoice->setInvoiceType(Invoice::TYPE_ADVANCE);      // Advance payment
$invoice->setInvoiceType(Invoice::TYPE_CREDIT_NOTE);  // Credit note
```

### Payment Methods

[](#payment-methods)

```
PaymentMethod::TYPE_BANKNOTE  // Cash
PaymentMethod::TYPE_CARD      // Card payment
PaymentMethod::TYPE_ACCOUNT   // Bank transfer
PaymentMethod::TYPE_ORDER     // Order/Check
PaymentMethod::TYPE_OTHER     // Other
```

### Error Handling

[](#error-handling)

```
use DeveloperItsMe\FiscalService\Exceptions\CertificateException;

try {
    $fiscal = Fiscal::fromFile('/path/to/cert.pfx', 'password');
} catch (CertificateException $e) {
    // Invalid certificate or wrong password
    $errors = $e->getOpensslErrors();
}

$response = $fiscal->request($request)->send();

if ($response->failed()) {
    $error = $response->error();   // Error message (includes connection errors like timeouts)
    $errors = $response->errors(); // Detailed errors array
}
```

### Array Serialization

[](#array-serialization)

All models support `toArray()` for inspection, logging, or JSON encoding. Validation runs automatically before serialization.

```
$arr = $invoice->toArray();
// ['uuid' => '...', 'number' => 'bu001/1/2025/en001', 'seller' => [...], 'items' => [...], ...]

json_encode($invoice->toArray());
```

### Request Timeouts

[](#request-timeouts)

```
$request = new RegisterInvoice($invoice);
$request->timeout(60);         // Total timeout in seconds (default: 30)
$request->connect_timeout(15); // Connection timeout in seconds (default: 10)
```

License
-------

[](#license)

MIT

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance84

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~174 days

Recently: every ~6 days

Total

11

Last Release

82d ago

PHP version history (2 changes)0.1.0-alphaPHP ^7.3|^8.0

0.5.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3b958247c4209402873f204ce8924dd9c818f6b3d6872441235531276557489a?d=identicon)[developeritsme](/maintainers/developeritsme)

---

Top Contributors

[![developeritsme](https://avatars.githubusercontent.com/u/1728050?v=4)](https://github.com/developeritsme "developeritsme (76 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/developeritsme-fiscal-service/health.svg)

```
[![Health](https://phpackages.com/badges/developeritsme-fiscal-service/health.svg)](https://phpackages.com/packages/developeritsme-fiscal-service)
```

###  Alternatives

[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M350](/packages/tymon-jwt-auth)[bagisto/bagisto

Bagisto Laravel E-Commerce

26.2k161.6k7](/packages/bagisto-bagisto)[spatie/laravel-sitemap

Create and generate sitemaps with ease

2.6k14.6M107](/packages/spatie-laravel-sitemap)[statamic/cms

The Statamic CMS Core Package

4.8k3.2M720](/packages/statamic-cms)[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k379.4k24](/packages/team-reflex-discord-php)[temporal/sdk

Temporal SDK

4002.2M18](/packages/temporal-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
