Skip to main content
PHP FacturaE supports both line-level discounts and invoice-level general discounts and charges. This guide covers invoice-level adjustments that apply to the total invoice amount.

General Discounts

Apply discounts at the invoice level using the generalDiscount() method:
use PhpFacturae\Invoice;

$invoice = Invoice::create('FAC-001')
    ->seller($seller)
    ->buyer($buyer)
    ->line('Product A', price: 100.00, vat: 21)
    ->line('Product B', price: 200.00, vat: 21)
    ->generalDiscount('VIP customer discount', amount: 50.00)
    ->toXml();
General discounts are applied to the gross invoice total before tax calculations, reducing the taxable base.

General Charges

Add additional charges at the invoice level using the generalCharge() method:
$invoice = Invoice::create('FAC-002')
    ->seller($seller)
    ->buyer($buyer)
    ->line('Service', price: 500.00, vat: 21)
    ->generalCharge('Shipping costs', amount: 15.00)
    ->toXml();
Charges increase the taxable base, so taxes are calculated on the total including charges.

Fixed Amount vs Percentage Rate

You can specify discounts and charges either as a fixed amount or as a percentage rate.

Fixed Amount

// Discount of €50
->generalDiscount('Early payment discount', amount: 50.00)

// Charge of €15
->generalCharge('Handling fee', amount: 15.00)

Percentage Rate

// 10% discount on gross total
->generalDiscount('Volume discount', rate: 10)

// 5% surcharge
->generalCharge('Rush order fee', rate: 5)
1
How Rates are Calculated
2
  • Calculate the gross total of all invoice lines
  • Apply the rate percentage to the gross total
  • The calculated amount is used as the discount/charge
  • Adjust the taxable base accordingly
  • Calculate taxes on the adjusted base
  • Multiple Discounts and Charges

    You can apply multiple discounts and charges to the same invoice:
    $invoice = Invoice::create('FAC-003')
        ->seller($seller)
        ->buyer($buyer)
        ->line('Consulting', price: 1000.00, vat: 21)
        ->line('Materials', price: 300.00, vat: 21)
        // Apply multiple discounts
        ->generalDiscount('Early payment', rate: 5)
        ->generalDiscount('Loyalty program', amount: 25.00)
        // Add charges
        ->generalCharge('Shipping', amount: 20.00)
        ->generalCharge('Insurance', rate: 2)
        ->toXml();
    
    When using both rate and amount parameters together, the amount parameter takes precedence. Only specify one per discount/charge.

    How Discounts Affect Total Calculation

    Here’s how general discounts and charges are applied:
    // Example calculation
    $invoice = Invoice::create('FAC-004')
        ->line('Item 1', price: 100.00, vat: 21)  // €100
        ->line('Item 2', price: 200.00, vat: 21)  // €200
        ->generalDiscount('Discount', amount: 30.00)
        ->generalCharge('Shipping', amount: 10.00);
    
    // Gross total: €300.00
    // After discount: €300.00 - €30.00 = €270.00
    // After charge: €270.00 + €10.00 = €280.00
    // Taxable base: €280.00
    // VAT (21%): €58.80
    // Invoice total: €338.80
    

    Complete Example

    use PhpFacturae\Invoice;
    use PhpFacturae\Party;
    
    $seller = Party::company('B12345678', 'Mi Empresa S.L.')
        ->address('Calle Mayor 1', '28001', 'Madrid', 'Madrid');
    
    $buyer = Party::company('A87654321', 'Cliente Premium S.A.')
        ->address('Gran Via 10', '28013', 'Madrid', 'Madrid');
    
    $invoice = Invoice::create('FAC-2024-0015')
        ->series('A')
        ->date('2024-03-15')
        ->seller($seller)
        ->buyer($buyer)
        // Invoice lines
        ->line('Web development', price: 2000.00, vat: 21)
        ->line('Hosting (annual)', price: 120.00, vat: 21)
        ->line('SSL certificate', price: 50.00, vat: 21)
        // Apply 10% early payment discount
        ->generalDiscount('10% early payment discount', rate: 10)
        // Add shipping charge
        ->generalCharge('Express delivery', amount: 25.00)
        // Payment terms
        ->transferPayment(
            iban: 'ES91 2100 0418 4502 0005 1332',
            dueDate: '2024-04-15'
        )
        ->toXml();
    
    // Calculation breakdown:
    // Lines total: €2,170.00
    // 10% discount: -€217.00
    // Shipping: +€25.00
    // Taxable base: €1,978.00
    // VAT 21%: €415.38
    // Total: €2,393.38
    

    Method Reference

    Both methods are defined in Invoice.php:

    generalDiscount()

    public function generalDiscount(
        string $reason,
        ?float $rate = null,
        ?float $amount = null
    ): self
    
    Defined at Invoice.php:358

    generalCharge()

    public function generalCharge(
        string $reason,
        ?float $rate = null,
        ?float $amount = null
    ): self
    
    Defined at Invoice.php:374

    Parameters

    • reason (required): Description of the discount/charge
    • rate: Percentage rate to apply (e.g., 10 for 10%)
    • amount: Fixed amount in invoice currency
    Provide descriptive reasons for discounts and charges. These appear on the invoice and help explain the adjustments to your customers and tax authorities.

    Line-Level Discounts

    For discounts on individual lines, use the discount parameter in the line() method:
    ->line(
        description: 'Product with line discount',
        price: 100.00,
        vat: 21,
        discount: 10  // 10% discount on this line only
    )
    
    See Invoice Lines for more details on line-level discounts.

    Common Scenarios

    Early Payment Discount

    ->generalDiscount('Early payment discount - 5%', rate: 5)
    

    Volume-Based Discount

    ->generalDiscount('Volume discount - orders over €1000', amount: 100.00)
    

    Shipping and Handling

    ->generalCharge('Shipping and handling', amount: 15.50)
    

    Insurance Fee

    ->generalCharge('Insurance fee', rate: 2)
    

    Combined Discounts

    ->generalDiscount('Seasonal discount', rate: 10)
    ->generalDiscount('Loyalty points redemption', amount: 50.00)
    

    Best Practices

    1
    Be Explicit
    2
    Use clear, descriptive reasons that explain why the discount or charge was applied.
    3
    Use Rates for Proportional Adjustments
    4
    When the adjustment should scale with the invoice amount, use rates instead of fixed amounts.
    5
    Document Special Arrangements
    6
    For negotiated discounts, reference the agreement in the description.
    7
    Validate Totals
    8
    Always verify that the final total matches your expectations, especially with multiple adjustments.

    Storage Format

    Internally, discounts and charges are stored as arrays in the Invoice class:
    // From Invoice.php:52-55
    private array $generalDiscounts = [];
    private array $generalCharges = [];
    
    // Each entry has the structure:
    [
        'reason' => 'Discount description',
        'rate' => 10.0,  // optional
        'amount' => 50.0
    ]
    

    Build docs developers (and LLMs) love