janes.hu logo

Laravel Manager Pattern for Multiple Drivers

By Janes Zsolt | 2026-04-21

Laravel Manager Pattern for Multiple Drivers

Laravel’s Manager pattern is a clean and scalable solution for handling multiple providers behind a unified API. This article demonstrates how to build a configurable invoice driver system in Laravel using Billingo and PDF drivers. The implementation includes configuration files, interfaces, drivers, a manager class, service provider registration, and facade usage. The pattern provides easy extensibility, centralized configuration, and a consistent API across multiple providers.

In Hungary, there are many invoice providers such as Billingo or Számlázz.hu. In many projects, clients want the flexibility to choose which invoice provider they use.

To make switching providers easy and configurable, Laravel’s Manager pattern is an excellent solution. Laravel internally uses this pattern for cache, mail, queue, and filesystem drivers.

In this article, I will show you how to build a simple invoice driver system using Laravel Managers.

Create the configuration file

Create a new config file called config/invoice.php.

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default invoice driver
    |--------------------------------------------------------------------------
    |
    | Supported drivers: pdf, billingo
    |
    */

    'driver' => env('INVOICE_DRIVER', 'pdf'),
];

Now you can change the default driver directly from your .env file.

INVOICE_DRIVER=pdf

or

INVOICE_DRIVER=billingo

Create the Driver Interface

Create the interface at app/Drivers/InvoiceInterface.php.

<?php

namespace App\Drivers;

interface InvoiceInterface
{
    public function create(array $data): mixed;
}

The interface ensures that every driver follows the same API.

Create the Billingo Driver

Create app/Drivers/Billingo.php.

<?php

namespace App\Drivers;

class Billingo implements InvoiceInterface
{
    public function create(array $data): mixed
    {
        // Create invoice using Billingo API

        return true;
    }
}

Create the PDF Driver

Create app/Drivers/PDF.php.

<?php

namespace App\Drivers;

class PDF implements InvoiceInterface
{
    public function create(array $data): mixed
    {
        // Generate PDF invoice

        return true;
    }
}

Create the Invoice Manager

Create app/Managers/InvoiceManager.php.

<?php

namespace App\Managers;

use App\Drivers\Billingo;
use App\Drivers\PDF;
use Illuminate\Support\Manager;

class InvoiceManager extends Manager
{
    public function createBillingoDriver(): Billingo
    {
        return $this->container->make(Billingo::class);
    }

    public function createPdfDriver(): PDF
    {
        return $this->container->make(PDF::class);
    }

    public function getDefaultDriver(): string
    {
        return $this->config->get('invoice.driver');
    }
}

The Manager class automatically resolves drivers through the driver() method.

For example:

app('invoice')->driver('billingo');

internally calls:

createBillingoDriver()

Register the Manager

Register the manager inside app/Providers/AppServiceProvider.php.

<?php

namespace App\Providers;

use App\Managers\InvoiceManager;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton('invoice', function ($app) {
            return new InvoiceManager($app);
        });
    }
}

Create the Facade

Create app/Facades/Invoice.php.

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
 * @method static mixed create(array $data)
 * @method static mixed driver(string|null $driver = null)
 */
class Invoice extends Facade
{
    protected static function getFacadeAccessor(): string
    {
        return 'invoice';
    }
}

Usage

Now you can use the invoice service anywhere in your application.

use App\Facades\Invoice;

Invoice::create($data);

Laravel will automatically use the default driver configured in the config file.

Switch Driver Dynamically

You can also switch drivers dynamically at runtime.

Invoice::driver('billingo')->create($data);

or

Invoice::driver('pdf')->create($data);

Why use the Manager pattern?

The Manager pattern provides several advantages:

  • Easy driver switching

  • Centralized configuration

  • Clean abstraction layer

  • Extensible architecture

  • Better testability

  • Consistent API across providers

Adding a new invoice provider becomes very simple. Just create a new driver class and register it inside the manager.

Conclusion

Laravel’s Manager pattern is a clean and scalable solution for handling multiple providers behind a unified API.

It is especially useful for:

  • Invoice providers

  • Payment gateways

  • SMS providers

  • Cloud storage providers

  • Email services

If your application needs interchangeable providers, Laravel Managers are an excellent choice.

Additional Resources

If you enjoyed this article, please share it so others can find it too

Janes Zsolt

Janes Zsolt

I am a Hungarian Laravel developer with over 10 years of experience, primarily focused on developing modern web applications. On a daily basis, I work with Laravel, Vue.js, various cloud and DevOps tools, as well as AI-powered solutions (OpenAI API). I have contributed to the development of everything from simple websites to complex systems, including e-commerce platforms and admin interfaces. Currently, I am continuously expanding my skills in AI, Python, and vector databases.

Keep Reading...

Discover more interesting articles