Billing Engine for Laravel
Issue an invoice
Issue an invoice
An invoice is a confirmed quote fixed to a legal number. The flow is: build the quote, confirm it, issue.
Build a quote
QuoteBuilder composes tax (via cboxdk/laravel-tax) and any wallet credit into
the totals. The QuoteContext carries the place of supply, customer type, and the
seller's tax registrations:
use Cbox\Billing\Money\Money;
use Cbox\Billing\Quote\Contracts\QuoteBuilder;
use Cbox\Billing\Quote\ValueObjects\LineInput;
$quote = $quotes->build(
lines: [
new LineInput(description: 'Pro plan — July', quantity: 1, unitAmount: Money::ofMinor(3_000, 'EUR')),
],
context: $quoteContext,
);
If the jurisdiction cannot be resolved, the quote comes back tax-pending — a correct "we don't know the tax yet" state, never a wrong number.
Issue the invoice
use Cbox\Billing\Invoice\Contracts\Invoicer;
$invoice = $invoicer->issue(
quote: $quote, // must be confirmed, not tax-pending
seller: $sellerEntity,
account: $accountId,
at: new DateTimeImmutable(),
);
issue:
- raises
CannotInvoicePendingQuoteif the quote is still tax-pending; - draws the number from the per-seller
InvoiceNumberSequence— monotonic and gapless within each seller of record; - stamps and guards the account's billing currency, so the first finalized invoice locks it.
Credit notes
To reverse invoiced value, issue a CreditNote, which draws from its own per-seller
gapless CreditNoteNumberSequence.