PHP code example of digitaldev-lx / laravel-moloni

1. Go to this page and download the library: Download digitaldev-lx/laravel-moloni 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/ */

    

digitaldev-lx / laravel-moloni example snippets


use DigitaldevLx\LaravelMoloni\Facades\Moloni;

$tenant = Moloni::forAccount("tenant-{$tenantId}", [
    'username' => $tenant->moloni_username,
    'password' => $tenant->moloni_password,
    // optional overrides: client_id, client_secret, base_url
]);

$customers = $tenant->customers()->getAll($tenant->moloni_company_id);

use DigitaldevLx\LaravelMoloni\TokenStores\ArrayTokenStore;

$moloni = Moloni::forAccount('tenant-1', ['username' => '...', 'password' => '...'], new ArrayTokenStore);

// config/moloni.php
'retry' => [
    'enabled' => true,        // MOLONI_RETRY_ENABLED
    'max_attempts' => 3,      // total attempts, including the first
    'base_delay_ms' => 500,   // 500, 1000, 2000, ...
    'max_delay_ms' => 10000,
    'statuses' => [429, 500, 502, 503, 504],
],

use DigitaldevLx\LaravelMoloni\Facades\Moloni;

// List all companies
$companies = Moloni::companies()->getAll();

$companyId = config('moloni.company_id');

// List all customers
$customers = Moloni::customers()->getAll($companyId);

// Find a customer by VAT number
$customer = Moloni::customers()->getByVat($companyId, '123456789');

// Create a customer using a DTO
use DigitaldevLx\LaravelMoloni\DataTransferObjects\Customer as CustomerDto;

$dto = new CustomerDto(
    vat: '123456789',
    number: 'C001',
    name: 'John Doe',
    email: '[email protected]',
    address: '123 Main Street',
    city: 'Lisbon',
    zipCode: '1000-001',
    countryId: 1,
);

$customer = Moloni::customers()->insert($companyId, $dto);

// Create a customer using an array
$customer = Moloni::customers()->insert($companyId, [
    'vat' => '123456789',
    'number' => 'C001',
    'name' => 'John Doe',
    'email' => '[email protected]',
]);

// List all products
$products = Moloni::products()->getAll($companyId);

// Find a product by reference
$product = Moloni::products()->getByReference($companyId, 'PROD-001');

// Create a product using a DTO
use DigitaldevLx\LaravelMoloni\DataTransferObjects\Product as ProductDto;
use DigitaldevLx\LaravelMoloni\Enums\ProductType;

$dto = new ProductDto(
    name: 'Widget',
    reference: 'PROD-001',
    type: ProductType::Product,
    categoryId: 1,
    unitId: 1,
    price: 29.99,
);

$product = Moloni::products()->insert($companyId, $dto);

use DigitaldevLx\LaravelMoloni\DataTransferObjects\Document as DocumentDto;
use DigitaldevLx\LaravelMoloni\DataTransferObjects\DocumentProduct;
use DigitaldevLx\LaravelMoloni\DataTransferObjects\Payment;

// Create an invoice
$dto = new DocumentDto(
    documentSetId: 1,
    customerId: 1,
    date: '2026-03-31',
    expirationDate: '2026-04-30',
    products: [
        new DocumentProduct(
            productId: 1,
            qty: 2,
            price: 29.99,
        ),
    ],
    payments: [
        new Payment(
            paymentMethodId: 1,
            value: 59.98,
            date: '2026-03-31',
        ),
    ],
);

$invoice = Moloni::invoices()->insert($companyId, $dto);

// Get PDF link for a document
$pdfLink = Moloni::invoices()->getPdfLink($companyId, $invoiceId);

$taxes = Moloni::taxes()->getAll($companyId);
$paymentMethods = Moloni::paymentMethods()->getAll($companyId);
$documentSets = Moloni::documentSets()->getAll($companyId);
$warehouses = Moloni::warehouses()->getAll($companyId);
$units = Moloni::measurementUnits()->getAll($companyId);
$maturityDates = Moloni::maturityDates()->getAll($companyId);
$deliveryMethods = Moloni::deliveryMethods()->getAll($companyId);
$bankAccounts = Moloni::bankAccounts()->getAll($companyId);

// Global resources (no company_id needed)
$countries = Moloni::countries()->getAll();
$currencies = Moloni::currencies()->getAll();
$languages = Moloni::languages()->getAll();
$exemptions = Moloni::taxExemptions()->getAll();
$fiscalZones = Moloni::fiscalZones()->getAll($countryId);

use DigitaldevLx\LaravelMoloni\Events\DocumentCreated;

class SendInvoiceNotification
{
    public function handle(DocumentCreated $event): void
    {
        // $event->data contains the API response
        // $event->documentType contains the document type
    }
}

use DigitaldevLx\LaravelMoloni\Events\DocumentCreated;
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(
        DocumentCreated::class,
        SendInvoiceNotification::class,
    );
}

use DigitaldevLx\LaravelMoloni\Events\DocumentCreated;
use Illuminate\Support\Facades\Event;

Event::listen(function (DocumentCreated $event) {
    // ...
});

use DigitaldevLx\LaravelMoloni\Exceptions\AuthenticationException;
use DigitaldevLx\LaravelMoloni\Enums\AuthError;

try {
    $customers = Moloni::customers()->getAll($companyId);
} catch (AuthenticationException $e) {
    $e->authError;        // AuthError enum (e.g. AuthError::InvalidGrant)
    $e->errorDescription; // Moloni's error description string
    $e->getMessage();     // Full formatted message
}

use DigitaldevLx\LaravelMoloni\Exceptions\ValidationException;
use DigitaldevLx\LaravelMoloni\Enums\ValidationErrorCode;

try {
    $customer = Moloni::customers()->insert($companyId, $data);
} catch (ValidationException $e) {
    $e->errors;             // Array of ['code' => int, 'field' => string, 'description' => string]
    $e->getFieldErrors();   // ['field_name' => 'description', ...]
    $e->hasFieldError('vat'); // true/false
}

use DigitaldevLx\LaravelMoloni\Exceptions\MoloniException;
use DigitaldevLx\LaravelMoloni\Exceptions\AuthenticationException;
use DigitaldevLx\LaravelMoloni\Exceptions\ValidationException;
use DigitaldevLx\LaravelMoloni\Exceptions\RateLimitException;

try {
    $invoice = Moloni::invoices()->insert($companyId, $data);
} catch (AuthenticationException $e) {
    // Handle auth errors (invalid credentials, expired tokens)
} catch (ValidationException $e) {
    // Handle validation errors (invalid data)
} catch (RateLimitException $e) {
    // Handle rate limiting (retry later)
} catch (MoloniException $e) {
    // Handle all other API errors
}

use DigitaldevLx\LaravelMoloni\Concerns\HasMoloniDocuments;

class Order extends Model
{
    use HasMoloniDocuments;
}

// Then use it
$order->moloniDocuments;

use Illuminate\Support\Facades\Http;

Http::fake([
    'api.moloni.pt/sandbox/grant/*' => Http::response([
        'access_token' => 'fake-token',
        'refresh_token' => 'fake-refresh',
        'expires_in' => 3600,
    ]),
    'api.moloni.pt/sandbox/customers/getAll/*' => Http::response([
        ['customer_id' => 1, 'name' => 'Test Customer'],
    ]),
]);

$customers = Moloni::customers()->getAll($companyId);
bash
php artisan vendor:publish --tag=moloni-config
bash
php artisan migrate
bash
php artisan tinker --execute="\DigitaldevLx\LaravelMoloni\Models\MoloniToken::truncate();"