PHP code example of codebar-ag / laravel-bexio

1. Go to this page and download the library: Download codebar-ag/laravel-bexio library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

codebar-ag / laravel-bexio example snippets


use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithToken;

// Using environment configuration
$connector = new BexioConnector(new ConnectWithToken());

// Or with explicit token
$connector = new BexioConnector(new ConnectWithToken(token: 'your-specific-token'));

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithOAuth;

// Using environment configuration
$connector = new BexioConnector(new ConnectWithOAuth());

// Or with explicit configuration
$connector = new BexioConnector(new ConnectWithOAuth(
    client_id: 'your_client_id',
    client_secret: 'your_client_secret',
    redirect_uri: 'https://yourapp.com/bexio/callback',
    scopes: ['openid', 'profile', 'email', 'accounting']
));

// config/bexio.php
'route_prefix' => 'custom-bexio-prefix',

// Add custom middleware to OAuth routes (in addition to 'web' middleware)
'route_middleware' => ['auth', 'verified'],

// When OAuth authentication is successful
session()->get('bexio_oauth_success'); // true
session()->get('bexio_oauth_message'); // 'Successfully authenticated with Bexio.'

// When user rejects authorization or OAuth returns an error
session()->get('bexio_oauth_success'); // false
session()->get('bexio_oauth_message'); // 'OAuth authorization failed: access_denied'

// When 



namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function index(Request $request)
    {
        if (session()->has('bexio_oauth_success')) {
            $success = session()->get('bexio_oauth_success');
            $message = session()->get('bexio_oauth_message');
            
            if ($success) {
                // OAuth authentication was successful
                // You can now use the BexioConnector to make API calls
                return view('dashboard.index')->with('success', $message);
            } else {
                // OAuth authentication failed
                return view('dashboard.index')->with('error', $message);
            }
        }

        return view('dashboard.index');
    }
}

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithToken;

// Different token for each tenant
$tenantToken = $currentUser->bexio_token; // Retrieved from your database
$connector = new BexioConnector(new ConnectWithToken(token: $tenantToken));



namespace App\Support\Bexio;

use CodebarAg\Bexio\Contracts\BexioOAuthConfigResolver as BexioOAuthConfigResolverContract;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithOAuth;
use Illuminate\Support\Facades\Auth;

class BexioOAuthConfigResolver implements BexioOAuthConfigResolverContract
{
    public function resolve(): ConnectWithOAuth
    {
        $user = Auth::user();
        
        return new ConnectWithOAuth(
            client_id: $user->bexio_client_id,
            client_secret: $user->bexio_client_secret,
            scopes: $user->bexio_scopes ?? []
        );
    }
}



namespace App\Support\Bexio;

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Contracts\BexioOAuthAuthenticationStoreResolver as BexioOAuthAuthenticationStoreResolverContract;
use CodebarAg\Bexio\Contracts\BexioOAuthConfigResolver;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Saloon\Http\Auth\AccessTokenAuthenticator;

class BexioOAuthAuthenticationStoreResolver implements BexioOAuthAuthenticationStoreResolverContract
{
    protected string $cacheKey = 'bexio_oauth_authenticator';

    public function get(): ?AccessTokenAuthenticator
    {
        $userId = Auth::id();
        $cacheStore = Cache::store(config('bexio.cache_store', config('cache.default')));
        $cacheKey = $this->cacheKey . ':' . $userId;

        if (! $cacheStore->has($cacheKey)) {
            return null;
        }

        try {
            $serialized = Crypt::decrypt($cacheStore->get($cacheKey));
            $authenticator = AccessTokenAuthenticator::unserialize($serialized);

            if ($authenticator->hasExpired()) {
                // Refresh the access token
                $resolver = App::make(BexioOAuthConfigResolver::class);
                $connector = new BexioConnector($resolver->resolve());
                
                $authenticator = $connector->refreshAccessToken($authenticator);
                $this->put($authenticator);
            }

            return $authenticator;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function put(AccessTokenAuthenticator $authenticator): void
    {
        $userId = Auth::id();
        $cacheStore = Cache::store(config('bexio.cache_store', config('cache.default')));
        $cacheKey = $this->cacheKey . ':' . $userId;

        $serialized = $authenticator->serialize();
        $encrypted = Crypt::encrypt($serialized);

        $cacheStore->put($cacheKey, $encrypted);
    }

    public function forget(): void
    {
        $userId = Auth::id();
        $cacheStore = Cache::store(config('bexio.cache_store', config('cache.default')));
        $cacheKey = $this->cacheKey . ':' . $userId;

        $cacheStore->forget($cacheKey);
    }
}



namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class BexioServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(
            \CodebarAg\Bexio\Contracts\BexioOAuthConfigResolver::class,
            \App\Support\Bexio\BexioOAuthConfigResolver::class
        );

        $this->app->bind(
            \CodebarAg\Bexio\Contracts\BexioOAuthAuthenticationStoreResolver::class,
            \App\Support\Bexio\BexioOAuthAuthenticationStoreResolver::class
        );
    }
}

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithOAuth;

