Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Szamlazzhu Laravel Package

zoparga/laravel-szamlazzhu

Laravel package for integrating Szamlazz.hu, the Hungarian online invoicing service. Create and manage invoices, configure seller and buyer data, and issue invoices from your Laravel app through a simple API wrapper.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require zoparga/laravel-szamlazzhu. The service provider is auto-discovered; Szamlazz is registered as a facade.
  • Publish the config first: php artisan vendor:publish --tag=szamlazzhu-config (check the README for the exact tag — the package ships a single config/szamlazzhu.php). Most keys map to env vars, so set SZAMLAZZHU_AGENT_KEY and the invoice/receipt agent keys in .env rather than editing the file.
  • Szamlazz.hu issues separate agent keys for invoice (számla) and receipt (nyugta) agents, and separate keys for the live system vs. the test/sandbox agent. Create a test agent in the Szamlazz.hu admin panel before writing any code — every invoice you generate with the live key is a real, legally-issued document.
  • Where to look first: config/szamlazzhu.php (to see which credential keys exist), then the package README for the facade method signatures, then the Szamlazz.hu XML API documentation, since the package is a thin transport over that XML schema. The vendor source under vendor/zoparga/laravel-szamlazzhu/src is small and readable when the README is ambiguous.
  • First use case: issue one invoice for a test order and save the PDF. Typical shape:
use Szamlazz;

$invoice = Szamlazz::createInvoice([...]);   // header + line items
$pdf     = Szamlazz::getPdf($invoice->getInvoiceNumber());

Storage::disk('invoices')->put("invoices/{$invoice->getInvoiceNumber()}.pdf", $pdf);

Confirm you can see the invoice in the Szamlazz.hu web UI before wiring it into a checkout flow. That end-to-end check is the fastest way to validate your agent key, tax number, and payload structure in one go.

Implementation Patterns

Wrap the facade in a domain action, never call it from a controller. Create a single App\Actions\IssueInvoice (or App\Services\Billing\SzamlazzBiller) that takes your Order model, builds the XML payload, calls the facade, and returns a result DTO. You want exactly one place to change when Szamlazz.hu's schema or the package's array keys shift, and exactly one place to add logging.

Map your domain to the payload in a dedicated builder. Keep a InvoicePayloadBuilder that turns Order + OrderItem[] into the package's array/XML structure: net unit price, quantity, VAT rate code, currency, payment method, and the buyer's tax number. Isolating this makes it unit-testable without any HTTP at all, which is where most of your test coverage should live.

Treat issuance as two steps. Creating the invoice and fetching the PDF are separate round trips. Persist the invoice number on your orders table in the same request that issues, then fetch and store the PDF — either immediately or in a follow-up job. If the PDF fetch fails you have a legitimately issued invoice referenced by number and can re-fetch later; if you treat them as one atomic step you'll be tempted to retry the creation call and issue a duplicate.

// after createInvoice()
$order->update([
    'invoice_number'     => $invoice->getInvoiceNumber(),
    'invoice_issued_at'  => now(),
]);
FetchInvoicePdf::dispatch($order)->delay(now()->addSeconds(10));

Queue issuance, but guard against duplicates. Invoice creation belongs in a job (network timeouts, Szamlazz.hu outages), with $tries, exponential backoff, and a ShouldBeUnique or a DB-level invoice_number IS NULL guard so a retried job can't issue a second invoice. Never issue inside a DB transaction that could roll back after the call succeeds — you'll end up with an orphan invoice and a retried order.

Lean on the 1.8 error messages. This release fills in previously unmapped Szamlazz.hu API error strings, so error handling can now branch on message content rather than a generic failure. Wrap the facade calls in a try/catch that converts package exceptions into your own InvoiceFailedException carrying the raw request/response, then either surface a safe message to the customer or escalate to an operator. The messages are Hungarian and API-specific, so log them verbatim and translate only for user-facing copy.

Cancellations have their own flow. A storno/credit note is not "delete the invoice." It references the original invoice number explicitly. Model it as a separate action that stores both the original and the reversing document numbers on the order, and never allow a storno more than once per invoice.

Multi-tenant setups need runtime config. If each tenant has its own Szamlazz.hu agent, don't rely on a single env key. Resolve credentials per tenant and set them at call time (via a bound config repository or a per-call client), and cache the resolved config per tenant to avoid re-reading on every request. Be careful here: if you mutate global config with config()->set(), you must reset it in queued workers between jobs, or tenant A's agent key leaks into tenant B's invoice.

Testing. Separate the builder tests (pure array comparison, no HTTP) from the transport tests. For transport, use the package's HTTP abstraction — if it goes through the Laravel HTTP client, Http::fake() works; if it uses Guzzle directly, inject a mock handler. Snapshot the generated XML with a fixture so a dependency bump that changes a field name fails loudly in CI rather than silently producing invalid invoices in production.

Gotchas and Tips

  • Laravel 13 support (1.8) is a constraint widening, not a behavioural change. Nothing to migrate; but before upgrading, check the rest of your dependency tree also supports 13. If you're on Laravel 11/12, this release changes nothing for you — upgrade for the error messages alone only if you actually handle failures programmatically.
  • Invoice numbers come from Szamlazz.hu, never from you. Do not pre-generate or predict them. Store the returned number as the source of truth and use it as the filename/identifier for the PDF.
  • Separate live and test agent keys. The most common way to accidentally issue real invoices from staging is a copied .env. Assert on app()->environment() or, better, use a distinct config key set per environment so a staging deploy can't reach the live agent.
  • PDF bytes are not returned on creation. If you assume createInvoice() gives you the document, you'll get an object with metadata but no bytes. Fetch separately.
  • XML schema quirks bite silently. Date format, decimal precision on unit prices, and VAT rate encoding (numeric rates vs. special codes like AAM/EU/tax-exempt) are all easy to get subtly wrong. Szamlazz.hu often accepts the request but issues a document with wrong totals, so validate the returned totals against your expected gross amount and alert on mismatch rather than trusting a 200.
  • config:cache breaks env reads at runtime. Any code reading env('SZAMLAZZHU_...') directly will return null in a cached environment. Read through config() only.
  • Timeouts and retries cause duplicate invoices. The request may succeed on Szamlazz.hu's side while your connection times out. On retry, check by your own order state (or query existing invoices for the order reference) before calling createInvoice() again. Keep the order's external reference/idempotency field stable across retries.
  • 1.8's error messages are an extension point, not a contract. Because they're mapped strings from the upstream API, don't str_contains() on them in business logic for anything important — match on the error code if the package exposes one, and treat message text as logging material.
  • Log the full XML round trip on failure only. It contains customer PII and tax numbers, so gate it behind a debug flag or a dedicated szamlazzhu log channel with limited retention; but do capture it, because upstream support will ask for it.
  • Debugging checklist: (1) is the agent key for the right agent type, (2) does the tax number match the seller profile, (3) does the payload validate against the XML schema, (4) is the invoice visible in the Szamlazz.hu UI even though your app errored — check this before retrying, since it determines whether you have a duplicate problem or a transport problem.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package