For Craft Commerce 5
Your orders, already in the books
Every completed order becomes a document in Twinfield — with the debtor created, the revenue on the right ledger account, and a VAT code that will survive the return. Nothing else connects Craft Commerce to Twinfield.
One order, two shapes
Twinfield's invoicing module is a separate product, so shops that already send their own invoices need the bookkeeping rather than the document. Twinsies does both, and it is one setting.
<!-- Sales invoice — Twinfield prints, emails and chases it -->
<salesinvoice>
<header>
<office>001</office>
<invoicetype>FACTUUR</invoicetype>
<customer>1000</customer>
<duedate>20260903</duedate>
<status>concept</status>
</header>
<lines>
<line id="1">
<article>WIDGET</article>
<quantity>2</quantity>
<unitspriceexcl>49.50</unitspriceexcl>
<vatcode>VH</vatcode>
<dim1>8000</dim1>
</line>
</lines>
</salesinvoice>
<!-- Journal transaction — the bookkeeping only, on any subscription -->
<transaction destiny="temporary" autobalancevat="true">
<header><office>001</office><code>VRK</code><date>20260820</date></header>
<lines>
<line type="detail" id="1">
<dim1>8000</dim1><debitcredit>credit</debitcredit>
<value>99.00</value><vatcode>VH</vatcode>
</line>
<line type="total" id="2">
<dim1>1300</dim1><dim2>1000</dim2>
<debitcredit>debit</debitcredit><value>119.79</value>
</line>
</lines>
</transaction>
Features
Built for this one pair, rather than a field-mapping screen that knows nothing about Commerce.
Your chart of accounts, in a dropdown
Twinsies reads your real Twinfield administration — offices, articles, ledger accounts, VAT codes, daybooks — and maps against it. Per purchasable, per product type, then a catch-all.
- Shipping and discounts book to their own accounts
- A mistyped ledger account is not rejected by Twinfield — it is created
Customers become debtors first
Twinfield will not book an invoice to a customer that does not exist, and it will not create one for you. The DEB dimension is written before the document, so an order never fails on a missing debtor.
- Four numbering strategies, or one catch-all debtor for guest checkouts
- Existing debtors are left alone unless you ask — a corrected address stays corrected
VAT that survives the return
Matched on the rate Commerce actually charged, not on a tax category that covers three zones — a Dutch shop shipping to Belgium charges 21% under one category and 0% under another.
- Zero-rated exports and reverse-charged intra-EU sales get their own code, not the standard-rate fallback
- Commerce's tax is never sent as its own line: Twinfield derives it, and both would charge it twice
It refuses rather than guess
Every document is reconciled against what the customer actually paid before anything is sent. A cent or two goes to a visible Rounding line; anything larger fails the build and names the adjustment types it could not express.
- Books that reconcile and are wrong cost more than a support ticket
Twinfield knows when it is paid
A bank statement is matched to an invoice in Twinfield, so for transfers and on-account orders Twinfield knows before Craft does. Twinsies reads the open value back and can move the order's status or record a Commerce payment.
- A concept invoice has no open value to read, and Twinsies says so rather than leaving every invoice looking unpaid
Refunds credit themselves
A Commerce refund posts a credit document. A partial refund is apportioned across the order's VAT codes in proportion to their value — the only split that leaves the VAT return right without inventing facts about what came back.
The reason, not just the refusal
Twinfield reports rejections inside a 200 OK, as attributes on whichever tag it disliked — the response body is the only place the reason ever appears. Twinsies keeps every request and response, with access tokens redacted.
In Dutch, properly
The whole control panel interface is translated in Twinfield's own vocabulary rather than literally: administratie, dagboek, debiteur, grootboekrekening, afletteren, creditfactuur.
- No ext-soap required — the envelopes are built over the HTTP client Craft already ships
Frequently Asked Questions
The questions worth answering before you install it.
Only for sales invoice mode, where Twinfield produces a document it can print and send. Journal transaction mode posts the bookkeeping only and works on every Twinfield subscription — which is what you want if you already send invoices from Craft.
No. Twinfield's web services are SOAP, but there are two operations worth calling and both take plain strings, so Twinsies builds the envelopes itself over the HTTP client Craft already ships. That also means the request that failed can be shown to you verbatim.
The client ID and secret are plugin settings, so put them in .env and reference them — plugin settings are project config, and project config is committed. The grant itself is never in project config: it lives in Twinsies' own table, encrypted with your Craft security key. A Twinfield refresh token is valid for roughly 25 years.
Nothing the customer sees. The trigger catches everything and posting goes through the queue by default, so the order completes and the document is parked for a retry. An accounting system must never be able to stop someone paying.
Not from Craft, and Twinsies does not pretend otherwise. A concept invoice or provisional transaction can be deleted in Twinfield; a final one can only be credited. "Forget this record" removes Twinsies' own copy so the order can be posted again — it changes nothing in Twinfield. This is why the defaults are concept and provisional.
The refunded amount is apportioned across the order's VAT codes in proportion to their value. A partial refund cannot know which items came back, and that split is the only one that leaves the VAT return correct without inventing facts about the return. A full refund mirrors the invoice exactly.
Because the lines did not add up to what the customer paid, by more than a rounding cent. The message names the adjustment types it could not express — usually a custom Commerce adjuster like a tip or a surcharge. Booking an unexplained difference to a revenue account produces books that reconcile and are wrong, and nobody finds out until an accountant does.
Yes — "Post unposted orders" on the Documents screen, or php craft twinsies/sync/pending. Post a few first and check them in Twinfield before doing the lot.
Not in this version. One site posts into one office.
Yes — the whole control panel interface, in Twinfield's own vocabulary rather than a literal translation. Set your Craft user's language to Dutch and the plugin follows.
No. Twinsies is an independent plugin. Twinfield is a product of Wolters Kluwer.
Craft CMS 5.3+, Craft Commerce 5.0+, PHP 8.2+. There is no Craft 4 version.
Stop rekeying orders into the books
$149, one edition, everything included. Start on concept invoices, check what comes out, then switch it on properly.