Configuration
All settings live at Settings → Plugins → Lexies. None of them is required, so a fresh install can save the screen before the API key exists.
When to invoice
| Setting | What it does |
|---|---|
| Trigger | When the order is completed (default), When the order reaches a status (Pro), or Only when I ask |
| Statuses | With the status trigger, the handles that raise an invoice — the first time the order reaches any of them |
| Only invoice paid orders | Off by default. Leave it off if the invoice is the request for payment |
| Finalise invoices | Off by default. On, invoices arrive open with a voucher number and cannot be edited or deleted, only voided |
| Stores | Which Commerce stores Lexies invoices for. None selected means all of them |
Invoicing never happens inside the checkout request. The order-complete handler pushes a queue job and returns; a Lexware outage can make an invoice late, but it can never stop a customer paying.
Tax
Tax type is Work it out per order by default. That resolves each order from three real
inputs:
| Situation | Tax type |
|---|---|
| Your organisation is a Kleinunternehmer (§19 UStG) | vatfree |
| Customer in Germany | net or gross, matching how your store enters prices |
| Customer in the EU with a VAT ID | intraCommunitySupply — reverse charge |
| Customer in the EU without a VAT ID, OSS on | net/gross with taxSubType: distanceSales |
| Customer outside the EU | thirdPartyCountryDelivery, or …Service for digital goods |
Whether a country counts as EU comes from Lexware's own countries endpoint, not a list baked into the plugin. It is the same table their voucher validation uses, so it stays correct when a country joins or leaves.
Every decision is recorded with its reasoning on the document. Open any document under
Lexies → Documents to see why it was taxed the way it was — intraCommunitySupply on an
invoice is a claim to the Finanzamt, and you should be able to see what produced it.
You can pin a single tax type instead, if you would rather decide yourself.
The other tax settings
- VAT-free note — printed on zero-rated invoices. Empty uses Lexware's own wording.
- EU distance sales (OSS) — only turn this on if you are registered for One-Stop-Shop and
your Lexware distance sales principle is set to
DESTINATION. The connection test reports that. - I sell electronic services — changes both the distance-sales subtype and the tax type used outside the EU.
- Order-level discounts —
Spread across line items(default) keeps every tax rate exact.Send as a total discountis tidier on the printed invoice but lets Lexware decide how the discount lands on each rate: fine at one rate, and a blocked invoice at two. - Reconciliation tolerance — how far the invoice may sit from the order before Lexies refuses to send it, in cents. Zero is correct. See Usage.
Contacts (Pro)
Sync contacts creates a real Lexware contact per customer and reuses it, rather than printing the address onto each invoice. One customer means one contact and one customer number, held by a unique key: the Craft user id where there is one, the lowercased email where there is not.
Before creating anything, Lexies looks for a contact Lexware already holds under that email and adopts it — a shop that has been invoicing by hand for a year does not want a parallel set of customers. The match is exact, because Lexware's email filter matches substrings.
Registered customers only books guests against Lexware's collective customer instead.
Leaving contacts off means intra-community and third-country orders are blocked, because Lexware will not accept those tax types without a referenced contact.
Payments and refunds (Pro)
| Setting | What it does |
|---|---|
| Listen for Lexware webhooks | Lexware calls this site when a payment or voucher status changes |
| Verify webhook signatures | On. Checks the RSA-SHA512 signature against Lexware's published key |
| Record payments in Commerce | Off. On, a paid invoice adds a Commerce transaction |
| Payment gateway | Which gateway that transaction is attributed to. Without one, nothing is recorded |
| Status when paid | Move the order to this status once Lexware reports it paid |
| Credit note on refund | Raise a Lexware credit note when a refund is captured in Commerce |
Record payments in Commerce is off by default on purpose. It creates money in Commerce's ledger, and a shop that already takes card at checkout would end up with the same sale paid twice. Turn it on when the invoice is how you get paid — bank transfer, on account — not as a matter of course.
Subscribing
Press Subscribe on the settings screen. Lexware sends a HEAD request to your callback URL
first to check the certificate, so the URL has to be publicly reachable over valid HTTPS before it
will accept the subscription.
Revoking a Lexware API key deletes every subscription made with it. After rotating a key, run
php craft lexies/webhooks/syncagain — that is the whole recovery procedure.
If you would rather not expose a public endpoint, leave webhooks off and poll instead:
php craft lexies/payments/poll
The document
| Setting | Notes |
|---|---|
| Language | de (default) or en. Drives Lexware's own default text on the printed document |
| Title | Object template. Lexware caps this at 25 characters |
| Introduction / Remark | Object templates, rendered against the order. 2000 characters each |
| Shipping conditions | Not cosmetic: Lexware uses the shipping date to decide which VAT rates are legal on the voucher |
| Payment term (days) | Empty uses the term configured in Lexware |
| Shipping as a line item | On. Shipping is always its own line in Lexware's model |
| Default unit name | Used when a variant has no unit of its own. Stück by default |
| Include SKU | Adds Art.-Nr. … to the line description |
| Print layout ID | Empty uses your Lexware default layout |
The three text fields are object templates, so they can quote the order:
Bestellung {{ object.reference ?? object.shortNumber }}
Front end (Pro)
Customer invoice downloads serves the Lexware PDF at /lexies/invoice/{order number}. It
authorises exactly the way Commerce's own order-details page does: a logged-in customer must own
the order, and a guest order is proved by its unguessable 32-character order number. Link to it
with craft.lexies.invoiceUrl(order), which returns null when there is nothing to download.
Connection and logging
| Setting | Default | Notes |
|---|---|---|
| Minimum request interval | 550 ms | Lexware allows two requests a second across your whole key |
| Retries | 3 | Reads, and writes Lexware definitively rejected. A create that timed out is never retried |
| Timeout | 35 s | Lexware's own gateway times out at 30 |
| Logging | On | |
| Keep request and response bodies | On (Pro) | They contain customer addresses and order contents |
| Keep logs for | 30 days | Pruned by lexies/log/prune. Zero keeps everything |
The request interval is enforced across the whole install behind a mutex, so several queue workers share one budget rather than each politely staying under the limit and collectively tripling it.
Permissions
- View Lexware documents — the Documents screen and the panel on the order edit screen
- Create, finalise and re-check documents — nested under it; the buttons that act
- View the Lexware connection log