定制 aichadigital/larabill 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

aichadigital/larabill

Composer 安装命令:

composer require aichadigital/larabill

包简介

Professional billing & invoicing package for Laravel with UUID v7, VAT verification, tax calculation for Spain/EU/worldwide, and EU compliance

README 文档

README

Latest Version Total Downloads Tests Code Coverage PHPStan level 8 PHP Version Laravel Version License

ℹ️ Schema upgrade policy — Larabill does not promise in-place schema upgrades between versions. Install fresh and seed with larabill:install (or migrate:fresh) rather than migrating an existing schema across major versions. See ADR-006.

Larabill is a professional, UUID-first billing and invoicing package for Laravel applications. It provides comprehensive VAT verification, tax calculation for Spain/EU/worldwide, and flexible invoice generation with immutability protection. The consumer app's users.id MUST be UUID v7 char(36) — see docs/setup-uuid.md and ADR-006.

🎯 Features

Core Functionality

  • Invoice Management: UUID-based IDs, sequential numbering, proforma invoices, immutable records
  • Tax Calculation: Spanish (IVA), Canary Islands (IGIC), Ceuta/Melilla (IPSI), EU reverse charge, worldwide
  • VAT/Tax Code Verification: Integration with AbstractAPI and APILayer for real-time validation
  • Fiscal Data Management: Company and customer fiscal configurations with temporal validity
  • PDF Generation: Built-in invoice PDF generation using DomPDF
  • EU Compliance: Full support for EU B2B reverse charge and destination VAT rules

Technical Excellence

  • String UUID v7: Ordered UUIDs for invoices and the consumer's users.id (ADR-006)
  • FixedDecimal money: Precise monetary value objects backed by base-100 integers (no floating-point errors)
  • Preflight check: larabill:install aborts cleanly when users.id is not UUID-compatible
  • Temporal Validity: Fiscal configurations with valid_from/valid_until dates
  • Invoice Immutability: Protection against modifications after issuance

📦 Requirements

🚀 Installation

Via Composer

composer require aichadigital/larabill

Publish Configuration

php artisan vendor:publish --tag="larabill-config"

Run the Installer

php artisan larabill:install

This will:

  1. Publish migrations
  2. Run database migrations
  3. Seed default tax categories and rates

Manual Installation (if preferred)

# Publish migrations
php artisan vendor:publish --tag="larabill-migrations"

# Run migrations
php artisan migrate

# Seed default data
php artisan db:seed --class="AichaDigital\Larabill\Database\Seeders\TaxCategoriesSeeder"
php artisan db:seed --class="AichaDigital\Larabill\Database\Seeders\TaxRatesSeeder"

⚙️ Configuration

Environment Variables

Add these to your .env file:

# Tax Code Verification APIs
LARABILL_ABSTRACTAPI_KEY="your_abstractapi_key"
LARABILL_APILAYER_KEY="your_apilayer_key"
LARABILL_VAT_PREFERRED_API="abstractapi"
LARABILL_VAT_CACHE_DAYS=30

# Invoice Numbering
LARABILL_INVOICE_PREFIX="FAC"
LARABILL_PROFORMA_PREFIX="PRO"

# Optional: override the User model class. Must use UUID v7 char(36) ids.
LARABILL_USER_MODEL="App\\Models\\User"

Model Configuration

Configure your user model in config/larabill.php:

'models' => [
    'user' => \App\Models\User::class,
    'invoice' => \AichaDigital\Larabill\Models\Invoice::class,
    'invoice_item' => \AichaDigital\Larabill\Models\InvoiceItem::class,
    // ...
],

🏗️ Architecture

Fiscal Data Model

Larabill separates company and customer fiscal data with temporal validity:

CompanyFiscalConfig    → Issuer fiscal settings (one active at a time)
UserTaxProfile         → Customer fiscal data, temporally versioned per user
Invoice                → Immutable invoice with fiscal snapshot

Key principles:

  • The customer is a User (ADR-003); businesses and sub-accounts are modelled with parent_user_id. The legacy CustomerFiscalData model was removed.
  • Company config changes apply from a specific date forward
  • UserTaxProfile records are temporally versioned (valid_from/valid_until) — never modify past records
  • Invoices capture a fiscal snapshot at creation time
  • Invoices are absolutely immutable once issued

UUID Strategy

Larabill uses string UUID v7 for invoices:

// Model with UUID
use AichaDigital\Larabill\Concerns\HasUuid;

class Invoice extends Model
{
    use HasUuid;
}

// Migration
$table->uuid('id')->primary();

Monetary Values (FixedDecimal)

Money is stored as base-100 integers and exposed as FixedDecimal value objects (from lara100), so there are no floating-point errors. You assign the unscaled base-100 integer; reading the attribute returns a FixedDecimal:

// Assign the base-100 integer (€12.34 → 1234):
$invoice->total_amount = 1234;

// Reading the attribute returns a FixedDecimal value object
// (base-100 backed, scale 2) — not a raw int:
$money = $invoice->total_amount; // FixedDecimal

Invoice and invoice-item money attributes use the FixedDecimalCast (scale 2) from the lara100 package. Note: query-builder access (->value(), ->sum(), ->where()) returns the raw integer, while Eloquent attribute access returns a FixedDecimal.

