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'],
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();