skylence / exactonline-laravel-api
This is my package exactonline-laravel-api
Fund package maintenance!
skylence
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 1
pkg:composer/skylence/exactonline-laravel-api
Requires
- php: ^8.3|^8.4
- illuminate/contracts: ^11.0|^12.0
- picqer/exact-php-client: ^4.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.4
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2026-01-14 01:14:45 UTC
README
A Laravel package for integrating with the Exact Online API. Provides OAuth authentication, entity synchronization, rate limiting, and polymorphic mappings between your Laravel models and Exact Online entities.
Features
- OAuth 2.0 authentication with automatic token refresh
- Sync entities: Accounts, Contacts, Items, Sales Orders, Invoices, and more
- Polymorphic mappings between local models and Exact Online
- Division management and switching
- Rate limit handling with automatic retry
- Webhook support for real-time updates
- Payload validation before API calls
- Custom exception hierarchy for error handling
Installation
composer require skylence/exactonline-laravel-api
Publish and run the migrations:
php artisan vendor:publish --tag="exactonline-laravel-api-migrations"
php artisan migrate
Optionally publish the config:
php artisan vendor:publish --tag="exactonline-laravel-api-config"
Configuration
Add to your .env:
EXACT_CLIENT_ID=your-client-id EXACT_CLIENT_SECRET=your-client-secret EXACT_REDIRECT_URL=https://your-app.com/exact/oauth/callback
OAuth Setup
1. Create a Connection
use Skylence\ExactonlineLaravelApi\Models\ExactConnection; $connection = ExactConnection::create([ 'name' => 'My Connection', 'client_id' => config('exactonline-laravel-api.oauth.client_id'), 'client_secret' => 'your-secret', // Auto-encrypted 'redirect_url' => config('exactonline-laravel-api.oauth.redirect_url'), 'base_url' => 'https://start.exactonline.nl', 'is_active' => true, ]);
2. Initiate OAuth Flow
The package provides routes for OAuth:
GET /exact/oauth/authorize/{connection}- Redirects to Exact OnlineGET /exact/oauth/callback- Handles the callback
After successful authentication, divisions are automatically synced.
3. Select a Division
$connection->update(['division' => 123456]);
Usage
Syncing Entities
use Skylence\ExactonlineLaravelApi\Support\Config; use Skylence\ExactonlineLaravelApi\Actions\API\SyncAccountAction; $action = Config::getAction('sync_account', SyncAccountAction::class); $result = $action->execute($connection, $localCompany);
Making Your Models Mappable
Add the ExactMappable trait to models you want to sync:
use Skylence\ExactonlineLaravelApi\Concerns\ExactMappable; use Skylence\ExactonlineLaravelApi\Contracts\HasExactMapping; class Company extends Model implements HasExactMapping { use ExactMappable; }
This provides:
// Check if mapped $company->hasExactId($connection); // Get Exact ID $exactId = $company->getExactId($connection); // Set Exact ID after sync $company->setExactId($connection, $exactGuid, 'primary', $exactCode); // Find by Exact ID $company = Company::findByExactId($exactGuid, $connection); // Mappings are auto-deleted when model is deleted
Available Actions
| Entity | Actions |
|---|---|
| Account | get, get_all, create, update, sync |
| Contact | get, get_all, create, update, sync |
| Item | get, get_all, create, update, sync |
| Sales Order | get, get_all, create, update, sync |
| Sales Invoice | get, get_all, create, sync |
| Purchase Order | get, get_all, create, update, sync |
| Purchase Invoice | get, get_all, create, sync |
| Quotation | get, get_all, create, update, sync |
| Project | get, get_all, create, update, sync |
| GL Account | get, get_all, create, update, sync |
| Division | get_all, sync |
| Document | get, get_all, create, sync, download |
| Address | get, get_all, create, update, sync |
| Bank Account | get, get_all, create, update, sync |
| Warehouse | get, get_all, create, update, sync |
| Journal | get, get_all, create, update, sync |
| VAT Code | get, get_all, create, update, sync |
Fetching Data
use Skylence\ExactonlineLaravelApi\Actions\API\GetAccountsAction; $action = Config::getAction('get_accounts', GetAccountsAction::class); $accounts = $action->execute($connection, [ 'filter' => "Name eq 'Acme Corp'", 'select' => 'ID,Name,Email', ]);
Creating Entities
use Skylence\ExactonlineLaravelApi\Actions\API\CreateAccountAction; $action = Config::getAction('create_account', CreateAccountAction::class); $result = $action->execute($connection, [ 'Name' => 'New Customer', 'Email' => 'contact@example.com', 'Country' => 'NL', ]);
Events
Events are dispatched after sync operations:
AccountSyncedContactSyncedItemSyncedSalesOrderSyncedDivisionsSynced- ... and more
use Skylence\ExactonlineLaravelApi\Events\AccountSynced; Event::listen(AccountSynced::class, function ($event) { // $event->connection // $event->model // $event->exactId // $event->wasCreated });
Exception Handling
The package provides a custom exception hierarchy:
use Skylence\ExactonlineLaravelApi\Exceptions\ExactOnlineException; use Skylence\ExactonlineLaravelApi\Exceptions\AuthenticationException; use Skylence\ExactonlineLaravelApi\Exceptions\ApiException; use Skylence\ExactonlineLaravelApi\Exceptions\SyncException; use Skylence\ExactonlineLaravelApi\Exceptions\EntityNotFoundException; try { $action->execute($connection, $data); } catch (AuthenticationException $e) { // OAuth errors (invalid credentials, expired tokens) } catch (EntityNotFoundException $e) { // Entity not found in Exact Online } catch (SyncException $e) { // Sync operation failed } catch (ApiException $e) { // General API errors $statusCode = $e->getStatusCode(); $response = $e->getResponse(); }
Rate Limiting
The package automatically handles Exact Online rate limits:
// config/exactonline-laravel-api.php 'rate_limiting' => [ 'wait_on_minutely_limit' => true, // Auto-wait on 60/min limit 'throw_on_daily_limit' => true, // Throw on daily limit 'max_wait_seconds' => 65, ],
Payload Validation
Payloads are validated before sending to the API:
// config/exactonline-laravel-api.php 'validation' => [ 'enabled' => true, 'strict' => false, // Fail on unknown fields ],
Testing
composer test
Credits
License
The MIT License (MIT). Please see License File for more information.