📖 Usage

Creating an Invoice

use AichaDigital\Larabill\Services\BillingService;

$billingService = app(BillingService::class);

$invoice = $billingService->createInvoice([
    'user_id' => $user->id, // UUID v7 of the customer (a User; ADR-003)
    'items' => [
        [
            'description'  => 'Professional Service',
            'quantity'     => 100,           // base-100: 100 = 1.0 unit
            'unit_price'   => 10000,         // base-100: 10000 = €100.00
            'tax_group_id' => $taxGroup->id, // resolves the applicable VAT/IGIC/IPSI
        ],
    ],
]);

Tax Calculation

use AichaDigital\Larabill\Services\TaxCalculationService;

$taxService = app(TaxCalculationService::class);

// Calculate taxes for a single line. Amounts are base-100 integers. The
// applicable rate (Spanish IVA, Canary IGIC, Ceuta/Melilla IPSI, EU reverse
// charge or destination VAT) is resolved from the TaxGroup and the customer's
// fiscal profile — not passed in directly.
$result = $taxService->calculateForInvoiceItem([
    'quantity'         => 100,           // base-100: 1.0 unit
    'base_price'       => 10000,         // base-100: €100.00
    'tax_group_id'     => $taxGroup->id,
    'billable_user_id' => $user->id,     // optional: drives B2B / destination rules
]);

// $result keys (base-100 integers + breakdown):
//   taxable_amount, total_tax_amount, total_amount, tax_group_id, taxes_applied

VAT Verification

use AichaDigital\Larabill\Services\VatVerificationService;

$vatService = app(VatVerificationService::class);

$result = $vatService->verifyVatNumber('ESB12345678', 'ES');

if ($result['is_valid']) {
    echo "Valid VAT for: " . $result['company_name'];
}

Company Fiscal Configuration

use AichaDigital\Larabill\Models\CompanyFiscalConfig;

// Get current active config
$config = CompanyFiscalConfig::getActive();

// Create new config (the previous active one is auto-closed)
$newConfig = CompanyFiscalConfig::createNew([
    'tax_id'        => 'ESB12345678',
    'business_name' => 'Your Company S.L.',
    'address'       => 'Calle Test 123',
    'city'          => 'Madrid',
    'zip_code'      => '28001',
    'country_code'  => 'ES',
    'is_oss'        => true,
    'valid_from'    => now(),
]);

User Tax Profile

The customer is a User (ADR-003); their fiscal data lives in UserTaxProfile, temporally versioned. This replaces the removed CustomerFiscalData model.

use AichaDigital\Larabill\Models\UserTaxProfile;

// Get the active fiscal profile for a user
$profile = UserTaxProfile::getActiveForOwner($user->id);

// Create a new profile (previous stays as history)
$newProfile = UserTaxProfile::createForOwner($user->id, [
    'fiscal_name'  => 'Client SARL',
    'tax_id'       => 'FR12345678901',
    'country_code' => 'FR',
    'is_company'   => true,
]);

🧪 Testing

# Run all tests
composer test

# Run specific tests
composer test -- --filter=Invoice

# Run with coverage
composer test-coverage

# Static analysis
vendor/bin/phpstan analyse

Current status (v3.1.1): 1021 tests passing on SQLite, plus MySQL 8 integration tests (real column types and unique constraints) and fork-based concurrency tests. The UUID-first contract is demonstrated on MySQL 8.

📚 Documentation

Document Description
ARCHITECTURE.md Core architecture and domain model
setup-uuid.md UUID-first onboarding for the consumer app
ADR-006 UUID-first decision (supersedes the agnostic id contract)
TAX_RATES_MIGRATION_GUIDE.md Tax rates migration guide
CHANGELOG.md Version history and breaking changes

For AI agents working with this package, see .claude/project.md.

🗺️ Roadmap

Shipped

  • ✅ Core invoice management (immutable records, UUID v7, sequential numbering, proforma)
  • ✅ Spanish tax system (IVA, IGIC, IPSI)
  • ✅ EU reverse charge (B2B) and destination VAT
  • ✅ Fiscal data with temporal validity (CompanyFiscalConfig, UserTaxProfile)
  • FixedDecimal money type (base-100, no floating-point errors)
  • ✅ VeriFACTU integration (Spain AEAT) via lara-verifactu
  • ✅ Grouped payments
  • ✅ Legal-retention contract (LegallyRetainable) for GDPR tooling

Under consideration

  • Subscription billing
  • Payment gateway integration (Stripe, PayPal, Redsys)
  • Advanced reporting

See the CHANGELOG for the full release history.

🤝 Contributing

Please see CONTRIBUTING for details.

🔒 Security

Please review our security policy on how to report security vulnerabilities.

📄 License

GNU Affero General Public License v3.0 (AGPL-3.0-or-later). See LICENSE.md for details.

This means:

  • ✅ You can use, modify, and distribute this software
  • ✅ You must share any modifications under the same license
  • ⚠️ If you run this as a network service, you must provide the source code to users
  • ⚠️ You must preserve copyright and attribution notices

👥 Credits

统计信息

  • 总下载量: 106
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 27
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: AGPL-3.0-or-later
  • 更新时间: 2026-01-08

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固