// The connector will:
// 1. Use your custom config resolver to get user-specific OAuth config
// 2. Use your custom auth store resolver to manage tokens per user
// 3. Automatically handle token refresh when needed
$connector = new BexioConnector();

// If you prefer, you can still provide the config yourself
$connector = new BexioConnector(new \CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithOAuth(
    client_id: Auth::user()->bexio_client_id,
    client_secret: Auth::user()->bexio_client_secret,
));

// Or you can manually use your custom resolver
$configuration = App::make(\CodebarAg\Bexio\Contracts\BexioOAuthConfigResolver::class)->resolve();

$connector = new BexioConnector($configuration);



namespace App\Support\Bexio;

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Contracts\BexioOAuthAuthenticationValidateResolver as BexioOAuthAuthenticationValidateResolverContract;
use CodebarAg\Bexio\Dto\OAuthConfiguration\BexioOAuthAuthenticationValidationResult;
use CodebarAg\Bexio\Requests\OpenID\FetchUserInfoRequest;
use CodebarAg\Bexio\Requests\CompanyProfiles\FetchACompanyProfileRequest;
use Illuminate\Support\Facades\Redirect;

class BexioOAuthAuthenticationValidateResolver implements BexioOAuthAuthenticationValidateResolverContract
{
    public function resolve(BexioConnector $connector): BexioOAuthAuthenticationValidationResult
    {
        try {
            // Example 1: Validate user info
            $userInfo = $connector->send(new FetchUserInfoRequest());
            $userData = $userInfo->json();
            
            if (!$this->isValidUser($userData)) {
                return BexioOAuthAuthenticationValidationResult::failed(
                    Redirect::to('/unauthorized')
                        ->with('error', 'User not authorized for this application')
                        ->with('user_email', $userData['email'])
                );
            }
            
            // Example 2: Validate company permissions
            $companyProfile = $connector->send(new FetchACompanyProfileRequest());
            $companyData = $companyProfile->json();
            
            if (!$this->isAllowedCompany($companyData['id'])) {
                return BexioOAuthAuthenticationValidationResult::failed(
                    Redirect::to('/company-not-allowed')
                        ->with('error', 'Your company is not authorized to use this application')
                        ->with('company_name', $companyData['name'])
                );
            }
            
            // All validations passed
            return BexioOAuthAuthenticationValidationResult::success();
            
        } catch (\Exception $e) {
            // Handle API errors during validation
            return BexioOAuthAuthenticationValidationResult::failed(
                Redirect::to('/validation-error')
                    ->with('error', 'Unable to validate OAuth permissions: ' . $e->getMessage())
            );
        }
    }
    
    private function isValidUser(array $userData): bool
    {
        // Your custom user validation logic
        return in_array($userData['email'], [
            '[email protected]',
            '[email protected]'
        ]);
    }
    
    private function isAllowedCompany(int $companyId): bool
    {
        // Your custom company validation logic
        $allowedCompanies = [12345, 67890];
        return in_array($companyId, $allowedCompanies);
    }
}



namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class BexioServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // ... existing bindings ...
        
        $this->app->bind(
            \CodebarAg\Bexio\Contracts\BexioOAuthAuthenticationValidateResolver::class,
            \App\Support\Bexio\BexioOAuthAuthenticationValidateResolver::class
        );
    }
}

