kingcode/exact-php-client

此软件包已被废弃且不再维护。作者建议使用picqer/exact-php-client软件包。

Exact API的PHP客户端

v3.8.04 2017-10-30 14:25 UTC

README

Build Status

用于使用Exact Online API的PHP客户端库。

注意:对于Guzzle 6,请使用v2;对于Guzzle 3,请使用v1。

Composer安装

可以通过Composer安装此PHP客户端。

composer require picqer/exact-php-client

使用方法

  1. 在Exact App Center设置应用以获取凭据
  2. 从您的应用中授权集成
  3. 解析回调并完成连接设置
  4. 使用库进行操作

步骤1-3在设置时仅需执行一次。

在Exact App Center设置应用以获取凭据

在Exact App Center设置一个应用以获取您的Client IDClient Secret。您还需要设置正确的回调URL以使OAuth工作。

从您的应用中授权集成

以下是一个示例authorize()函数。

$connection = new \Picqer\Financials\Exact\Connection();
$connection->setRedirectUrl('CALLBACK_URL'); // Same as entered online in the App Center
$connection->setExactClientId('CLIENT_ID');
$connection->setExactClientSecret('CLIENT_SECRET');
$connection->redirectForAuthorization();

这将重定向用户到Exact进行登录并授权您的集成。

解析回调并完成连接设置

Exact将重定向回您提供的回调URL。回调将接收一个code参数。这是OAuth的授权码。保存此代码。

创建一个新的Exact连接,以便库可以交换代码并获取accesstokenrefreshtokenaccesstoken是一个临时令牌,允许您的应用与Exact进行通信。refreshtoken是一个用于获取新的accesstoken并刷新refreshtoken的令牌。库将为您处理所有这些。以下是一个通用的connect()函数,它返回API连接。

$connection = new \Picqer\Financials\Exact\Connection();
$connection->setRedirectUrl('CALLBACK_URL');
$connection->setExactClientId('CLIENT_ID');
$connection->setExactClientSecret('CLIENT_SECRET');

if (getValue('authorizationcode')) // Retrieves authorizationcode from database
	$connection->setAuthorizationCode(getValue('authorizationcode'));

if (getValue('accesstoken')) // Retrieves accesstoken from database
	$connection->setAccessToken(unserialize(getValue('accesstoken')));

if (getValue('refreshtoken')) // Retrieves refreshtoken from database
	$connection->setRefreshToken(getValue('refreshtoken'));

if (getValue('expires_in'))  // Retrieves expires timestamp from database
	$connection->setTokenExpires(getValue('expires_in'));

// Make the client connect and exchange tokens
try {
	$connection->connect();
} catch (\Exception $e)
{
	throw new Exception('Could not connect to Exact: ' . $e->getMessage());
}

// Save the new tokens for next connections
setValue('accesstoken', serialize($connection->getAccessToken()));
setValue('refreshtoken', $connection->getRefreshToken());

// Optionally, save the expiry-timestamp. This prevents exchanging valid tokens (ie. saves you some requests)
setValue('expires_in', $connection->getTokenExpires());

关于部门(行政部门)

默认情况下,库将使用用户的默认行政部门。这意味着当用户在Exact Online中切换行政部门时,库也将使用此行政部门。

使用库进行操作(示例)

// Optionally set administration, otherwise use the current administration of the user
$connection->setDivision(123456);

// Create a new account
$account = new Account($connection);
$account->AddressLine1 = $customer['address'];
$account->AddressLine2 = $customer['address2'];
$account->City = $customer['city'];
$account->Code = $customer['customerid'];
$account->Country = $customer['country'];
$account->IsSales = 'true';
$account->Name = $customer['name'];
$account->Postcode = $customer['zipcode'];
$account->Status = 'C';
$account->save();


// Add a product in Exact
$item = new Item($connection);
$item->Code = $productcode;
$item->CostPriceStandard = $costprice;
$item->Description = $name;
$item->IsSalesItem = true;
$item->SalesVatCode = 'VH';
$item->save();


// Retrieve an item
$item = new Item($connection);
$item->find(ID);

// List items
$item = new Item($connection);
$item->get();

// List items with filter (using a filter always returns a collection)
$item = new Item($connection);
$items = $item->filter("Code eq '$productcode'"); // Uses filters as described in Exact API docs (odata filters)

// Create new invoice with invoice lines
$items[] = [
	'Item'      => $itemId,
	'Quantity'  => $orderproduct['amount'],
	'UnitPrice' => $orderproduct['price']
];

$salesInvoice = new SalesInvoice($this->connection());
$salesInvoice->InvoiceTo = $customer_code;
$salesInvoice->OrderedBy = $customer_code;
$salesInvoice->YourRef = $orderId;
$salesInvoice->SalesInvoiceLines = $items;

连接到NL以外的其他Exact国家

根据Exact开发者指南选择正确的基URL。

<?php
$connection = new \Picqer\Financials\Exact\Connection();
$connection->setRedirectUrl('CALLBACK_URL');
$connection->setExactClientId('CLIENT_ID');
$connection->setExactClientSecret('CLIENT_SECRET');
$connection->setBaseUrl('https://start.exactonline.de');

查看src/Picqer/Financials/Exact获取所有可用的实体。

Webhooks

可以通过 WebhookSubscription 实体来管理 webhook 订阅。

为了验证传入的 webhook 调用,可以使用 Authenticatable 特性。将完整的 JSON 请求和 Exact 提供的 Webhook 密钥传递给 authenticate 方法,它将返回 true 或 false。

故障排除

出现 'Picqer\Financials\Exact\ApiException' 异常,信息为 '错误 400:请向查询字符串中添加 $select 或 $top=1 语句。

在特定情况下,遗憾的是 Exact API 文档中没有记录这一点,这是必需的。可能是为了防止请求过载。遇到此错误时,您需要添加 select 或 top。select 用于提供您想要提取的字段列表,$top=1 将结果限制为一个条目。

示例

仅返回 EntryID 和 FinancialYear。

$test = new GeneralJournalEntry($connection);
var_dump($test->filter('', '', 'EntryID, FinancialYear'));

$top=1 的添加方式如下

$test = new GeneralJournalEntry($connection);
var_dump($test->filter('', '', '', ['$top'=> 1]));

认证错误

出现 '致命错误:未捕获异常:无法连接到 Exact:客户端错误:POST https://start.exactonline.nl/api/oauth2/token 导致 400 请求错误响应:Bad Request 在 /var/www/html/oauth_call_connect.php:61 栈跟踪:#0 {main} 抛出在 /var/www/html/oauth_call_connect.php 行 61`'

此错误发生是因为您在重定向 URL 中获得的代码仅对一次调用有效。当您再次调用认证过程并使用一个 "已使用" 的代码时,您会得到这个错误。请确保您只使用 Exact Online 提供的代码一次以获取访问令牌。

代码示例

例如,请参阅: example/example.php

待办事项

  • 当前实体不包含所有可用的属性。如果您需要它们,请自由提交包含或扩展实体的 PR。使用 greasemonkey 或 tampermonkey 中的 userscript.js 生成一致和完整的实体。