Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Lexoffice Bundle Laravel Package

deter-consulting/lexoffice-bundle

Laravel bundle for integrating with the lexoffice API. Provides a structured foundation to connect your app to lexoffice services, helping you authenticate, make API requests, and build features around invoices, contacts, and accounting data.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require deter-consulting/lexoffice-bundle
    

    Register the bundle in config/bundles.php:

    return [
        DeterConsulting\LexOfficeBundle\LexOfficeBundle::class => ['all' => true],
    ];
    
  2. Publish Configuration

    php artisan vendor:publish --provider="DeterConsulting\LexOfficeBundle\LexOfficeBundle" --tag="config"
    

    Update config/lexoffice.php with your LexOffice API credentials:

    return [
        'client_id'     => env('LEXOFFICE_CLIENT_ID'),
        'client_secret' => env('LEXOFFICE_CLIENT_SECRET'),
        'account_id'    => env('LEXOFFICE_ACCOUNT_ID'),
        'base_uri'      => env('LEXOFFICE_BASE_URI', 'https://api.lexoffice.com'),
    ];
    
  3. First Use Case: Fetch a Customer Inject the LexOfficeClient service into a controller or service:

    use DeterConsulting\LexOfficeBundle\Client\LexOfficeClient;
    
    public function __construct(private LexOfficeClient $lexOffice)
    {
    }
    
    public function showCustomer($id)
    {
        $customer = $this->lexOffice->customers()->find($id);
        return response()->json($customer);
    }
    

Implementation Patterns

Core Workflows

  1. Resource Management Use the fluent API for common operations:

    // Create a customer
    $customer = $this->lexOffice->customers()->create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'address' => '123 Main St',
    ]);
    
    // Fetch all invoices for a customer
    $invoices = $this->lexOffice->invoices()
        ->where('customer_id', $customer->id)
        ->all();
    
    // Update an invoice status
    $invoice = $this->lexOffice->invoices()->find($invoiceId);
    $invoice->update(['status' => 'sent']);
    
  2. Event-Driven Integrations Listen to LexOffice webhook events using Laravel's Messenger:

    // config/lexoffice.php
    'webhooks' => [
        'invoice_created' => 'https://your-app.com/lexoffice/webhooks/invoice',
        'payment_received' => 'https://your-app.com/lexoffice/webhooks/payment',
    ],
    
    // routes/web.php
    Route::post('/lexoffice/webhooks/invoice', [LexOfficeWebhookController::class, 'handleInvoice']);
    
  3. Data Synchronization Sync local models with LexOffice resources:

    public function syncCustomers()
    {
        $lexOfficeCustomers = $this->lexOffice->customers()->all();
        foreach ($lexOfficeCustomers as $customer) {
            Customer::updateOrCreate(
                ['lexoffice_id' => $customer->id],
                $customer->toArray()
            );
        }
    }
    
  4. Batch Operations Process large datasets efficiently:

    $this->lexOffice->invoices()->paginate(100)->each(function ($invoice) {
        // Process each invoice (e.g., update local records)
    });
    