use CodebarAg\Bexio\Dto\OAuthConfiguration\BexioOAuthAuthenticationValidationResult;
use Illuminate\Support\Facades\Redirect;

// Success - proceed with storing the authenticator
BexioOAuthAuthenticationValidationResult::success();

// Failed - use default error redirect (configured redirect_url with error message)
BexioOAuthAuthenticationValidationResult::failed();

// Failed - use custom redirect with your own error handling
BexioOAuthAuthenticationValidationResult::failed(
    Redirect::to('/custom-error-page')
        ->with('error', 'Custom validation message')
        ->with('additional_data', 'any extra data you need')
);

// For default failed validation
session()->get('bexio_oauth_success'); // false
session()->get('bexio_oauth_message'); // 'Authentication validation failed.'

// For custom redirects, you control the session data
session()->get('error'); // Your custom error message
session()->get('user_email'); // Any additional data you passed

use CodebarAg\Bexio\Enums\OAuthConfiguration\OAuthOpenIDConnectScope;
use CodebarAg\Bexio\Enums\OAuthConfiguration\OAuthApiScope;

// OpenID Connect scopes
OAuthOpenIDConnectScope::OPENID->value;          // 'openid'
OAuthOpenIDConnectScope::PROFILE->value;         // 'profile'
OAuthOpenIDConnectScope::EMAIL->value;           // 'email'
OAuthOpenIDConnectScope::COMPANY_PROFILE->value; // 'company_profile'
OAuthOpenIDConnectScope::OFFLINE_ACCESS->value;  // 'offline_access'

// API scopes
OAuthApiScope::ACCOUNTING->value;     // 'accounting'
OAuthApiScope::CONTACT_SHOW->value;   // 'contact_show'
OAuthApiScope::CONTACT_EDIT->value;   // 'contact_edit'
// ... and many more

// config/bexio.php
'cache_store' => 'redis', // or any other configured cache store

// config/bexio.php
'route_prefix' => 'api/bexio',        // Custom route prefix
'redirect_url' => '/dashboard',       // Where to redirect after OAuth Callback

// Add custom middleware to OAuth routes (in addition to 'web' middleware)
'route_middleware' => ['auth', 'verified'],

// Require authentication for OAuth routes
'route_middleware' => ['auth'],

// Require authentication and email verification
'route_middleware' => ['auth', 'verified'],

// Add custom middleware
'route_middleware' => ['auth', 'custom-middleware'],

// Multiple middleware with parameters
'route_middleware' => ['auth:api', 'throttle:60,1'],

use CodebarAg\Bexio\BexioConnector;

// For single tenant (uses default resolvers)
$connector = new BexioConnector();

// For specific authentication
$connector = new BexioConnector(new ConnectWithToken(token: 'your-token'));
$connector = new BexioConnector(new ConnectWithOAuth(/* config */));

use CodebarAg\Bexio\BexioConnector;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithToken;
use CodebarAg\Bexio\Dto\OAuthConfiguration\ConnectWithOAuth;

// Token authentication using environment configuration
$connector = new BexioConnector(new ConnectWithToken());

// Token authentication with explicit token
$connector = new BexioConnector(new ConnectWithToken(token: 'your-specific-token'));

// OAuth authentication using environment configuration
$connector = new BexioConnector(new ConnectWithOAuth());

// OAuth authentication with explicit configuration
$connector = new BexioConnector(new ConnectWithOAuth(
    client_id: 'your_client_id',
    client_secret: 'your_client_secret',
    redirect_uri: 'https://yourapp.com/bexio/callback',
    scopes: ['openid', 'profile', 'email', 'accounting']
));

// Multi-tenant with custom resolvers (using default connector)
$connector = new BexioConnector();

/**
 * Fetch A List Of Account Groups
 */
$accountGroups = $connector->send(new FetchAListOfAccountGroupsRequest())->dto();

/**
 * Fetch A List Of Accounts
 */
$accounts = $connector->send(new FetchAListOfAccountsRequest())->dto();

/**
 * Search Accounts
 */
