PHPackages                             involve-digital/fakturoid-php - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. involve-digital/fakturoid-php

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

involve-digital/fakturoid-php
=============================

Fakturoid PHP library

01PHP

Since Oct 28Pushed 1y agoCompare

[ Source](https://github.com/Involve-Digital/fakturoid-php)[ Packagist](https://packagist.org/packages/involve-digital/fakturoid-php)[ RSS](/packages/involve-digital-fakturoid-php/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Fakturoid PHP lib
=================

[](#fakturoid-php-lib)

[![Tests](https://github.com/fakturoid/fakturoid-php/actions/workflows/main.yml/badge.svg)](https://github.com/fakturoid/fakturoid-php/actions/workflows/main.yml/badge.svg)[![](https://camo.githubusercontent.com/b3762d7d4db295b7c86e126994cbd677df945820d58a977e59f3f949ef78460a/68747470733a2f2f62616467656e2e6e65742f6769746875622f636865636b732f66616b7475726f69642f66616b7475726f69642d7068702f6d6173746572)](https://github.com/fakturoid/fakturoid-php/actions)[![](https://camo.githubusercontent.com/2db5a4f53b0291be2602f417d980af0742d35057500474677fd158fdfe3f490f/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f646d2f66616b7475726f69642f66616b7475726f69642d706870)](https://packagist.org/packages/fakturoid/fakturoid-php)[![](https://camo.githubusercontent.com/7c1e42aa7c002178db89cfee012078bdf08f6ffce7a44311fce4571da62435f8/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f762f66616b7475726f69642f66616b7475726f69642d706870)](https://packagist.org/packages/fakturoid/fakturoid-php)[![](https://camo.githubusercontent.com/3cdaffdf3c2116e63f6f26185448f2c76a6cd93877aae0ec914d1266839acf67/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f7068702f66616b7475726f69642f66616b7475726f69642d706870)](https://packagist.org/packages/fakturoid/fakturoid-php)[![](https://camo.githubusercontent.com/11d96beb23cd569c13f4b9a82522dbc253c8e7c5f596113a6e3b76557973e8d5/68747470733a2f2f62616467656e2e6e65742f6769746875622f6c6963656e73652f66616b7475726f69642f66616b7475726f69642d706870)](https://github.com/fakturoid/fakturoid-php)

PHP library for [Fakturoid.cz](https://www.fakturoid.cz/). Please see [API](https://www.fakturoid.cz/api/v3) for more documentation. New account just for testing API and using separate user (created via "Settings &gt; User account") for production usage is highly recommended.

Content
-------

[](#content)

- [Versions](#versions)
- [Installation](#installation)
- [Authorization by OAuth 2.0](#authorization-by-oauth-20)

    - [Authorization Code Flow](#authorization-code-flow)
    - [Client Credentials Flow](#client-credentials-flow)
- [Usage](#usage)

    - [Set credentials to the Fakturoid manager](#set-credentials-to-the-fakturoid-manager)
    - [Switch account](#switch-account)
    - [Basic usage](#basic-usage)
    - [Downloading an invoice PDF](#downloading-an-invoice-pdf)
    - [Using `custom_id`](#using-custom_id)
    - [InventoryItem resource](#inventoryitem-resource)
- [Handling errors](#handling-errors)

    - [Common problems](#common-problems)
- [Development](#development)

    - [Docker](#docker)
    - [Testing](#testing)
    - [Code-Style Check](#code-style-check)
    - [Check all requires for PR](#check-all-requires-for-pr)

Versions
--------

[](#versions)

Lib. versionFakturoid APIPHP`2.x``v3``>=8.1``1.x``v2``>=5.3.0`Installation
------------

[](#installation)

The recommended way to install is through Composer:

```
composer require fakturoid/fakturoid-php

```

Library requires PHP 8.1 (or later) and `ext-json`, `nyholm/psr7` and `psr/http-client` extensions.

Authorization by OAuth 2.0
--------------------------

[](#authorization-by-oauth-20)

### Authorization Code Flow

[](#authorization-code-flow)

Authorization using OAuth takes place in several steps. We use data obtained from the developer portal as client ID and client secret (*Settings → Connect other apps → OAuth 2 for app developers*).

First, we offer the user a URL address where he enters his login information. We obtain this using the following method:

```
$fManager = new \Fakturoid\FakturoidManager(
    new ClientInterface(), // PSR-18 client
    '{fakturoid-client-id}',
    '{fakturoid-client-secret}',
    'PHPlib ',
    null,
    '{your-redirect-uri}'
);
echo 'Link';
```

After entering the login data, the user is redirected to the specified redirect URI and with the code with which we obtain his credentials. We process the code as follows:

```
$fManager->requestCredentials($_GET['code']);
```

Credentials are now established in the object instance and we can send queries to the Fakturoid api. Credentials can be obtained in 2 ways. Obtaining credentials directly from the object:

```
$credentials = $fManager->getCredentials();
echo $credentials->toJson();
```

### Client Credentials Flow

[](#client-credentials-flow)

```
$fManager = new \Fakturoid\FakturoidManager(
    new ClientInterface(), // PSR-18 client
    '{fakturoid-client-id}',
    '{fakturoid-client-secret}',
    'PHPlib '
);
$fManager->authClientCredentials();
```

Processing credentials using the credentials callback:
------------------------------------------------------

[](#processing-credentials-using-the-credentials-callback)

The way callback works is that the library calls the callback function whenever the credentials are changed. This is useful because the token is automatically refreshed after its expiration.

```
$fManager->setCredentialsCallback(new class implements \Fakturoid\Auth\CredentialCallback {
    public function __invoke(?\Fakturoid\Auth\Credentials $credentials = null): void
    {
        // Save credentials to database or another storage
    }
});
```

Usage
-----

[](#usage)

### Set credentials to the Fakturoid manager

[](#set-credentials-to-the-fakturoid-manager)

If you run a multi-tenant application or an application that processes documents in parallel, you need to set Credentials correctly. Each time a new access token is obtained, the previous one is invalidated. For these needs there is `AuthProvider::setCredentials()` and also `CredentialCallback`.

```
$fManager = new \Fakturoid\FakturoidManager(
    new ClientInterface(), // PSR-18 client
    '{fakturoid-client-id}',
    '{fakturoid-client-secret}',
    'PHPlib '
);
// restore credentials from storage
$credentials = new \Fakturoid\Auth\Credentials(
    'refreshToken',
    'accessToken',
    (new DateTimeImmutable())->modify('-2 minutes'),
    \Fakturoid\Enum\AuthTypeEnum::AUTHORIZATION_CODE_FLOW // or \Fakturoid\Enum\AuthTypeEnum:CLIENT_CREDENTIALS_CODE_FLOW
);

$fManager->getAuthProvider()->setCredentials($credentials);
$fManager->setCredentialsCallback(new class implements \Fakturoid\Auth\CredentialCallback {
    public function __invoke(?\Fakturoid\Auth\Credentials $credentials = null): void
    {
        // Save credentials to database or another storage
    }
});
```

### Switch account

[](#switch-account)

```
$fManager = new \Fakturoid\FakturoidManager(
    new ClientInterface(), // PSR-18 client
    '{fakturoid-client-id}',
    '{fakturoid-client-secret}',
    'PHPlib '
    '{fakturoid-account-slug}',
);
$fManager->authClientCredentials();
$fManager->getBankAccountsProvider()->list();

// switch account and company
$fManager->setAccountSlug('{fakturoid-account-slug-another}');
$fManager->getBankAccountsProvider()->list();
```

### Basic usage

[](#basic-usage)

```
require __DIR__ . '/vendor/autoload.php';
$fManager = new \Fakturoid\FakturoidManager(
    new ClientInterface(), // PSR-18 client
    '{fakturoid-client-id}',
    '{fakturoid-client-secret}',
    'PHPlib '
);
$fManager->authClientCredentials();

// get current user
$user = $fManager->getUsersProvider()->getCurrentUser();
$fManager->setAccountSlug($user->getBody()->accounts[0]->slug);
// or you can set account slug manually
$fManager->setAccountSlug('{fakturoid-account-slug}');

// create subject
$response = $fManager->getSubjectsProvider()->create(['name' => 'Firma s.r.o.', 'email' => 'aloha@pokus.cz']);
$subject  = $response->getBody();

// create invoice with lines
$lines    = [['name' => 'Big sale', 'quantity' => 1, 'unit_price' => 1000]];
$response = $fManager->getInvoicesProvider()->create(['subject_id' => $subject->id, 'lines' => $lines]);
$invoice  = $response->getBody();

// send by mail
$fManager->getInvoicesProvider()->createMessage($invoice->id, ['email' => 'aloha@pokus.cz']);

// to mark invoice as paid and send thank you email
$fManager->getInvoicesProvider()->createPayment($invoice->id, ['paid_on' => (new \DateTime())->format('Y-m-d'), 'send_thank_you_email' => true]);

// lock invoice (other fire actions are described in the API documentation)
$fManager->getInvoicesProvider()->fireAction($invoice->id, 'lock');
```

### Downloading an invoice PDF

[](#downloading-an-invoice-pdf)

```
$invoiceId = 123;
$response = $fManager->getInvoicesProvider()->getPdf($invoiceId);
$data = $response->getBody();
file_put_contents("{$invoiceId}.pdf", $data);
```

If you call `$fManager->getInvoicesProvider()->getPdf()` right after creating an invoice, you'll get a status code `204` (`No Content`) with empty body, this means the invoice PDF hasn't yet been generated and you should try again a second or two later.

More info in [API docs](https://www.fakturoid.cz/api/v3/invoices#download-invoice-pdf).

```
$invoiceId = 123;

// This is just an example, you may want to do this in a background job and be more defensive.
while (true) {
    $response = $fManager->getInvoicesProvider()->getPdf($invoiceId);

    if ($response->getStatusCode() == 200) {
        $data = $response->getBody();
        file_put_contents("{$invoiceId}.pdf", $data);
        break;
    }

    sleep(1);
}
```

### Using `custom_id`

[](#using-custom_id)

You can use `custom_id` attribute to store your application record ID into our record. Invoices and subjects can be filtered to find a particular record:

```
$response = $fManager->getSubjectsProvider()->list(['custom_id' => '10']);
$subjects = $response->getBody();
$subject  = null;

if (count($subjects) > 0) {
    $subject = $subjects[0];
}
```

As for subjects, Fakturoid won't let you create two records with the same `custom_id` so you don't have to worry about multiple results. Also note that the field always returns a string.

### InventoryItem resource

[](#inventoryitem-resource)

To get all inventory items:

```
$fManager->getInventoryItemsProvider()->list();
```

To filter inventory items by certain SKU code or article number:

```
$fManager->getInventoryItemsProvider()->list(['sku' => 'SKU1234']);
$fManager->getInventoryItemsProvider()->list(['article_number' => 'IAN321']);
```

To search inventory items (searches in `name`, `article_number` and `sku`):

```
$fManager->getInventoryItemsProvider()->listArchived(['query' => 'Item name']);
```

To get all archived inventory items:

```
$fManager->getInventoryItemsProvider()->listArchived();
```

To get a single inventory item:

```
$fManager->getInventoryItemsProvider()->get($inventoryItemId);
```

To create an inventory item:

```
$data = [
    'name' => 'Item name',
    'sku' => 'SKU12345',
    'track_quantity' => true,
    'quantity' => 100,
    'native_purchase_price' => 500,
    'native_retail_price' => 1000
];
$fManager->getInventoryItemsProvider()->create($data)
```

To update an inventory item:

```
$fManager->getInventoryItemsProvider()->update($inventoryItemId, ['name' => 'Another name']);
```

To archive an inventory item:

```
$fManager->getInventoryItemsProvider()->archive($inventoryItemId);
```

To unarchive an inventory item:

```
$fManager->getInventoryItemsProvider()->unArchive($inventoryItemId);
```

To delete an inventory item:

```
$fManager->getInventoryItemsProvider()->delete($inventoryItemId);
```

InventoryMove resource
----------------------

[](#inventorymove-resource)

To get get all inventory moves across all inventory items:

```
$fManager->getInventoryMovesProvider()->list()
```

To get inventory moves for a single inventory item:

```
$fManager->getInventoryMovesProvider()->list(['inventory_item_id' => $inventoryItemId]);
```

To get a single inventory move:

```
$fManager->getInventoryMovesProvider()->get($inventoryItemId, $inventoryMoveId);
```

To create a stock-in inventory move:

```
$fManager->getInventoryMovesProvider()->create(
    $inventoryItemId,
    [
        'direction' => 'in',
        'moved_on' => '2023-01-12',
        'quantity_change' => 5,
        'purchase_price' => '249.99',
        'purchase_currency' => 'CZK',
        'private_note' => 'Bought with discount'
    ]
)
```

To create a stock-out inventory move:

```
$fManager->getInventoryMovesProvider()->create(
    $inventoryItemId,
    [
        'direction' => 'out',
        'moved_on' => '2023-01-12',
        'quantity_change' => '1.5',
        'retail_price' => 50,
        'retail_currency' => 'EUR',
        'native_retail_price' => '1250'
    ]
);
```

To update an inventory move:

```
$fManager->getInventoryMovesProvider()->update($inventoryItemId, $inventoryMoveId, ['moved_on' => '2023-01-11']);
```

To delete an inventory move:

```
$fManager->getInventoryMovesProvider()->update($inventoryItemId, $inventoryMoveId);
```

Handling errors
---------------

[](#handling-errors)

Library raises `Fakturoid\Exception\ClientErrorException` for `4xx` and `Fakturoid\Exception\ServerErrorException` for `5xx` status. You can get response code and response body by calling `getCode()` or `getResponse()->getBody()`.

```
try {
    $response = $fManager->getSubjectsProvider()->create(['name' => '', 'email' => 'aloha@pokus.cz']);
    $subject  = $response->getBody();
} catch (\Fakturoid\Exception\ClientErrorException $e) {
    $e->getCode(); // 422
    $e->getMessage(); // Unprocessable entity
    $e->getResponse()->getBody()->getContents(); // '{"errors":{"name":["je povinná položka","je příliš krátký/á/é (min. 2 znaků)"]}}'
} catch (\Fakturoid\Exception\ServerErrorException $e) {
    $e->getCode(); // 503
    $e->getMessage(); // Fakturoid is in read only state
}
```

### Common problems

[](#common-problems)

- In case of problem please contact our invoicing robot on .

Development
-----------

[](#development)

- To run tests, PHPUnit requires `ext-dom` extension (typically a `php-xml` package on Debian) and `ext-mbstring` extension (`php-mbstring` package).
- If you wish to generate code coverage (and have more intelligent stack traces), you will need [Xdebug](https://xdebug.org/)(`php-xdebug` package), it will hook itself into PHPUnit automatically.

### Docker

[](#docker)

```
$ docker-compose up -d
$ docker-compose exec php composer install
$ docker-compose exec php bash
```

### Testing

[](#testing)

Both commands do the same but the second version is a bit faster.

```
$ docker-compose exec php composer test:phpunit
$ docker-compose exec php composer coverage:phpunit
# or locally
$ composer test:phpunit
$ composer coverage:phpunit
```

### Code-Style Check

[](#code-style-check)

Both commands do the same but the second version seems to have a more intelligent output.

```
$ docker-compose exec php composer check:cs
# or locally
$ composer check:cs
```

### Check all requires for PR

[](#check-all-requires-for-pr)

```
$ docker-compose exec php composer check:all
# or locally
$ composer check:all
```

Or you can fix CS and Rector issues automatically:

```
$ docker-compose exec php composer fix:all
# or locally
$ composer fix:all
```

###  Health Score

16

—

LowBetter than 5% of packages

Maintenance33

Infrequent updates — may be unmaintained

Popularity1

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity18

Early-stage or recently created project

 Bus Factor1

Top contributor holds 51% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/2616cda46acbf6153279c25aa9669fdfef8bd78072203fcd3e292903cef7ce52?d=identicon)[mforbakova](/maintainers/mforbakova)

---

Top Contributors

[![ollie](https://avatars.githubusercontent.com/u/53026?v=4)](https://github.com/ollie "ollie (53 commits)")[![lukaskonarovsky](https://avatars.githubusercontent.com/u/9624?v=4)](https://github.com/lukaskonarovsky "lukaskonarovsky (32 commits)")[![tomas-kulhanek](https://avatars.githubusercontent.com/u/7447745?v=4)](https://github.com/tomas-kulhanek "tomas-kulhanek (7 commits)")[![goodhoko](https://avatars.githubusercontent.com/u/16712262?v=4)](https://github.com/goodhoko "goodhoko (3 commits)")[![edariedl](https://avatars.githubusercontent.com/u/163762?v=4)](https://github.com/edariedl "edariedl (2 commits)")[![TakeruDavis](https://avatars.githubusercontent.com/u/1822248?v=4)](https://github.com/TakeruDavis "TakeruDavis (1 commits)")[![arthurwozniak](https://avatars.githubusercontent.com/u/1984961?v=4)](https://github.com/arthurwozniak "arthurwozniak (1 commits)")[![vikijel](https://avatars.githubusercontent.com/u/2683048?v=4)](https://github.com/vikijel "vikijel (1 commits)")[![grogy](https://avatars.githubusercontent.com/u/1322983?v=4)](https://github.com/grogy "grogy (1 commits)")[![mforbakova](https://avatars.githubusercontent.com/u/107694983?v=4)](https://github.com/mforbakova "mforbakova (1 commits)")[![radimvaculik](https://avatars.githubusercontent.com/u/461164?v=4)](https://github.com/radimvaculik "radimvaculik (1 commits)")[![RiKap](https://avatars.githubusercontent.com/u/6736715?v=4)](https://github.com/RiKap "RiKap (1 commits)")

### Embed Badge

![Health badge](/badges/involve-digital-fakturoid-php/health.svg)

```
[![Health](https://phpackages.com/badges/involve-digital-fakturoid-php/health.svg)](https://phpackages.com/packages/involve-digital-fakturoid-php)
```

###  Alternatives

[shipmonk/name-collision-detector

Simple tool to find ambiguous classes or any other name duplicates within your project.

362.1M34](/packages/shipmonk-name-collision-detector)[bostondv/bootstrap-ninja-forms

Adds Bootstrap classes to Ninja Forms

222.2k](/packages/bostondv-bootstrap-ninja-forms)

PHPackages © 2026

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