PHPackages                             chrislorando/laravel-accurate - 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. chrislorando/laravel-accurate

ActiveLibrary

chrislorando/laravel-accurate
=============================

Laravel package for Accurate Online API integration.

v0.9.1(2w ago)045↓73.4%MITPHPPHP ^8.2CI passing

Since Jul 14Pushed 2w agoCompare

[ Source](https://github.com/chrislorando/laravel-accurate)[ Packagist](https://packagist.org/packages/chrislorando/laravel-accurate)[ Docs](https://github.com/chrislorando/laravel-accurate)[ GitHub Sponsors](https://github.com/chrislorando)[ RSS](/packages/chrislorando-laravel-accurate/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (28)Versions (22)Used By (0)

Laravel Accurate
================

[](#laravel-accurate)

[![Latest Version on Packagist](https://camo.githubusercontent.com/6eb7de6b7375995eb3eb9b15398bc6c0473e915022de563ef802289e0be2fc51/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f63687269736c6f72616e646f2f6c61726176656c2d61636375726174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/chrislorando/laravel-accurate)[![GitHub Tests Action Status](https://camo.githubusercontent.com/fb40781575e7feb6839b9c4e6a4abcbd1a9690271ca3188e4d7cf15acaa32d7b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f63687269736c6f72616e646f2f6c61726176656c2d61636375726174652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473)](https://github.com/chrislorando/laravel-accurate/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/381ae24d3b61215b4adac8bb1bb30d156d9b106b254be82cc8268914e09050d1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f63687269736c6f72616e646f2f6c61726176656c2d61636375726174652f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65)](https://github.com/chrislorando/laravel-accurate/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/d845ac40d1d836fe1061c5eda24551b41891d4ecec1b58e12e5e17c3c1ed2833/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f63687269736c6f72616e646f2f6c61726176656c2d61636375726174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/chrislorando/laravel-accurate)

Laravel package for integrating with the Accurate Online accounting API. Provides OAuth 2.0 authentication, database management, and a fluent API client.

> 📘 Refer to the [Accurate Online API Documentation](https://accurate.id/api-integration/?a=WVGE671G) for full API reference.
>
> ⚠️ This is an **unofficial** community package. Not affiliated with [PT Cipta Piranti Sejahtera](https://cpssoft.com/) / Accurate Online.

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

[](#installation)

You can install the package via composer:

```
composer require chrislorando/laravel-accurate
```

You can publish and run the migrations with:

```
php artisan vendor:publish --tag="accurate-migrations"
php artisan migrate
```

You can publish the config file with:

```
php artisan vendor:publish --tag="accurate-config"
```

This is the contents of the published config file:

```
return [
    'client_id' => env('ACCURATE_CLIENT_ID'),
    'client_secret' => env('ACCURATE_CLIENT_SECRET'),
    'redirect_uri' => env('ACCURATE_REDIRECT_URI'),
    'base_url' => env('ACCURATE_BASE_URL', 'https://account.accurate.id'),
    'timeout' => 30,
    'verify_ssl' => true,
    'scopes' => ['item_view', 'item_category_view', 'unit_view'],
];
```

Usage
-----

[](#usage)

### OAuth Connect Flow

[](#oauth-connect-flow)

Add the following environment variables to your `.env`:

```
ACCURATE_BASE_URL=https://account.accurate.id
ACCURATE_CLIENT_ID=your-client-id
ACCURATE_CLIENT_SECRET=your-client-secret
ACCURATE_REDIRECT_URI=https://your-app.test/accurate/callback
```

Then register the routes in your `routes/web.php`:

```
use ChrisLorando\LaravelAccurate\Facades\Accurate;
use ChrisLorando\LaravelAccurate\Http\Controllers\CallbackController;

// Start OAuth flow
Route::get('accurate/connect', function () {
    return redirect(Accurate::authorizationUrl());
})->name('accurate.connect');

// OAuth callback — handles token exchange
Route::get('accurate/callback', CallbackController::class)->name('accurate.callback');

// See available company databases (after OAuth is set up)
Route::get('/accurate/databases', function () {
    return Accurate::connection('default')->databases();
});
```

Then visit `/accurate/connect` to start the OAuth flow.

### Using the Facade

[](#using-the-facade)

```
use ChrisLorando\LaravelAccurate\Facades\Accurate;

// Get the authorization URL
$url = Accurate::authorizationUrl();

// ── Step 1: Check available databases ──

$dbs = Accurate::connection('default')->databases();

// $dbs → ['d' => [['id' => '1234567', 'name' => 'PT ABC', ...], ...]]
// Pick the database ID you want to work with.

// ── Step 2: Open the database (hits Accurate API) ──

Accurate::connection('default')->openDatabase('1234567');

// ── Step 3: Call API — session auto-resolves connection & database ──

// Raw endpoints (any Accurate API endpoint)
$items    = Accurate::get('api/item/list.do', ['fields' => 'id,no,name', 'sp.pageSize' => '20']);
$detail   = Accurate::get('api/item/detail.do', ['id' => '53']);
Accurate::post('api/item/save.do', ['name' => 'Kabel USB-C', 'itemType' => 'INVENTORY']);
Accurate::put('api/item/save.do', ['id' => '53', 'name' => 'Updated Item']);
Accurate::delete('api/item/delete.do', ['id' => '53']);

// Typed resources (when you have a dedicated Resource class)
Accurate::items()->list(['sp.pageSize' => 20]);
Accurate::items()->detail('53');
Accurate::items()->save(['name' => 'Item Baru', 'itemType' => 'INVENTORY']);
Accurate::items()->delete('53');

Accurate::itemCategories()->list();
Accurate::itemCategories()->save(['name' => 'Elektronik']);

Accurate::units()->list();
Accurate::units()->save(['unitName' => 'Pcs']);

// Generic resource by name (no class needed)
Accurate::resource('customer')->list();
Accurate::resource('sales-invoice')->detail('123');
```

### Background Jobs &amp; Multi-DB

[](#background-jobs--multi-db)

The HTTP session is unavailable in queue jobs, CLI commands, or when you need to switch databases without a costly API call. Use `on()` to resolve a previously-opened database **from the local DB table** — no HTTP overhead.

```
// Job / command / multi-DB — resolves session from the accurate_databases table
Accurate::connection('default')
    ->on('1234567')           // ← no API call, uses cached session_id
    ->items()->list();

// Switch to another DB mid-request, also zero HTTP calls
$itemsA = Accurate::connection('default')->on('1234567')->items()->list();
$itemsB = Accurate::connection('default')->on('99999')->items()->list();

// Works with ALL calling styles:
Accurate::connection('default')->on('1234567')->get('api/item/list.do', ['sp.pageSize' => '20']);
Accurate::connection('default')->on('1234567')->post('api/item/save.do', ['name' => 'Kabel USB-C', 'itemType' => 'INVENTORY']);
Accurate::connection('default')->on('1234567')->resource('customer')->list();
Accurate::connection('default')->on('1234567')->items()->query()
    ->select('id', 'no', 'name')
    ->where('keywords', 'like', 'Kabel')
    ->get();
```

MethodAPI call?Use case`openDatabase('id')`✅ YesFirst-time setup, refresh session`on('id')`❌ NoBackground jobs, CLI, fast DB switching> 💡 **Calling styles summary:**
>
> - **Bare**: `Accurate::get()` / `Accurate::items()` — session auto-resolves connection + database.
> - **Explicit connection**: `Accurate::connection('default')->items()` — pick a specific connection.
> - **Open database**: `connection('x')->openDatabase('y')` — set/switch the active database for the session.
> - **On (no API)**: `connection('x')->on('y')` — resolve DB from the local table, zero HTTP.
>
> ⚠️ The Facade is a singleton — one active database at a time per request.

> ℹ️ **Dedicated classes** exist for `item` (`items()`), `item-category` (`itemCategories()`), and `unit` (`units()`). For any other resource use `Accurate::resource('customer')` or raw endpoints — both shown above. More dedicated resources will be added over time.

### Query Builder

[](#query-builder)

Fluent query builder with filter, sort, pagination, and shorthand operators. Available on every resource via `->query()`:

```
// Dedicated resource
$results = Accurate::items()->query()
    ->select('id', 'no', 'name', 'unit1NameWarehouse')
    ->where('keywords', 'like', 'Kabel')
    ->where('itemType', 'INVENTORY')
    ->where('unitPrice', '>', 10000)
    ->orderBy('name', 'asc')
    ->limit(20)
    ->page(1)
    ->get();

// Generic resource — same fluent API
$customers = Accurate::resource('customer')->query()
    ->select('id', 'name', 'email')
    ->where('keywords', 'like', 'PT')
    ->limit(10)
    ->get();

// Get single record (or null)
$first = Accurate::items()->query()
    ->select('id', 'name')
    ->orderBy('id', 'desc')
    ->first();

// Paginate with metadata (sp.page, sp.pageSize, sp.totalPage, sp.totalData)
$paged = Accurate::items()->query()
    ->select('id', 'name')
    ->where('keywords', 'like', 'Kabel')
    ->limit(10)
    ->paginate();

// $paged['data']  → array of items
// $paged['sp']    → pagination metadata (page, pageSize, totalPage, totalData)
```

#### Shorthand Operator Mapping

[](#shorthand-operator-mapping)

ArgumentAccurate OperatorExample2-arg `where(field, value)``EQUAL``where('itemType', 'INVENTORY')``>` / `gt``GREATER_THAN``where('price', '>', 100)``>=` / `gte``GREATER_EQUAL_THAN``where('price', '>=', 100)``