$accounts = $connector->send(new SearchAccountsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Fetch A List Of Addresses
 */
$addresses = $connector->send(new FetchAListOfAddressesRequest())->dto();

/**
 * Fetch An Address
 */
$address = $connector->send(new FetchAnAddressRequest(
    id: 1
))->dto();

/**
 * Search Addresses
 */
$addresses = $connector->send(new SearchAddressesRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Create Address
 */
$address = $connector->send(new CreateAddressRequest(
    data: new CreateEditAddressDTO(
        name: 'Test',
        subject: 'Test Subject',
        description: 'This is a test',
        address: 'Test Address',
        postcode: '1234',
        city: 'Test City',
    ) 
));

/**
 * Edit Address
 */
$address = $connector->send(new EditAnAddressRequest(
    id: 1,
    data: new CreateEditAddressDTO(
        name: 'Test Edit',
        subject: 'Test Subject Edit',
        description: 'This is a test edit',
        address: 'Test Address Edit',
        postcode: '4567',
        city: 'Test City Edit',
    ) 
));

/**
 * Delete Address
 */
$address = $connector->send(new DeleteAnAddressRequest(
    id: 1
));

/**
 * Fetch A List Of Bank Accounts
 */
$bankAccounts = $connector->send(new FetchAListOfBankAccountsRequest())->dto();

/**
 * Fetch A Single Bank Account
 */
$bankAccount = $connector->send(new FetchASingleBankAccountRequest(
    id: 1
))->dto();

/**
 * Fetch A List Of Business Years
 */
$businessYears = $connector->send(new FetchAListOfBusinessYearsRequest())->dto();

/**
 * Fetch A Business Year
 */
$businessYear = $connector->send(new FetchABusinessYearRequest(
    id: 1
))->dto();

/**
 * Fetch A List Of Calendar Years
 */
$calendarYears = $connector->send(new FetchAListOfCalendarYearsRequest())->dto();

/**
 * Fetch A Calendar Year
 */
$calendarYear = $connector->send(new FetchACalendarYearRequest(
    id: 1
))->dto();

/**
 * Fetch A List Of Company Profiles
 */
$companyProfiles = $connector->send(new FetchAListOfCompanyProfilesRequest())->dto();

/**
 * Fetch A Company Profile
 */
$companyProfile = $connector->send(new FetchACompanyProfileRequest(
    id: 1
))->dto();

/**
 * Fetch A List Of Contact Additional Addresses
 */
$contactAdditionalAddresses = $connector->send(new FetchAListOfContactAdditionalAddressesRequest(
    contactId: 1
))->dto();

/**
 * Fetch A Contact Additional Address
 */
$contactAdditionalAddress = $connector->send(new FetchAContactAdditionalAddressRequest(
    contactId: 1,
    id: 1
))->dto();

/**
 * Search Contact Additional Address
 */
$contactAdditionalAddresses = $connector->send(new SearchContactAdditionalAddressesRequest(
    contactId: 1,
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Create Contact Additional Address
 */
$contactAdditionalAddress = $connector->send(new CreateContactAdditionalAddressRequest(
    contactId: 1,
    data: new CreateEditContactAdditionalAddressDTO(
        name: 'Test',
        subject: 'Test Subject',
        description: 'This is a test',
        address: 'Test Address',
        postcode: '1234',
        city: 'Test City',
    )
));

/**
 * Edit Contact Additional Address
 */
$contactAdditionalAddress = $connector->send(new EditAContactAdditionalAddressRequest(
    contactId: 1,
    id: 9,
    data: new CreateEditContactAdditionalAddressDTO(
        name: 'Test Edit',
        subject: 'Test Subject Edit',
        description: 'This is a test edit',
        address: 'Test Address Edit',
        postcode: '4567',
        city: 'Test City Edit',
    )
));

/**
 * Delete Contact Additional Address
 */
$contactAdditionalAddress = $connector->send(new DeleteAContactAdditionalAddressRequest(
    contactId: 1,
    id: 9,
));

/**
 * Fetch A List Of Contact Groups
 */
$contactGroups = $connector->send(new FetchAListOfContactGroupsRequest())->dto();

/**
 * Fetch A Contact Group
 */
$contactGroup = $connector->send(new FetchAContactGroupRequest(
    id: 1
))->dto();

/**
 * Search Contact Groups
 */
$contactGroups = $connector->send(new SearchContactGroupsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Create Contact Group
 */
$contactGroup = $connector->send(new CreateContactGroupRequest(
    data: new CreateEditContactGroupDTO(
        name: 'Name'
    )
));

/**
 * Edit Contact Group
 */
$contactGroup = $connector->send(new EditAContactGroupRequest(
    id: 1,
    data: new CreateEditContactGroupDTO(
        name: 'Name'
    )
));

/**
 * Delete Contact Group
 */
$contactGroup = $connector->send(new DeleteAContactGroupRequest(
    id: 1
));

/**
 * Fetch A List Of Contact Relations
 */
$contactRelations = $connector->send(new FetchAListOfContactRelationsRequest())->dto();

/**
 * Fetch A Contact Relation
 */
$contactRelation = $connector->send(new FetchAContactRelationRequest(
    id: 1
))->dto();

/**
 * Search Contact Relations
 */
$contactRelations = $connector->send(new SearchContactRelationsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Create Contact Relation
 */
$contactRelation = $connector->send(new CreateContactRelationRequest(
    data: new CreateEditContactRelationDTO(
        contact_id: 1,
        contact_sub_id: 2,
        description: 'Something',
    )
));

/**
 * Edit Contact Relation
 */
$contactRelation = $connector->send(new EditAContactRelationRequest(
    id: 1,
    data: new CreateEditContactRelationDTO(
        contact_id: 1,
        contact_sub_id: 2,
        description: 'Something',
    )
));

/**
 * Delete Contact Relation
 */
$contactRelation = $connector->send(new DeleteAContactRelationRequest(
    id: 1
));

/**
* Fetch A List Of Contacts
 */
$contacts = $connector->send(new FetchAListOfContactsRequest())->dto();

/**
 * Fetch A Contact
 */
$contact = $connector->send(new FetchAContactRequest(
    id: 1
))->dto();

/**
 * Search Contacts
 */
$contacts = $connector->send(new SearchContactsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();

/**
 * Create Contact
 */
$contact = $connector->send(new CreateContactRequest(
    data: new CreateEditContactDTO(
        user_id: 1,
        owner_id: 1,
        contact_type_id: 1,
        name_1: 'Name'
    )
));

/**
 * Bulk Create Contacts
 */
$contact = $connector->send(new BulkCreateContactsRequest(
    data: [
        new CreateEditContactDTO(
            user_id: 1,
            owner_id: 1,
            contact_type_id: 1,
            name_1: 'Name'
        ),
        new CreateEditContactDTO(
            user_id: 1,
            owner_id: 1,
            contact_type_id: 1,
            name_1: 'Name 2'
        )
    ]
));

/**
 * Edit Contact
 */
$contact = $connector->send(new EditAContactRequest(
    id: 1,
    data: new CreateEditContactDTO(
        user_id: 1,
        owner_id: 1,
        contact_type_id: 1,
        name_1: 'Name'
    )
));

/**
 * Delete Contact
 */
$contact = $connector->send(new DeleteAContactRequest(
    id: 1
));

/**
 * Restore Contact
 */
$contact = $connector->send(new RestoreAContactRequest(
    id: 1
));

/**
 * Fetch A List Of Contact Sectors
 */
$contactSectors = $connector->send(new FetchAListOfContactSectorsRequest())->dto();

/**
 * Search Contact Sectors
 */
$contactSectors = $connector->send(new SearchContactSectorsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();


/**
 * Fetch A List Of Currencies
 */
$currencies = $connector->send(new FetchAListOfCurrenciesRequest())->dto();

/**
 * Fetch A Currency
 */
$currency = $connector->send(new FetchACurrencyRequest(
    id: 1
))->dto();

/**
 * Create Currency
 */
$currency = $connector->send(new CreateCurrencyRequest(
    data: new CreateCurrencyDTO(
        name: 'JPY',
        round_factor: 0.05,
    )
));

/**
 * Edit Currency
 */
$currency = $connector->send(new EditACurrencyRequest(
    id: 1,
    data: new EditCurrencyDTO(
        round_factor: 0.05,
    )
));

/**
 * Delete Currency
 */
$currency = $connector->send(new DeleteACurrencyRequest(
    id: 1
));

/**
 * Fetch All Possible Currency Codes
 */
$currencyCodes = $connector->send(new FetchAllPossibleCurrencyCodesRequest())->dto();

/**
 * Fetch Exchange Rates For Currencies
 */
$exchangeRates = $connector->send(new FetchExchangeRatesForCurrenciesRequest(
    currencyId: 1
))->dto();

/**
 * Fetch A List Of Files
 */
$files = $connector->send(new FetchAListOfFilesRequest())->dto();

/**
 * Get A Single File
 */
$file = $connector->send(new GetASingleFileRequest(
    id: 1
))->dto();

/**
 * Show A File Usage
 */
$fileUsage = $connector->send(new ShowAFileUsageRequest(
    id: 1
))->dto();

/**
 * Get A File Preview
 */
$filePreview = $connector->send(new GetAFilePreviewRequest(
    id: 1
))->stream();

/**
 * Download File Download
 */
$fileDownload = $connector->send(new DownloadFileDownloadRequest(
    id: 1
))->stream();

/**
 * Create A File
 */
$file = $connector->send(new CreateAFileRequest(
    data: [
        new MultipartValue(
            name: 'picture',
            value: fopen(__DIR__ . 'image.png', 'r'),
        )
    ],
));

/**
 * Edit A File
 */
$file = $connector->send(new EditAFileRequest(
    id: 1,
    data: new EditFileDTO(
        name: 'Test name edited',
        is_archived: false,
        source_type: 'web',
    )
));

/**
 * Delete A File
 */
$file = $connector->send(new DeleteAFileRequest(
    id: 1
));

/**
 * Fetch An Iban Payment
 */
$payment = $connector->send(new GetIbanPaymentRequest(
    bank_account_id: 1,
    payment_id: 3
))->dto();

/**
 * Create Iban Payment
 */
$payment = $connector->send(new CreateIbanPaymentRequest(
    bank_account_id: 1,
    data: new CreateEditIbanPaymentDTO(
        instructed_amount: [
            'currency' => 'CHF',
            'amount' => 100,
        ],
        recipient: [
            'name' => 'Müller GmbH',
            'street' => 'Sonnenstrasse',
            'zip' => 8005,
            'city' => 'Zürich',
            'country_code' => 'CH',
            'house_number' => 36,
        ],
        iban: 'CH8100700110005554634',
        execution_date: '2024-01-08',
        is_salary_payment: false,
        is_editing_restricted: false,
        message: 'Rechnung 1234',
        allowance_type: 'no_fee',
    )
))->dto();

/**
 * Update Iban Payment
 * 
 * NOTE: THE PAYMENT MUST HAVE A STATUS OF OPEN TO BE UPDATED
 */
$payment = $connector->send(new EditIbanPaymentRequest(
    bank_account_id: 1,
    payment_id: 3,
    iban: 'CH8100700110005554634',
    id: 3,
    data: new CreateEditIbanPaymentDTO(
        instructed_amount: [
            'currency' => 'CHF',
            'amount' => 100,
        ],
        recipient: [
            'name' => 'Müller GmbH',
            'street' => 'Colchester Place',
            'zip' => 8005,
            'city' => 'Zürich',
            'country_code' => 'CH',
            'house_number' => 36,
        ],
        iban: 'CH8100700110005554634',
        execution_date: '2024-01-08',
        is_salary_payment: false,
        is_editing_restricted: false,
        message: 'Rechnung 1234',
        allowance_type: 'no_fee',
    )
))->dto();

/**
 * Fetch A List Of Invoices
 */
$invoices = $connector->send(new FetchAListOfInvoicesRequest())->dto();

/**
 * Fetch An Invoice
 */
$invoice = $connector->send(new FetchAnInvoiceRequest(
    invoice_id: 1
))->dto();

/**
 * Create An Invoice
 */
$contacts = $connector->send(new FetchAListOfContactsRequest);
$user = $connector->send(new FetchAuthenticatedUserRequest);
$languages = $connector->send(new FetchAListOfLanguagesRequest);
$banks = $connector->send(new FetchAListOfBankAccountsRequest);
$currencies = $connector->send(new FetchAListOfCurrenciesRequest);
$paymentTypes = $connector->send(new FetchAListOfPaymentTypesRequest);
$units = $connector->send(new FetchAListOfUnitsRequest);
$accounts = $connector->send(new FetchAListOfAccountsRequest);
$taxes = $connector->send(new FetchAListOfTaxesRequest(scope: 'active', types: 'sales_tax'));

$newInvoice = InvoiceDTO::fromArray([
    'title' => 'Test',
    'contact_id' => $contacts->dto()->first()->id,
    'user_id' => $user->dto()->id,
    'pr_project_id' => null,
    'language_id' => $languages->dto()->first()->id,
    'bank_account_id' => $banks->dto()->first()->id,
    'currency_id' => $currencies->dto()->first()->id,
    'payment_type_id' => $paymentTypes->dto()->first()->id,
    'mwst_type' => 1,
    'mwst_is_net' => true,
    'show_position_taxes' => true,
    'is_valid_from' => now()->format('Y-m-d h:m:s'),
    'is_valid_to' => now()->addDays(5)->format('Y-m-d h:m:s'),
    'api_reference' => Str::uuid(),
    'positions' => [
        InvoicePositionDTO::fromArray([
            'type' => 'KbPositionText',
            'show_pos_nr' => true,
            'text' => Str::uuid(),
        ]),
        InvoicePositionDTO::fromArray([
            'type' => 'KbPositionCustom',
            'amount' => 1,
            'unit_id' => $units->dto()->first()->id,
            'account_id' => $accounts->dto()->filter(fn ($account) => $account->account_type_enum === AccountTypeEnum::ACTIVE_ACCOUNTS())->first()->id,
            'tax_id' => $taxes->dto()->first()->id,
            'text' => Str::uuid(),
            'unit_price' => 100,
            'discount_in_percent' => '0',
        ]),
    ],
]);

$invoice = $connector->send(new CreateAnInvoiceRequest(invoice: $newInvoice))->dto();

/**
 * Edit An Invoice
 */
$editInvoice = $connector->send(new FetchAnInvoiceRequest(invoice_id: 1))->dto();

$editInvoice->title = 'Test Invoice';

$invoice = $connector->send(new EditAnInvoiceRequest(invoice_id: 1, invoice: $editInvoice));

/**
 * Delete An Invoice
 */
$response = $connector->send(new DeleteAnInvoiceRequest(
    invoice_id: 1
));

/**
 * Cancel An Invoice
 */
$response = $connector->send(new CancelAnInvoiceRequest(
    invoice_id: 1
));

/**
 * Create A Default Position For An Invoice
 */
$units = $connector->send(new FetchAListOfUnitsRequest);
$accounts = $connector->send(new FetchAListOfAccountsRequest);
$taxes = $connector->send(new FetchAListOfTaxesRequest(scope: 'active', types: 'sales_tax'));

$position = InvoicePositionDTO::fromArray([
    'type' => 'KbPositionCustom',
    'amount' => 1,
    'unit_id' => $units->dto()->first()->id,
    'account_id' => $accounts->dto()->filter(fn ($account) => $account->account_type === 1)->first()->id,
    'tax_id' => $taxes->dto()->first()->id,
    'text' => Str::uuid(),
    'unit_price' => 100,
    'discount_in_percent' => '0',
]);

$response = $connector->send(new CreateADefaultPositionRequest(
    kb_document_type: 'kb_invoice',
    invoice_id: 1,
    position: $position,
));

/**
 * Create A Sub Position For An Invoice
 */
$position = InvoicePositionDTO::fromArray([
    'type' => 'KbSubPosition',
    'text' => Str::uuid(),
    'show_pos_nr' => true,
]);

$response = $connector->send(new CreateASubPositionRequest(
    kb_document_type: 'kb_invoice',
    invoice_id: 1,
    position: $position,
));

/**
 * Show PDF
 */
$pdf = $connector->send(new ShowPdfRequest(
    invoice_id: 1
))->dto();

/**
 * Saving PDF from response
 */
Storage::disk('local')->put('your/directory/'. $pdf->name, base64_decode($pdf->content));

/**
 * Download PDF from response
 */
return response(base64_decode($pdf->content))
    ->header('Content-Type', $pdf->mime)
    ->header('Content-Disposition', 'attachment; filename="'.$pdf->name.'"')
    ->header('Content-Length', $pdf->size);

/**
 * Fetch A List Of Languages
 */
$languages = $connector->send(new FetchAListOfLanguagesRequest())->dto();

/**
 * Fetch A List Of Manual Entries
 */
$manualEntries = $connector->send(new FetchAListOfManualEntriesRequest())->dto();

/**
 * Fetch Files Of Accounting Entry
 */
$files = $connector->send(new FetchFilesOfAccountingEntryRequest(
    manual_entry_id: 1,
    entry_id: 1
))->dto();

/**
 * Fetch File Of Accounting Entry Line
 */
$file = $connector->send(new FetchFileOfAccountingEntryLineRequest(
    manual_entry_id: 1,
    entry_id: 1,
    line_id: 1
))->dto();

/**
 * Create Manual Entry
 */
$manualEntry = $connector->send(new CreateManualEntryRequest(
    data: new CreateManualEntryDTO(
        type: 'manual_single_entry',
        date: '2023-12-13',
        reference_nr: '1234',
        entries: collect([
            new CreateEntryDTO(
                debit_account_id: 89,
                credit_account_id: 90,
                tax_id: 10,
                tax_account_id: 89,
                description: 'Something',
                amount: 100,
                currency_id: 1,
                currency_factor: 1,
            ),
        ]),
    )
));

/**
 * Add File To Accounting Entry Line
 */
$manualEntry = $connector->send(new AddFileToAccountingEntryLineRequest(
    manual_entry_id: 1,
    entry_id: 1,
    data: new AddFileDTO(
        name: 'fileName',
        absolute_file_path_or_stream: fopen('image.png', 'r'),
        filename: 'image.png',
    )
));

/**
 * Get Next Reference Number
 */
$referenceNumber = $connector->send(new GetNextReferenceNumberRequest())->dto();
bash
php artisan vendor:publish --provider="CodebarAg\Bexio\BexioServiceProvider" --tag="bexio-config"
php
/**
 * Fetch A Note
 */
$note = $connector->send(new FetchANoteRequest(
    id: 1
))->dto();
php
/**
 * Search Notes
 */
$notes = $connector->send(new SearchNotesRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();
php
/**
 * Delete Note
 */
$note = $connector->send(new DeleteANoteRequest(
    id: 1
));
php
/**
* Cancel A Payment
*/
$payment = $connector->send(new CancelAPaymentRequest(
    payment_id: 1
))->dto();
php
/**
* Delete A Payment
*/
$payment = $connector->send(new DeleteAPaymentRequest(
    payment_id: 1
))->json();
php
/**
* Fetch A Qr Payment
*/
$payment = $connector->send(new GetQrPaymentRequest(
    bank_account_id: 1,
    payment_id: 4
))->dto();
php
/**
 * Journal
 */
$journals = $connector->send(new JournalRequest())->dto();
php
/**
 * Fetch A Salutation
 */
$salutation = $connector->send(new FetchASalutationRequest(
    id: 1
))->dto();
php
/**
 * Search Salutations
 */
$salutations = $connector->send(new SearchSalutationsRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();
php
/**
 * Delete Salutation
 */
$salutation = $connector->send(new DeleteASalutationRequest(
    id: 1
));
php
/**
 * Fetch A Tax
 */
$tax = $connector->send(new FetchATaxRequest(
    id: 1
))->dto();
php
/**
 * Delete A Tax
 */
$tax = $connector->send(new DeleteATaxRequest(
    id: 1
));
php  
/**
 * Fetch A Title
 */
$title = $connector->send(new FetchATitleRequest(
    id: 1
))->dto();
php
/**
 * Search Titles
 */
$titles = $connector->send(new SearchTitlesRequest(
    searchField: 'Name',
    searchTerm: 'Something'
))->dto();
php
/**
 * Delete Title
 */
$title = $connector->send(new DeleteATitleRequest(
    id: 1
));
php
/**
 * Fetch A VAT Period
 */
$vatPeriod = $connector->send(new FetchAVatPeriodRequest(
    id: 1
))->dto();