Laravel-Specific Patterns

  1. Service Provider Extensions Override or extend bundle services in your AppServiceProvider:

    public function register()
    {
        $this->app->extend('lexoffice.client', function ($client) {
            $client->setCustomHeader('X-Custom-Header', 'value');
            return $client;
        });
    }
    
  2. Command Integration Create custom Artisan commands for LexOffice operations:

    use Illuminate\Console\Command;
    use DeterConsulting\LexOfficeBundle\Client\LexOfficeClient;
    
    class SyncInvoicesCommand extends Command
    {
        protected $signature = 'lexoffice:sync-invoices';
        protected $description = 'Sync invoices from LexOffice';
    
        public function handle(LexOfficeClient $lexOffice)
        {
            $invoices = $lexOffice->invoices()->all();
            // Process invoices...
        }
    }
    
  3. API Resource Transformation Transform LexOffice API responses into Eloquent resources:

    use Illuminate\Http\Resources\Json\JsonResource;
    
    class LexOfficeInvoiceResource extends JsonResource
    {
        public function toArray($request)
        {
            return [
                'id' => $this->id,
                'number' => $this->number,
                'amount' => $this->amount,
                'due_date' => $this->due_date,
                'customer' => new LexOfficeCustomerResource($this->customer),
            ];
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Authentication Issues

    • Problem: OAuth2 token expiration or invalid credentials.
    • Solution: Implement token refresh logic in a middleware or service:
      $client = $this->app->make(LexOfficeClient::class);
      if (!$client->isAuthenticated()) {
          $client->refreshToken();
      }
      
  2. Rate Limiting

    • Problem: LexOffice API may throttle requests.
    • Solution: Use Laravel Queues for batch operations:
      Invoice::all()->each(function ($invoice) {
          SyncInvoiceJob::dispatch($invoice);
      });
      
  3. Data Mismatches

    • Problem: LexOffice and local data models may not align.
    • Solution: Create a mapping layer:
      $lexOfficeData = $this->lexOffice->invoices()->find($id);
      $localData = (new InvoiceMapper())->toLocal($lexOfficeData);
      
  4. Webhook Delays

    • Problem: Webhook processing may be delayed.
    • Solution: Implement retry logic with Laravel Horizon:
      public function handleWebhook(Request $request)
      {
          try {
              // Process webhook
          } catch (\Exception $e) {
              WebhookFailedJob::dispatch($request->all());
          }
      }
      

Debugging Tips

  1. Enable API Logging Configure the LexOfficeClient to log requests/responses:

    $client = $this->app->make(LexOfficeClient::class);
    $client->setDebug(true); // Enable logging
    
  2. Inspect Raw Responses Use Laravel's tap to debug API responses:

    $invoice = $this->lexOffice->invoices()->find($id)->tap(function ($invoice) {
        \Log::debug('Raw response:', $invoice->rawResponse);
    });
    
  3. Handle Undocumented Fields LexOffice API may return unexpected fields. Use a flexible approach:

    $data = $this->lexOffice->invoices()->find($id)->toArray();
    $localData = array_intersect_key($data, array_flip(['id', 'number', 'amount']));
    

Configuration Quirks

  1. Base URI Overrides Override the default LexOffice API URI in config:

    'base_uri' => env('LEXOFFICE_BASE_URI', 'https://api.lexoffice.com'),
    
  2. Custom Headers Add custom headers to all requests:

    $client = $this->app->make(LexOfficeClient::class);
    $client->setDefaultHeaders([
        'X-Custom-Header' => 'value',
        'Authorization' => 'Bearer ' . $this->getToken(),
    ]);
    
  3. Timeout Settings Adjust request timeouts:

    $client = $this->app->make(LexOfficeClient::class);
    $client->setTimeout(30); // 30 seconds
    

Extension Points

  1. Custom Resources Extend the bundle's resource classes:

    namespace App\LexOffice;
    
    use DeterConsulting\LexOfficeBundle\Resources\Invoice;
    
    class CustomInvoice extends Invoice
    {
        public function getCustomField()
        {
            return $this->custom_field ?? null;
        }
    }
    
  2. Event Listeners Listen to LexOffice events:

    use DeterConsulting\LexOfficeBundle\Events\InvoiceCreated;
    
    event(new InvoiceCreated($invoice));
    
  3. API Client Extensions Extend the LexOfficeClient for custom endpoints:

    $client->extend('custom', function () {
        return new CustomLexOfficeClient($this->httpClient);
    });
    

Performance Optimizations

  1. Caching Responses Cache frequent API calls:

    $customer = Cache::remember("lexoffice.customer.{$id}", now()->addHours(1), function () use ($id) {
        return $this->lexOffice->customers()->find($id);
    });
    
  2. Batch Processing Use chunking for large datasets:

    $this->lexOffice
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views