Troubleshooting
Start with the log
Lexies → Log holds every call made and every callback served, with status, timing and — on Pro — the bodies. A bookkeeping integration that silently stops working looks exactly like one with nothing to do, so "why is there no invoice for order 1042" should be a question with an answer.
Filter by order, or search the endpoint.
"The invoice would come to X but the order was charged Y"
The reconciliation guard refused to send a voucher that disagrees with the order. Usual causes, in order of likelihood:
- A discount applied after tax. Commerce's adjusters normally run discount → shipping → tax. If a custom adjuster or a third-party plugin discounts after tax has been calculated, the result cannot be expressed as an invoice at all, because Lexware recomputes tax from the unit prices.
- Order-level discount mode. Switch Order-level discounts to Spread across line items if it is set to Send as a total discount and the order has more than one tax rate.
- A rounding rule of your own. Anything that adjusts the order total without a matching adjustment will show up here as a gap.
The document records both figures. The difference is usually recognisable as one of the above.
"carries N different tax rates. Lexware allows one rate per line item"
Two tax adjustments with different rates are attached to the same Commerce line item. That is legitimate in Commerce and not representable in Lexware, which models one rate per line.
Split the product into separate line items, or fix the tax rule that is matching twice.
"Lexware Office only issues vouchers in EUR"
There is no other currency in the Lexware API and nothing Lexies could convert with that would be defensible on a tax return. Orders in other currencies are refused.
"Lexware requires an invoice with tax type X to reference a contact"
Intra-community and third-country invoices need a real Lexware contact. Turn on Sync contacts (Pro), or pin a tax type if the automatic decision is wrong for your business.
A document says "Needs checking"
Lexware did not answer, so it is not known whether a voucher was created. Lexies will not send it again on its own — see Usage.
Press Check with Lexware on the document, or run:
php craft lexies/sync/reconcile
If the search cannot decide — an unusual total, a contact that changed — look in Lexware directly. Finding a voucher there means the create worked; delete the draft or void the invoice if it is a duplicate, then reconcile.
No invoices are being created at all
Work down this list:
- Is there an API key? The order-complete handler does nothing without one, silently, by design — a half-configured install should not fill the queue with failures.
- Is the queue running? Lexies pushes a job. If Craft's queue is not being run, nothing happens. Check Utilities → Queue Manager.
- Is the trigger right?
Only when I askmeans exactly that. The status trigger fires the first time an order reaches one of the chosen statuses, which is not the same as completion. - Only invoice paid orders — if the order is not paid in Commerce, it is skipped.
- Stores — an empty store selection means all stores; a non-empty one means only those.
php craft lexies/sync/order <id> invoices one order regardless of the trigger rules and reports
exactly what happened.
Webhooks never arrive
- Is the callback URL reachable? Lexware sends a
HEADrequest before accepting the subscription and refuses if the certificate does not validate. The URL is a site URL, not a control-panel one, so an IP allow-list on/admindoes not affect it. - Was the API key rotated? Revoking a key deletes every subscription made with it. Run
php craft lexies/webhooks/sync. - Check the log. A callback with a bad signature is recorded as a rejected webhook, so you can tell "nothing arrived" from "something arrived and was refused".
- Is anything unhandled?
php craft lexies/webhooks/replayworks through callbacks that were stored but never acted on.
Failing all that, poll instead — php craft lexies/payments/poll on a schedule needs no inbound
connectivity at all.
An invoice was paid in Lexware but the order still says unpaid
Record payments in Commerce is off by default, and does nothing without a Payment gateway chosen. Both are needed. The order history will carry a note either way.
Note that Lexies never pays more than the outstanding balance and never touches an order Commerce already considers paid.
Rate limiting
Lexware allows two requests per second across your whole API key, counting every integration you have — not just this one. If you see 429s in the log, raise Minimum request interval above 550 ms. Lexies retries a rate-limited read, but backing off is cheaper than being blocked.
Duplicate contacts in Lexware
Lexies matches an existing contact by exact email before creating one. Two contacts for the same person usually means the two orders had different email addresses, or one contact was created by hand with the address in a field Lexware's filter does not search.
Merge them in Lexware, then let the next order re-link.
Nothing here matches
Turn on payload logging (Pro), reproduce, and read the request body on the failing call. Lexware's
validation errors name the field: missing_entity (address.city) is a great deal more useful than
"406", and it is in the log verbatim.