ktr/business-central-sdk
Composer 安装命令:
composer require ktr/business-central-sdk
包简介
Laravel SDK for Microsoft Business Central - Connect to Business Central web services with elegant model-based API
README 文档
README
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?
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
✅ 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 & 12 Support - Tested on PHP 8.2 and 8.3
Requirements
- PHP 8.2 or higher
- Laravel 11.0 or higher
Installation
Install the package via Composer:
composer require ktr/business-central-sdk
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
- Register your app in Azure Portal
- Create an App Registration with API permissions for Business Central
- Generate a client secret
- Note your Tenant ID from Azure AD
- Find your Company ID and Environment from Business Central
Tip: For sandbox testing, set
BUSINESS_CENTRAL_ENVIRONMENT=sandbox
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)
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
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
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
The Model API includes a powerful query builder with OData support:
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
// 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', '<', 50); }) ->get();
Selecting Fields
// Select specific fields only $customers = Customers::select('id', 'displayName', 'email') ->get(); // Select with filtering $items = Items::select('id', 'number', 'displayName', 'unitPrice') ->where('type', 'Inventory') ->orderBy('displayName') ->get();
Expanding Relationships
use Ktr\BusinessCentral\Models\ApiV20\SalesInvoices; use Ktr\BusinessCentral\Models\ApiV20\SalesInvoiceLines; // Expand related entities $invoice = SalesInvoices::query() ->expand(SalesInvoiceLines::class) ->first(); // Multiple expands $order = SalesOrders::query() ->expand(SalesOrderLines::class, 'customer', 'shipmentMethod') ->where('number', 'SO-001') ->first();
Sorting
// Order by single field $customers = Customers::orderBy('displayName', 'asc')->get(); // Order by multiple fields $items = Items::query() ->orderBy('type', 'asc') ->orderBy('unitPrice', 'desc') ->get();
Pagination
// Simple pagination $items = Items::take(10)->get(); // First 10 items // Skip and take $items = Items::skip(20)->take(10)->get(); // Items 21-30 // Lazy loading for large datasets (memory efficient) Items::lazy(1000)->each(function ($item) { // Process each item without loading all into memory echo $item->displayName; }); // Get all records (uses lazy loading internally) $allItems = Items::all();
Finding Records
// Find by ID $customer = Customers::find('{customer-id}'); // First matching record $customer = Customers::where('email', 'john@example.com')->first(); // Get all matching records $customers = Customers::where('city', 'Boston')->get(); // Count records $count = Customers::where('blocked', false)->count();
Data Type Handling
The query builder intelligently handles different data types to ensure correct OData formatting:
// String values - automatically quoted Items::where('type', 'Inventory')->get(); // Generates: type eq 'Inventory' // Numeric values - not quoted Items::where('unitPrice', '>', 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: balanceDue lt 0 // Real-world example: Items with inventory greater than zero use Ktr\BusinessCentral\Models\ODataV4\ItemQuantities; $items = ItemQuantities::query() ->where('Inventory', '>', 0) ->get(); // Generates: Inventory gt 0
Important Notes:
- Numeric
0is correctly handled as integer, not string'0' - Boolean
falseis distinct from integer0 - String values are automatically URL-encoded for OData compatibility
- DateTime objects are automatically detected and formatted correctly
Available Models
This SDK provides access to 85+ Business Central entities. Here are the most commonly used:
Sales & Customers
Customers- Customer master dataSalesOrders- Sales ordersSalesOrderLines- Sales order line itemsSalesInvoices- Posted sales invoicesSalesInvoiceLines- Sales invoice line itemsSalesQuotes- Sales quotesSalesShipments- Posted sales shipmentsSalesCreditMemos- Sales credit memos
Purchasing & Vendors
Vendors- Vendor master dataPurchaseOrders- Purchase ordersPurchaseOrderLines- Purchase order line itemsPurchaseInvoices- Posted purchase invoicesPurchaseInvoiceLines- Purchase invoice line itemsPurchaseCreditMemos- Purchase credit memos
Inventory & Items
Items- Item master dataItemCategories- Item categoriesUnitsOfMeasure- Units of measureInventoryPostingGroups- Inventory posting groups
Financial
Accounts- Chart of accountsGeneralLedgerEntries- G/L entriesCurrencies- Currency master dataCurrencyExchangeRates- Exchange ratesPaymentTerms- Payment termsPaymentMethods- Payment methodsDimensions- Financial dimensionsBankAccounts- Bank account master data
Journals
Journals- General journalsItemJournals- Item journalsCustomerPaymentJournals- Payment journalsVendorPaymentJournals- Vendor payment journals
Reporting & Analysis
BalanceSheets- Balance sheet reportsIncomeStatements- Income statement reportsCashFlowStatements- Cash flow reportsAgedAccountsReceivables- AR aging reportsAgedAccountsPayables- AP aging reportsTrialBalances- Trial balance reports
Master Data
Employees- Employee recordsProjects- Project/job cardsCountriesRegions- Countries and regionsTaxGroups- Tax groupsTaxAreas- Tax areasContacts- Contact informationCompanyInformation- Company details
Tip: All models are located in
Ktr\BusinessCentral\Models\ApiV20namespace and include full PHPDoc type hints for IDE autocompletion.
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.
Real-World Examples
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
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
use Ktr\BusinessCentral\Models\ApiV20\Items; // Get low stock items $lowStockItems = Items::query() ->where('type', 'Inventory') ->where('inventory', '<', 10) ->select('id', 'number', 'displayName', 'inventory') ->orderBy('inventory', 'asc') ->get(); foreach ($lowStockItems as $item) { echo "{$item->displayName}: {$item->inventory} units in stock\n"; // Your reorder logic here if ($item->inventory < 5) { // Send notification or create purchase order } }
Example 4: Customer Management
use Ktr\BusinessCentral\Models\ApiV20\Customers; // Create new customer $customer = Customers::create([ 'displayName' => 'New Customer Inc.', 'email' => 'contact@newcustomer.com', 'phoneNumber' => '+1-555-0100', 'addressLine1' => '789 Customer Blvd', 'city' => 'Seattle', 'state' => 'WA', 'postalCode' => '98101', 'countryCode' => 'US', 'currencyCode' => 'USD', 'blocked' => false, 'taxLiable' => true ]); // Update customer information $customer->email = 'newemail@newcustomer.com'; $customer->creditLimit = 50000.00; $customer->save(); // Find customers by city $seattleCustomers = Customers::query() ->where('city', 'Seattle') ->where('blocked', false) ->select('displayName', 'email', 'phoneNumber') ->get();
Troubleshooting
Authentication Errors
If you receive authentication errors:
- Verify your credentials in
.env - Check that your Azure app has the correct API permissions
- Ensure your client secret hasn't expired
- Clear the token cache:
php artisan cache:clear
API Limitations
- Business Central API has rate limits - implement appropriate throttling
- Some entities are read-only (e.g., Posted Invoices)
- Complex calculations may need to be done in Business Central AL code first
OData Query Syntax
This SDK uses OData v4 query conventions. If you encounter filter errors:
- Use single quotes for string values:
where('city', 'Boston') - Use proper operators:
eq,ne,gt,ge,lt,le - Check the OData documentation for advanced syntax
Getting Help
- Review the Business Central API Documentation
- Check existing GitHub Issues
- Create a new issue with details about your problem
Testing
Run the test suite:
composer test
Run tests with coverage:
composer test-coverage
Check code style:
composer pint-test
Fix code style:
composer pint
Changelog
Please see CHANGELOG for recent changes and version history.
Contributing
We welcome contributions! Please see CONTRIBUTING for details on how to contribute to this project.
Security
If you discover any security-related issues, please email john@ktr.fo instead of using the issue tracker.
Credits
- John Eystein Johannesen - Creator and maintainer
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
Built with ❤️ for the Laravel community
ktr/business-central-sdk 适用场景与选型建议
ktr/business-central-sdk 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 346 次下载、GitHub Stars 达 0, 最近一次更新时间为 2024 年 07 月 12 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「sdk」 「laravel」 「microsoft」 「Dynamics」 「ktr」 「business-central-sdk」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 ktr/business-central-sdk 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ktr/business-central-sdk 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 ktr/business-central-sdk 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A simple PHP package for sending messages to Microsoft Teams
Laravel 5 Queue Driver for Microsoft Azure Storage Queue
Laravel package for the simplification and integration of many of your users most wanted login providers. Installation is a breeze. Never worry about OAuth again.
Magento 2 Social Login extension is designed for quick login to your Magento 2 store without procesing complex register steps
LaraMicrosoft-Auth: autenticación social con Microsoft Entra ID (Office 365). Integrable con frontends Vue, Nuxt o React.
Azure Active Directory OAuth 2.0 Client Provider for The PHP League OAuth2-Client
统计信息
- 总下载量: 346
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 15
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-07-12