PHPackages                             chuckbe/clearfacts-laravel-sdk - 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. [API Development](/categories/api)
4. /
5. chuckbe/clearfacts-laravel-sdk

ActiveLibrary[API Development](/categories/api)

chuckbe/clearfacts-laravel-sdk
==============================

Laravel SDK for the Clearfacts pre-accounting platform API (GraphQL)

v0.1.0(1mo ago)01↑2900%MITPHPPHP ^8.2

Since Apr 5Pushed 1mo agoCompare

[ Source](https://github.com/chuckbe/clearfacts-laravel-sdk)[ Packagist](https://packagist.org/packages/chuckbe/clearfacts-laravel-sdk)[ Docs](https://github.com/chuckbe/clearfacts-laravel-sdk)[ RSS](/packages/chuckbe-clearfacts-laravel-sdk/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

Clearfacts Laravel SDK
======================

[](#clearfacts-laravel-sdk)

A Laravel SDK for the [Clearfacts](https://www.clearfacts.be/) pre-accounting platform API. Built on [Saloon PHP](https://docs.saloon.dev/) with a fluent, resource-based interface for the Clearfacts GraphQL API.

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

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, or 12

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

[](#installation)

```
composer require chuckbe/clearfacts-laravel-sdk
```

Publish the configuration file:

```
php artisan vendor:publish --tag=clearfacts-config
```

Configuration
-------------

[](#configuration)

Add the following to your `.env` file:

```
CLEARFACTS_API_URL=https://api.clearfacts.be
CLEARFACTS_CLIENT_ID=your-client-id
CLEARFACTS_CLIENT_SECRET=your-client-secret
CLEARFACTS_REDIRECT_URI=https://your-app.com/auth/clearfacts/callback
CLEARFACTS_ISSUER=https://login.clearfacts.be
```

See `config/clearfacts.php` for all available options (timeouts, retry behaviour, scopes).

Authentication (Multi-Tenant / SaaS)
------------------------------------

[](#authentication-multi-tenant--saas)

Clearfacts uses **OpenID Connect** (Authorization Code Flow). This SDK does **not** handle the OIDC flow itself. Instead, use [Laravel Socialite](https://laravel.com/docs/socialite) with a Clearfacts provider (or a generic OIDC Socialite driver) to obtain access tokens per tenant.

The OIDC discovery endpoint is at `https://login.clearfacts.be/.well-known/openid-configuration` (or `https://.clearfacts.be` for accountant-specific endpoints).

The configured scopes are: `openid`, `email`, `profile`, `accountant`, `statistics`, `read_administrations`, `associate_read`, `associate_actions`, `journal_read`, `contact_read`, `upload_document`, `archive_read`, `archive_actions`.

Once you have an access token for a tenant, set it before making API calls:

```
use Clearfacts\Facades\Clearfacts;

// Set the token (typically in middleware or a tenant-aware service)
Clearfacts::setAccessToken($tenant->clearfacts_access_token);
```

Usage
-----

[](#usage)

The SDK provides a fluent, resource-based API:

```
Clearfacts::api()->resource->method($args);
```

### Administrations

[](#administrations)

```
use Clearfacts\Facades\Clearfacts;

// List all administrations
$administrations = Clearfacts::api()->administration->list();

// Get a single administration by company number
$admin = Clearfacts::api()->administration->get('0123456789');

echo $admin->name;
echo $admin->companyNumber;
echo $admin->companyType;
echo $admin->accountManager;
echo $admin->address->locality;
echo $admin->language;
```

### Documents

[](#documents)

```
use Clearfacts\Facades\Clearfacts;
use Clearfacts\Enums\InvoiceType;
use Clearfacts\Enums\ArchiveType;

// Upload a purchase invoice to an administration's inbox
$file = Clearfacts::api()->document->upload(
    vatNumber: 'BE0123456789',
    fileName: 'invoice_001.pdf',
    invoiceType: InvoiceType::PURCHASE,
    fileContent: file_get_contents('/path/to/invoice.pdf'),
);

echo $file->uuid;
echo $file->name;
echo $file->amountOfPages;

// Upload to the archive (various or permanent)
$file = Clearfacts::api()->document->uploadArchive(
    vatNumber: 'BE0123456789',
    fileName: 'contract.pdf',
    type: ArchiveType::PERMANENT,
    category: 'category-id-from-archiveCategory-list',
    fileContent: file_get_contents('/path/to/contract.pdf'),
);

// Get a document by ID (returned after upload)
$doc = Clearfacts::api()->document->get('document-uuid');

echo $doc->type;          // InvoiceType (PURCHASE, SALE, VARIOUS)
echo $doc->paymentState;  // PAID or UNPAID
echo $doc->file->uuid;
```

**Invoice types:** `PURCHASE`, `SALE`, `VARIOUS`

**Archive types:** `VARIOUS`, `PERMANENT`

**Supported upload formats:** PDF, JPEG images, XML (Billing3/UBL.BE/E-FFF)

### Customers (Business Partners)

[](#customers-business-partners)

```
use Clearfacts\Facades\Clearfacts;

// Get all customers for an administration (paginated, max 100 per request)
$customers = Clearfacts::api()->customer->list('0123456789');

foreach ($customers as $customer) {
    echo $customer->name;
    echo $customer->companyNumber;
    echo $customer->email;
    echo $customer->phone;
    echo $customer->address->locality;
}

// Paginate with offset
$page2 = Clearfacts::api()->customer->list('0123456789', offset: 100);
```

### Journals

[](#journals)

```
use Clearfacts\Facades\Clearfacts;

// Get all journals for an administration
$journals = Clearfacts::api()->journal->list('0123456789');

foreach ($journals as $journal) {
    echo $journal->id;
    echo $journal->name;
    echo $journal->type;                // e.g. PURCHASE, SALE, VARIOUS
    echo $journal->creditNote;          // bool
    echo $journal->default;             // bool
    echo $journal->lastDocumentNumber;
}
```

### Archive Categories

[](#archive-categories)

```
use Clearfacts\Facades\Clearfacts;

// Get archive categories for an administration
$categories = Clearfacts::api()->archiveCategory->list('BE0123456789');

// Various categories
foreach ($categories->various as $category) {
    echo $category->id . ': ' . $category->name;
}

// Permanent categories
foreach ($categories->permanent as $category) {
    echo $category->id . ': ' . $category->name;
}
```

### Accountant

[](#accountant)

```
use Clearfacts\Facades\Clearfacts;

// Get the accountant linked to the authenticated user
$accountant = Clearfacts::api()->accountant->get();

echo $accountant->name;
echo $accountant->companyNumber;
echo $accountant->email;
echo $accountant->platformName;
echo $accountant->address->locality;
```

### Associates

[](#associates)

```
use Clearfacts\Facades\Clearfacts;
use Clearfacts\Enums\AssociateType;
use Clearfacts\Enums\Language;

// List all associates
$associates = Clearfacts::api()->associate->list();

foreach ($associates as $associate) {
    echo $associate->firstName . ' ' . $associate->lastName;
    echo $associate->email;
    echo $associate->type;     // ADMIN, ASSOCIATE, SUPPORT
    echo $associate->language;
    echo $associate->active ? 'Active' : 'Inactive';
}

// List associate groups
$groups = Clearfacts::api()->associate->groups();

// Add a new associate
$associate = Clearfacts::api()->associate->add(
    firstName: 'Jane',
    lastName: 'Doe',
    email: 'jane@example.com',
    type: AssociateType::ASSOCIATE,
    active: true,
    language: Language::DUTCH,
    sendActivationMail: true,
    associateGroups: [['id' => 'group-uuid']],
);

// The plain password is only available once after creation
echo $associate->plainPassword;

// Edit an associate (only pass the fields you want to update)
$associate = Clearfacts::api()->associate->edit(
    id: $associate->id,
    fields: ['firstName' => 'Updated', 'active' => false],
);
```

### Statistics

[](#statistics)

```
use Clearfacts\Facades\Clearfacts;

// Get company statistics (AIR or processing) for a period
$stats = Clearfacts::api()->statistic->companyStatistics(
    type: 'AIR',                   // or 'processing'
    startPeriod: '2024-01-01',
    endPeriod: '2024-12-31',
    companyNumber: '0123456789',   // optional: filter by company
    invoicetype: 'PURCHASE',       // optional: filter by invoice type
);

foreach ($stats as $companyStat) {
    echo $companyStat->companyNumber;
    foreach ($companyStat->items as $item) {
        echo $item->period . ': ' . $item->value;
    }
}
```

### App Info

[](#app-info)

```
use Clearfacts\Facades\Clearfacts;

// Update the app info for a specific administration
$appInfo = Clearfacts::api()->appInfo->update(
    vatnumber: 'BE0123456789',
    emailaddress: 'notify@example.com',
    badge: ['text' => '3', 'textColor' => '#FFFFFF', 'color' => '#FF0000'],
    icon: ['type' => 'warning', 'color' => '#FFA500'],
    imageUrl: 'https://example.com/logo.png',
    iFrameUrl: 'https://example.com/embed',
);
```

API Reference
-------------

[](#api-reference)

### Available Resources

[](#available-resources)

ResourceMethodDescription`administration``list()`List all administrations`administration``get(companyNumber)`Get a single administration`document``get(id)`Get a document by ID`document``upload(vatNumber, fileName, invoiceType, fileContent)`Upload invoice to inbox`document``uploadArchive(vatNumber, fileName, type, category, fileContent)`Upload file to archive`customer``list(companyNumber, ?offset)`List customers/business partners (paginated)`journal``list(companyNumber)`List journals for an administration`archiveCategory``list(vatNumber)`Get archive categories (various + permanent)`accountant``get()`Get the linked accountant`associate``list()`List all associates`associate``groups()`List associate groups`associate``add(firstName, lastName, email, type, active, language, sendActivationMail, ?associateGroups)`Add a new associate`associate``edit(id, fields)`Edit an existing associate`statistic``companyStatistics(type, startPeriod, endPeriod, ...)`Get company statistics`appInfo``update(vatnumber, ...)`Update app info for an administration### Data Classes

[](#data-classes)

All API responses are mapped to typed data classes in `Clearfacts\Data\`:

ClassFields`Administration`name, companyType, companyNumber, companyNumberType, vatLiable, address, slug, accountManager, emails\[\], language`Accountant`name, companyNumber, systemName, address, platformName, email, logo, favicon`Associate`id, firstName, lastName, email, language, type, active, associateGroups\[\], plainPassword`AssociateGroup`id, name`BusinessPartner`id, companyNumber, name, address, email, phone, fax`InvoiceDocument`file, date, comment, type, paymentState`File`uuid, name, amountOfPages, comment, tags\[\]`Journal`id, name, creditNote, type, default, lastDocumentNumber`CompanyStatistic`companyNumber, items\[\]`StatisticItem`period, value`AppInfo`vatnumber, emailaddress, badge, icon, imageUrl, iFrameUrl`ArchiveCategories`various\[\], permanent\[\]`Category`id, name`Address`streetAddress, extendedAddress, postalCode, locality, country`Country`iso2, name`Email`type, emailAddress### Enums

[](#enums)

EnumValues`InvoiceType`PURCHASE, SALE, VARIOUS`ArchiveType`VARIOUS, PERMANENT`AssociateType`ADMIN, ASSOCIATE, SUPPORT`Language`DUTCH (nl\_BE), FRENCH (fr\_BE), ENGLISH (en\_BE), GERMAN (de\_BE)`PaymentState`PAID, UNPAIDArchitecture
------------

[](#architecture)

```
config/
  clearfacts.php                # Configuration file
src/
  Api/
    ClearfactsApiClient.php     # Saloon Connector (entry point for all API calls)
    Requests/                   # GraphQL request classes per domain
      Administration/
        GetAdministrationsRequest.php
        GetAdministrationRequest.php
      Accountant/
        GetAccountantRequest.php
      AppInfo/
        UpdateAppInfoRequest.php
      ArchiveCategory/
        GetArchiveCategoriesRequest.php
      Associate/
        GetAssociatesRequest.php
        GetAssociateGroupsRequest.php
        AddAssociateRequest.php
        EditAssociateRequest.php
      Customer/
        GetCustomersRequest.php
      Document/
        GetDocumentRequest.php
        UploadFileRequest.php
        UploadArchiveFileRequest.php
      Journal/
        GetJournalsRequest.php
      Statistic/
        GetCompanyStatisticsRequest.php
      GraphQLRequest.php            # Base class for JSON GraphQL requests
      MultipartGraphQLRequest.php   # Base class for multipart file uploads
    Resources/                  # Fluent resource classes
      AdministrationResource.php
      AccountantResource.php
      AppInfoResource.php
      ArchiveCategoryResource.php
      AssociateResource.php
      CustomerResource.php
      DocumentResource.php
      JournalResource.php
      StatisticResource.php
  Concerns/
    ExtractsGraphQLData.php     # Shared trait for GraphQL response extraction
  Data/                         # Typed data/DTO classes
  Enums/                        # PHP 8.2+ backed enums
  Facades/
    Clearfacts.php              # Laravel Facade
  ClearfactsManager.php         # Manager (handles token, creates API client)
  ClearfactsServiceProvider.php # Service provider with auto-discovery

```

Multi-Tenant Setup Example
--------------------------

[](#multi-tenant-setup-example)

In a typical multi-tenant SaaS application, you might set the token in middleware:

```
// app/Http/Middleware/SetClearfactsToken.php
namespace App\Http\Middleware;

use Clearfacts\Facades\Clearfacts;
use Closure;

class SetClearfactsToken
{
    public function handle($request, Closure $next)
    {
        $tenant = $request->user()->tenant;

        if ($tenant->clearfacts_access_token) {
            Clearfacts::setAccessToken($tenant->clearfacts_access_token);
        }

        return $next($request);
    }
}
```

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

[](#development)

```
# Install dependencies
composer install

# Run tests
vendor/bin/phpunit

# Run static analysis (level 8)
vendor/bin/phpstan analyse

# Run code style fixer (PSR-12)
vendor/bin/php-cs-fixer fix --config=php-cs-fixer.php

# Run all checks at once (also runs automatically on commit via GrumPHP)
vendor/bin/grumphp run
```

### Tests

[](#tests)

Tests use [Orchestra Testbench](https://packages.tools/testbench) and [Saloon's MockClient](https://docs.saloon.dev/testing/recording-requests) to mock HTTP responses without hitting the real API.

```
tests/
  TestCase.php                              # Base test case (loads service provider + facade)
  Unit/
    ClearfactsManagerTest.php               # Manager: token management, client creation, facade
    Requests/
      GraphQLRequestTest.php                # Request body structure, variables, endpoint
      MultipartGraphQLRequestTest.php       # Multipart body parts, file attachment
    Resources/
      AccountantResourceTest.php            # Mocked responses → DTO mapping
      AdministrationResourceTest.php
      AppInfoResourceTest.php
      ArchiveCategoryResourceTest.php
      AssociateResourceTest.php
      CustomerResourceTest.php
      DocumentResourceTest.php
      JournalResourceTest.php
      StatisticResourceTest.php

```

Official Clearfacts API Documentation
-------------------------------------

[](#official-clearfacts-api-documentation)

- [Developer Portal](https://developer.clearfacts.be/)
- [GraphQL Schema Reference](https://assets-prod.cdn.clearfacts.be/doc/query.doc.html)
- [GitHub Documentation](https://github.com/Clearfacts/cf_developer_docs)
- [Postman Collection](https://www.postman.com/clearfacts/clearfacts-public-api)

**Note:** The Clearfacts API does not support GraphQL introspection. The query/mutation definitions in this SDK are based on the official documentation and schema. If Clearfacts adds or changes endpoints, the request classes in `src/Api/Requests/` can be updated accordingly.

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance90

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5599ac2c2c73cedb92bd392657a3f13f3b01bc982ab75b4b84a90417ee1edaef?d=identicon)[KarelBrijs](/maintainers/KarelBrijs)

---

Top Contributors

[![KarelBrijs](https://avatars.githubusercontent.com/u/16884712?v=4)](https://github.com/KarelBrijs "KarelBrijs (3 commits)")

---

Tags

laravelsdkgraphqlAccountingBelgiumclearfactspre-accounting

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/chuckbe-clearfacts-laravel-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/chuckbe-clearfacts-laravel-sdk/health.svg)](https://phpackages.com/packages/chuckbe-clearfacts-laravel-sdk)
```

###  Alternatives

[saloonphp/laravel-plugin

The official Laravel plugin for Saloon

805.7M125](/packages/saloonphp-laravel-plugin)[resend/resend-laravel

Resend for Laravel

1201.4M6](/packages/resend-resend-laravel)[mll-lab/laravel-graphiql

Easily integrate GraphiQL into your Laravel project

693.2M9](/packages/mll-lab-laravel-graphiql)[codebar-ag/laravel-docuware

DocuWare integration with Laravel

1221.1k](/packages/codebar-ag-laravel-docuware)[codebar-ag/laravel-zammad

Zammad integration with Laravel

106.1k](/packages/codebar-ag-laravel-zammad)

PHPackages © 2026

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