承接 kurusa/fortnox-php-client 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

kurusa/fortnox-php-client

Composer 安装命令:

composer require kurusa/fortnox-php-client

包简介

PHP client for the Fortnox API with OAuth2 support.

README 文档

README

PHP client for the Fortnox API with OAuth2 support.

Installation

composer require kurusa/fortnox-php-client

Token store

The client does not decide where OAuth tokens are stored. Implement TokenStoreInterface in your application.

use Kurusa\Fortnox\Contracts\TokenStoreInterface;
use Kurusa\Fortnox\ValueObjects\OAuthToken;

final class ArrayTokenStore implements TokenStoreInterface
{
    private ?OAuthToken $token = null;

    public function get(): OAuthToken
    {
        return $this->token;
    }

    public function save(OAuthToken $token): void
    {
        $this->token = $token;
    }
}

Basic setup

use Kurusa\Fortnox\Config\FortnoxConfig;
use Kurusa\Fortnox\Fortnox;

$tokenStore = new ArrayTokenStore();

$config = new FortnoxConfig(
    clientId: config('fortnox.client_id'),
    clientSecret: config('fortnox.client_secret'),
    redirectUri: config('fortnox.redirect_uri'),
);

$fortnox = new Fortnox(
    config: $config,
    tokenStore: $tokenStore,
);

OAuth flow

Authorization URL

use Kurusa\Fortnox\Enums\AccessType;
use Kurusa\Fortnox\Enums\Scope;

$authorizationUrl = $fortnox
    ->oauth()
    ->authorizationUrl(
        scopes: [
            Scope::Article,
            Scope::CompanyInformation,
            Scope::Customer,
            Scope::Invoice,
            Scope::Order,
        ],
        state: bin2hex(random_bytes(16)),
        accessType: AccessType::Offline,
    );
    
echo (string) $authorizationUrl;

The user should be redirected to the generated URL. After approval, Fortnox redirects back to your configured redirect URI with a code and state.

Exchange authorization code for token

$token = $fortnox
    ->oauth()
    ->exchangeCode($_GET['code']);

$tokenStore->save($token);

The returned object is an OAuthToken:

$token->accessToken;
$token->refreshToken;
$token->expiresIn;
$token->scope;

Refresh token

$currentToken = $tokenStore->get();

$newToken = $fortnox
    ->oauth()
    ->refresh($currentToken->refreshToken);

$tokenStore->save($newToken);

When refreshing a Fortnox token, store the newly returned refresh token. The old refresh token should not be reused.

API usage

API methods return FortnoxResponse.

$response->statusCode;
$response->data;
$response->headers;
$response->successful();

Example:

$response = $fortnox->customers()->list();

if ($response->successful()) {
    print_r($response->data);
}

Customers

use Kurusa\Fortnox\Data\Customers\CreateCustomerData;
use Kurusa\Fortnox\Data\Customers\UpdateCustomerData;

$response = $fortnox->customers()->list();

$response = $fortnox->customers()->getByNumber('1');

$response = $fortnox->customers()->create(new CreateCustomerData(
    name: 'Example Customer',
    email: 'customer@example.test',
    phone: '+37200000000',
    address1: 'Example Street 1',
    zipCode: '12345',
    city: 'Tallinn',
    country: 'Estonia',
));

$response = $fortnox->customers()->update('1', new UpdateCustomerData(
    email: 'new-email@example.test',
    phone: '+37211111111',
));

$response = $fortnox->customers()->deleteByNumber('1');

Articles

use Kurusa\Fortnox\Data\Articles\CreateArticleData;
use Kurusa\Fortnox\Data\Articles\UpdateArticleData;

$response = $fortnox->articles()->list();

$response = $fortnox->articles()->getByNumber('SKU-001');

$response = $fortnox->articles()->create(new CreateArticleData(
    description: 'Example article',
    articleNumber: 'SKU-001',
    unit: 'pcs',
    salesPrice: 10.50,
    active: true,
));

$response = $fortnox->articles()->update('SKU-001', new UpdateArticleData(
    description: 'Updated article',
    salesPrice: 12.00,
));

Orders

use Kurusa\Fortnox\Data\Orders\CreateOrderData;
use Kurusa\Fortnox\Data\Orders\OrderRowData;

$response = $fortnox->orders()->list();

$response = $fortnox->orders()->getByDocumentNumber('1001');

$response = $fortnox->orders()->create(new CreateOrderData(
    customerNumber: '1',
    rows: [
        new OrderRowData(
            articleNumber: 'SKU-001',
            deliveredQuantity: 2,
            price: 10.50,
        ),
    ],
));

Invoices

use Kurusa\Fortnox\Data\Invoices\CreateInvoiceData;
use Kurusa\Fortnox\Data\Invoices\InvoiceRowData;

$response = $fortnox->invoices()->list();

$response = $fortnox->invoices()->getByDocumentNumber('1001');

$response = $fortnox->invoices()->create(new CreateInvoiceData(
    customerNumber: '1',
    rows: [
        new InvoiceRowData(
            articleNumber: 'SKU-001',
            deliveredQuantity: 2,
            price: 10.50,
        ),
    ],
));

$response = $fortnox->invoices()->bookkeep('1001');

Company information

$response = $fortnox->companyInformation()->get();

Errors

API errors throw FortnoxApiException.

use Kurusa\Fortnox\Exceptions\FortnoxApiException;

try {
    $response = $fortnox->customers()->list();
} catch (FortnoxApiException $exception) {
    $statusCode = $exception->statusCode;
    $response = $exception->response;
}

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 8
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-06

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固