PHPackages                             ktr/business-central-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. ktr/business-central-sdk

ActiveLibrary[API Development](/categories/api)

ktr/business-central-sdk
========================

Laravel SDK for Microsoft Business Central - Connect to Business Central web services with elegant model-based API

v1.0.1(6mo ago)0155MITPHPPHP ^8.2|^8.3CI passing

Since Oct 23Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/ktrfo/business-central-sdk)[ Packagist](https://packagist.org/packages/ktr/business-central-sdk)[ Docs](https://github.com/ktrfo/business-central-sdk)[ RSS](/packages/ktr-business-central-sdk/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (4)Versions (3)Used By (0)

Microsoft Business Central SDK for Laravel
==========================================

[](#microsoft-business-central-sdk-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/44b6899cde8306add7401546648d4ce5bcb187fd8a8d94c19c5a54bdf8e4c8a2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b74722f627573696e6573732d63656e7472616c2d73646b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ktr/business-central-sdk)[![Total Downloads](https://camo.githubusercontent.com/dd3d54ddae9731c40b50e6c650b12007fadf603efbccfe88d7284ad611a4d471/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b74722f627573696e6573732d63656e7472616c2d73646b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ktr/business-central-sdk)[![Tests](https://github.com/ktrfo/business-central-sdk/workflows/tests/badge.svg)](https://github.com/ktrfo/business-central-sdk/workflows/tests/badge.svg)

A modern Laravel SDK for Microsoft Dynamics 365 Business Central. Connect to Business Central's web services with an elegant, Laravel-style API that feels right at home in your Laravel application.

Why This Package?
-----------------

[](#why-this-package)

Building integrations with Microsoft Business Central can be complex and time-consuming. This SDK simplifies the entire process by providing:

- **Laravel-Native Integration** - Feels like native Laravel code with familiar query builder patterns
- **Three Flexible APIs** - Choose between HTTP Client macros, Facades, or Eloquent-style Models
- **Comprehensive Coverage** - Access 85+ Business Central entities (Customers, Sales Orders, Items, Invoices, and more)
- **Modern PHP** - Built for PHP 8.2+ and Laravel 11+
- **Type-Safe** - Full PHPDoc annotations for IDE autocompletion
- **OAuth2 Authentication** - Handles token management and caching automatically
- **OData Query Builder** - Powerful filtering, sorting, expanding, and pagination

Features
--------

[](#features)

✅ **Model-Based API** - Eloquent-like models for all Business Central entities ✅ **Query Builder** - Intuitive filtering with `where()`, `whereIn()`, `whereContains()`, and more ✅ **Relationship Expansion** - Eager load related data with `expand()`✅ **Pagination Support** - Built-in `take()`, `skip()`, `lazy()`, and `all()` methods ✅ **HTTP Client Macro** - Use `Http::businessCentral()` for quick API calls ✅ **Facade Support** - Simple `BusinessCentral::get()` / `::post()` interface ✅ **Automatic Token Management** - OAuth2 tokens cached and refreshed automatically ✅ **Laravel 11 &amp; 12 Support** - Tested on PHP 8.2 and 8.3

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

[](#requirements)

- PHP 8.2 or higher
- Laravel 11.0 or higher

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

[](#installation)

Install the package via Composer:

```
composer require ktr/business-central-sdk
```

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

[](#configuration)

Add your Business Central credentials to your `.env` file:

```
BUSINESS_CENTRAL_CLIENT_ID=your-client-id
BUSINESS_CENTRAL_CLIENT_SECRET=your-client-secret
BUSINESS_CENTRAL_TENANT=your-tenant-id
BUSINESS_CENTRAL_ENVIRONMENT=production
BUSINESS_CENTRAL_COMPANY=your-company-id
```

### Getting Your Credentials

[](#getting-your-credentials)

1. Register your app in [Azure Portal](https://portal.azure.com)
2. Create an App Registration with API permissions for Business Central
3. Generate a client secret
4. Note your Tenant ID from Azure AD
5. Find your Company ID and Environment from Business Central

> **Tip:** For sandbox testing, set `BUSINESS_CENTRAL_ENVIRONMENT=sandbox`

Usage
-----

[](#usage)

This SDK provides three different APIs to fit your coding style. All examples below accomplish the same task - choose the one that feels best for your project.

### 1. Model-Based API (Recommended)

[](#1-model-based-api-recommended)

The Model API provides an Eloquent-like experience with full IDE autocompletion:

```
use Ktr\BusinessCentral\Models\ApiV20\SalesOrders;
use Ktr\BusinessCentral\Models\ApiV20\SalesOrderLines;
use Ktr\BusinessCentral\Models\ApiV20\Customers;
use Ktr\BusinessCentral\Models\ApiV20\Items;

// Create a sales order
$order = SalesOrders::create([
    'customerId' => '{customer-id}',
    'shipToName' => 'John Doe',
    'shipToAddress' => '123 Main St',
    'salesOrderLines' => [
        [
            'lineType' => 'Item',
            'itemId' => '{item-id}',
            'quantity' => 5,
            'unitPrice' => 29.99
        ]
    ]
]);

// Query with filters
$orders = SalesOrders::query()
    ->where('customerId', '{customer-id}')
    ->where('totalAmount', '>', 1000)
    ->orderBy('orderDate', 'desc')
    ->take(10)
    ->get();

// Select specific fields
$customer = Customers::select('id', 'displayName', 'email', 'phoneNumber')
    ->where('number', 'C-001')
    ->first();

// Expand related data
$order = SalesOrders::select('number', 'customerId', 'totalAmount')
    ->where('number', 'SO-001')
    ->expand(SalesOrderLines::class) // Load order lines
    ->first();

// Access expanded data
echo $order->number; // SO-001
echo $order->salesOrderLines[0]->quantity; // 5

// Update a record
$customer->email = 'newemail@example.com';
$customer->phoneNumber = '+1-555-0123';
$customer->save();

// Delete a record
$order->delete();
```

### 2. HTTP Client Macro

[](#2-http-client-macro)

For quick, one-off API calls without models:

```
use Illuminate\Support\Facades\Http;

// Create a sales order
$order = Http::businessCentral()->post('salesOrders', [
    'customerId' => '{customer-id}',
    'shipToName' => 'Jane Smith',
    'salesOrderLines' => [
        [
            'lineType' => 'Item',
            'itemId' => '{item-id}',
            'quantity' => 3,
            'unitPrice' => 49.99
        ]
    ]
]);

// Get customers with query parameters
$customers = Http::businessCentral()->get('customers', [
    '$filter' => "city eq 'New York'",
    '$select' => 'id,displayName,email',
    '$top' => 20
]);

// Update with PATCH
$response = Http::businessCentral()->patch("customers('{id}')", [
    'phoneNumber' => '+1-555-9999'
]);
```

### 3. Facade API

[](#3-facade-api)

Clean and simple for straightforward API interactions:

```
use Ktr\BusinessCentral\Facades\BusinessCentral;

// Create a customer
$customer = BusinessCentral::post('customers', [
    'displayName' => 'Acme Corporation',
    'email' => 'contact@acme.com',
    'phoneNumber' => '+1-555-1234',
    'addressLine1' => '456 Business Ave',
    'city' => 'San Francisco',
    'state' => 'CA',
    'postalCode' => '94102'
]);

// Get all items
$items = BusinessCentral::get('items');

// Get with filters
$items = BusinessCentral::get('items', [
    '$filter' => "type eq 'Inventory' and unitPrice gt 100",
    '$orderby' => 'displayName asc'
]);
```

Query Builder Examples
----------------------

[](#query-builder-examples)

The Model API includes a powerful query builder with OData support:

### Basic Filtering

[](#basic-filtering)

```
use Ktr\BusinessCentral\Models\ApiV20\Items;

// Simple where clause
$items = Items::where('type', 'Inventory')->get();

// Multiple conditions
$items = Items::query()
    ->where('type', 'Inventory')
    ->where('unitPrice', '>', 50)
    ->where('blocked', false)
    ->get();

// Or conditions
$items = Items::query()
    ->where('type', 'Inventory')
    ->orWhere('type', 'Service')
    ->get();
```

### Advanced Filtering

[](#advanced-filtering)

```
// Contains search
$customers = Customers::whereContains('displayName', 'Tech')->get();

// Starts with
$customers = Customers::whereStartsWith('displayName', 'Acme')->get();

// Ends with
$items = Items::whereEndsWith('number', '-X')->get();

// In clause
$customers = Customers::whereIn('city', ['New York', 'Los Angeles', 'Chicago'])->get();

// Date filtering
$orders = SalesOrders::whereDateTime('orderDate', '>=', now()->subDays(30))->get();

// Complex grouped conditions
$items = Items::query()
    ->where(function($query) {
        $query->where('type', 'Inventory')
              ->where('unitPrice', '>', 100);
    })
    ->orWhere(function($query) {
        $query->where('type', 'Service')
              ->where('unitCost', '', 100)->get();
Items::where('quantity', 0)->get();
// Generates: unitPrice gt 100 and quantity eq 0

// Boolean values - not quoted
Items::where('blocked', false)->get();
Customers::where('taxLiable', true)->get();
// Generates: blocked eq false and taxLiable eq true

// DateTime/Carbon objects - auto-formatted to ISO 8601
Items::where('lastModifiedDateTime', '>=', Carbon::parse('2024-01-01'))->get();
// Generates: lastModifiedDateTime ge 2024-01-01T00:00:00.000Z

// Negative numbers work correctly
Customers::where('balanceDue', '', 0)
    ->get();
// Generates: Inventory gt 0
```

**Important Notes:**

- Numeric `0` is correctly handled as integer, not string `'0'`
- Boolean `false` is distinct from integer `0`
- String values are automatically URL-encoded for OData compatibility
- DateTime objects are automatically detected and formatted correctly

Available Models
----------------

[](#available-models)

This SDK provides access to 85+ Business Central entities. Here are the most commonly used:

### Sales &amp; Customers

[](#sales--customers)

- `Customers` - Customer master data
- `SalesOrders` - Sales orders
- `SalesOrderLines` - Sales order line items
- `SalesInvoices` - Posted sales invoices
- `SalesInvoiceLines` - Sales invoice line items
- `SalesQuotes` - Sales quotes
- `SalesShipments` - Posted sales shipments
- `SalesCreditMemos` - Sales credit memos

### Purchasing &amp; Vendors

[](#purchasing--vendors)

- `Vendors` - Vendor master data
- `PurchaseOrders` - Purchase orders
- `PurchaseOrderLines` - Purchase order line items
- `PurchaseInvoices` - Posted purchase invoices
- `PurchaseInvoiceLines` - Purchase invoice line items
- `PurchaseCreditMemos` - Purchase credit memos

### Inventory &amp; Items

[](#inventory--items)

- `Items` - Item master data
- `ItemCategories` - Item categories
- `UnitsOfMeasure` - Units of measure
- `InventoryPostingGroups` - Inventory posting groups

### Financial

[](#financial)

- `Accounts` - Chart of accounts
- `GeneralLedgerEntries` - G/L entries
- `Currencies` - Currency master data
- `CurrencyExchangeRates` - Exchange rates
- `PaymentTerms` - Payment terms
- `PaymentMethods` - Payment methods
- `Dimensions` - Financial dimensions
- `BankAccounts` - Bank account master data

### Journals

[](#journals)

- `Journals` - General journals
- `ItemJournals` - Item journals
- `CustomerPaymentJournals` - Payment journals
- `VendorPaymentJournals` - Vendor payment journals

### Reporting &amp; Analysis

[](#reporting--analysis)

- `BalanceSheets` - Balance sheet reports
- `IncomeStatements` - Income statement reports
- `CashFlowStatements` - Cash flow reports
- `AgedAccountsReceivables` - AR aging reports
- `AgedAccountsPayables` - AP aging reports
- `TrialBalances` - Trial balance reports

### Master Data

[](#master-data)

- `Employees` - Employee records
- `Projects` - Project/job cards
- `CountriesRegions` - Countries and regions
- `TaxGroups` - Tax groups
- `TaxAreas` - Tax areas
- `Contacts` - Contact information
- `CompanyInformation` - Company details

> **Tip:** All models are located in `Ktr\BusinessCentral\Models\ApiV20` namespace and include full PHPDoc type hints for IDE autocompletion.

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

[](#api-reference)

For detailed information about available fields, filters, and operations for each entity, refer to the official [Microsoft Business Central API v2.0 Documentation](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/api-reference/v2.0/).

Real-World Examples
-------------------

[](#real-world-examples)

### Example 1: Create a Complete Sales Order

[](#example-1-create-a-complete-sales-order)

```
use Ktr\BusinessCentral\Models\ApiV20\SalesOrders;
use Ktr\BusinessCentral\Models\ApiV20\Customers;
use Ktr\BusinessCentral\Models\ApiV20\Items;

// Find customer
$customer = Customers::where('number', 'C-001')->first();

// Find items
$item1 = Items::where('number', 'ITEM-001')->first();
$item2 = Items::where('number', 'ITEM-002')->first();

// Create order with multiple lines
$order = SalesOrders::create([
    'customerId' => $customer->id,
    'customerNumber' => $customer->number,
    'shipToName' => $customer->displayName,
    'shipToAddress' => $customer->addressLine1,
    'shipToCity' => $customer->city,
    'salesOrderLines' => [
        [
            'lineType' => 'Item',
            'itemId' => $item1->id,
            'quantity' => 10,
            'unitPrice' => $item1->unitPrice,
            'description' => $item1->displayName
        ],
        [
            'lineType' => 'Item',
            'itemId' => $item2->id,
            'quantity' => 5,
            'unitPrice' => $item2->unitPrice,
            'description' => $item2->displayName
        ]
    ]
]);

echo "Order created: {$order->number}";
```

### Example 2: Generate Sales Report

[](#example-2-generate-sales-report)

```
use Ktr\BusinessCentral\Models\ApiV20\SalesInvoices;
use Carbon\Carbon;

// Get sales for last 30 days
$startDate = Carbon::now()->subDays(30);
$invoices = SalesInvoices::query()
    ->whereDateTime('orderDate', '>=', $startDate)
    ->select('id', 'number', 'customerId', 'totalAmountIncludingTax', 'orderDate')
    ->orderBy('orderDate', 'desc')
    ->get();

$totalRevenue = $invoices->sum('totalAmountIncludingTax');
$invoiceCount = $invoices->count();

echo "Total invoices: {$invoiceCount}\n";
echo "Total revenue: $" . number_format($totalRevenue, 2);
```

### Example 3: Sync Inventory Levels

[](#example-3-sync-inventory-levels)

```
use Ktr\BusinessCentral\Models\ApiV20\Items;

// Get low stock items
$lowStockItems = Items::query()
    ->where('type', 'Inventory')
    ->where('inventory', '
