beycanpress/freshbooks

FreshBooks API SDK。

0.1.5 2023-12-21 07:42 UTC

This package is auto-updated.

Last update: 2024-09-21 09:15:12 UTC


README

作为BeycanPress,我们决定在我们公司使用FreshBooks。然而,我们发现没有适用于WooCommerce的集成插件。虽然有很多人工自动化系统,但我们只想生成自动发票,所以我们准备了这个PHP SDK。我们邀请FreshBooks的用户进行贡献。目前,我们只集成了客户、发票、费用和付款模型。

通过此PHP SDK增强的WooCommerce FreshBooks集成插件:WooCommerce FreshBooks Integration

如何使用?

安装

composer require beycanpress/freshbooks

首次连接

<?php

use BeycanPress\FreshBooks\Connection;

$connection = new Connection(
    'your_client_id', 
    'your_client_secret', 
    'your_redirect_uri'
);

// Get authorization url
$authRequestUrl = $connection->getAuthRequestUrl();

您将被重定向到上述方法中获取的URL以从FreshBooks获取访问权限。当您通过FreshBooks确认访问权限时,您将被重定向到带有“code”GET参数的重定向URL地址。

通过获取上述方法中通过的方式接收访问代码,您的FreshBooks连接将在收到访问代码后建立。但是,您需要这样做一次。因为“access_token”将随后通过“refresh_token”继续更新。

<?php

// Get access token
$authCode = isset($_GET['code']) ? $_GET['code'] : null;
$connection->getAccessTokenByAuthCode($authCode);

然后您需要使用“setAccount”方法告诉SDK要操作的账户,如下所示。如果不传递$id参数,它将选择第一个账户。或者,您可以使用“getAccounts”方法获取账户,将它们保存到您的数据库中,并在那里设置选择的账户。

<?php

// Set account and get account id for save db
$account = $connection->setAccount(?$id)->getAccount();

// save $account->getId() to your database

后续连接

如果您已经按照上述方式完成了首次连接,只需使用下面的代码进行后续连接即可。

<?php

use BeycanPress\FreshBooks\Connection;

$connection = new Connection(
    'your_client_id', 
    'your_client_secret', 
    'your_redirect_uri'
);

if (file_exists($connection->getTokenFile())) {
    $connection->refreshAuthentication();
    $connection->setAccount(/* get account id from your database */);
}

连接方法

// Get authorization url
$authRequestUrl = $connection->getAuthRequestUrl();

// Get access token
$connection->getAccessTokenByAuthCode(/* get code from $authRequestUrl */);

// Refresh access token
// $direct (bool) is optional. If you want to renew instantly before the token expires.
$connection->refreshAuthentication();

// Set account
// $id (int) is optional. If you don't pass an $id parameter, it will choose the first account.
$connection->setAccount(?$id);

// Get accounts
$accounts = $connection->getAccounts();

// Get current account
$account = $connection->getAccount();

// Get token file path
$tokenFile = $connection->getTokenFile();

// Get token data
$tokenData = $connection->getTokenData();

// Delete token file
$tokenData = $connection->deleteTokenFile();

// Get token expire status
$expireStatus = $connection->getExpireStatus();

// Revoke access token
$connection->revokeAccessToken();

// Get profile
$profile = $connection->getProfile();

// Get business memberships
$business = $connection->getBusinessMemberships();

// Get first business membership
$businessMember = $connection->getFirstAccount();

// Create client model
$client = $connection->client();

// Create invoice model
$invoice = $connection->invoice();

// Create expense model
$expense = $connection->expense();

// Create payment model
$payment = $connection->payment();

使用模型

在使用模型时,您需要参考FreshBooks API文档。因为例如,如果您不想添加折扣数据,您只需将discountValue属性留空即可。所以您不需要添加任何数据。所以我们建议您查看文档。

FreshBooks API文档

此外,每个模型都有getById、create、update、delete方法。您可以在文档中看到这一点。update和delete方法需要$id参数。但是这个参数不是必需的。因为如果您已经使用getById检索了发票或费用数据。当前在模型中设置的id将被使用。

从模型派生对象时,您需要在构造方法中给出“Connection”类。然而,“Connection”类中为每个模型提供了没有这个的派生方法。您可以在下面的示例中看到。

// Examples

use BeycanPress\FreshBooks\Connection;
use BeycanPress\FreshBooks\Models\Client;
use BeycanPress\FreshBooks\Models\Invoice;
use BeycanPress\FreshBooks\Models\Expense;
use BeycanPress\FreshBooks\Models\Payment;
use BeycanPress\FreshBooks\Models\InvoiceLine;

$connection = new Connection(
    'your_client_id', 
    'your_client_secret', 
    'your_redirect_uri'
);

if (file_exists($connection->getTokenFile())) {
    $connection->refreshAuthentication();
    $connection->setAccount(/* get account id from your database */);
}

$invoice = new Invoice($connection);
// or
$invoice = $connection->invoice();

// Get invoice by id
$invoice = $invoice->getById(/* invoice id */);

// Delete invoice
$invoice->delete();

// Update invoice
$invoice->setDescription(/* description */);

$invoice->update();

// Create client if not exist
$client = $connection->client();

if (!$client->searchByEmail(/* email */)) {
    $client->setEmail(/* email */)
    ->setFirstName(/* first name */)
    ->setLastName(/* last name */)
    ->setOrganization(/* organization */)
    ->setMobilePhone(/* mobile phone */)
    ->setBillingStreet(/* billing street */)
    ->setBillingStreet2(/* billing street 2 */)
    ->setBillingCity(/* billing city */)
    ->setBillingProvince(/* billing province */)
    ->setBillingPostalCode(/* billing postal code */)
    ->setBillingCountry(/* billing country */)
    ->setCurrencyCode(/* currency code */)
    ->create();
}

$lines = [];

$lines[] = (new InvoiceLine())
->setName(/* name */)
->setAmount((object) [
    "amount" => /* amount */,
    "code" => /* currency code */
])
->setQuantity(/* quantity */);

if (/* if have taxes */) {
    $taxes = [/* tax 1 */, /* tax 2 */];

    if (isset($taxes[0])) {
        $tax = $taxes[0];
        $line->setTaxName1(/* tax name */)
        ->setTaxAmount1(/* tax amount */);
    }

    if (isset($taxes[1])) {
        $tax = $taxes[1];
        $line->setTaxName2(/* tax name */)
        ->setTaxAmount2(/* tax amount */);
    }
}
// Create invoice
$invoice = $connection->invoice()
->setCustomerId($client->getId())
->setStatus("draft")
->setCreateDate(date("Y-m-d"))
->setLines($lines);

if (/* if have discount */) {
    $invoice->setDiscountValue(/* discount value */)
    ->setDiscountDescription(/* discount description (discount code) */);
}

$invoice->create();

if (/* if you want send email to customer */) {
    $invoice->sendToEMail($email);
}

if (/* if invoice already paid */) {
    $connection->payment()
    ->setInvoiceId($invoice->getId())
    ->setAmount((object) [
        "amount" => $invoice->getOutstanding()->amount
    ])
    ->setDate(date("Y-m-d"))
    ->setType("Other" /* or "Credit" */) 
    ->create();
}

// or you can see all payment types: Payment::$types (private property)