Skip to content

Read purchase transaction

Reads one purchase transaction: the invoice number of the supplier and the due date, the total line with the supplier, the cost and VAT lines, whether it is paid, and with which payments.

Twinfield documentation: Purchase transactions.

get($dayBook, $number) returns a PurchaseTransaction, or throws a TransactionNotFoundException when the transaction (or the day book) does not exist. Use find() to get null instead. The purchase day book is usually INK in Dutch companies and PNV in English ones.

  • $transaction->header: company, day book, number, status (Provisional or Final), period, date, currency, origin, user and dates.
  • $transaction->invoiceNumber, dueDate and paymentReference. dueDate is null for a purchase invoice entered by hand without due date; paymentReference is null when not set.
  • $transaction->total: the line with the supplier (dim2) and the accounts payable account (account), the total including VAT, the VAT total, the payment status (matchStatus), the open amount and the payments it is matched with (matches).
  • $transaction->details: the costs without VAT, with VAT code and VAT amount, and the cost center (dim2) and project (dim3).
  • $transaction->vat: the VAT per VAT code, with the amount it was calculated on (vatTurnover).

value() is the total signed: positive for an invoice (what you owe the supplier), negative for a credit note (isCreditNote()). isPaid() is true when the invoice is matched with payments.

Twinfield gives the open amount in the base currency (openBaseValue) signed: negative for a purchase invoice, because its total line is credit. Imported invoices can have discount lines with a negative amount on the debit side; the SDK keeps them as they are, also in edit().

The Finder gives no transaction numbers; see Open invoices to find unpaid invoices by supplier.

$twinfield = Example::twinfield();
if (!isset($argv[1], $argv[2])) {
echo 'Pass a purchase day book and transaction number, e.g. INK 202600021.', PHP_EOL;
exit(0);
}
try {
$transaction = $twinfield->purchaseTransactions()->get($argv[1], (int) $argv[2]);
} catch (TransactionNotFoundException $exception) {
echo 'Not found: ', $exception->reason, PHP_EOL;
exit(1);
}
$header = $transaction->header;
$total = $transaction->total;
echo 'Transaction: ', $header->dayBook, ' ', $header->number, ' (', $header->status->name, ')', PHP_EOL;
echo 'Invoice: ', $transaction->invoiceNumber, $transaction->isCreditNote() ? ' (credit note)' : '', PHP_EOL;
echo 'Date: ', $header->date->format('Y-m-d'), ', due ', $transaction->dueDate?->format('Y-m-d') ?? '-',
', period ', $header->period, PHP_EOL;
echo 'Supplier: ', $transaction->supplier()->code, ' ', $transaction->supplier()->name, ' on ',
$total->dim1->code, PHP_EOL;
echo 'Total: ', $transaction->value(), ' ', $header->currency, ', VAT ', $total->vatTotal ?? '-', PHP_EOL;
echo 'Payment: ', $total->matchStatus->value, ', open ', $total->openBaseValue ?? '-', PHP_EOL;
foreach ($transaction->details as $line) {
echo sprintf(
' %-6s %-6s %10s %-4s %8s %s',
$line->debitCredit->value,
$line->dim1->code,
$line->value,
$line->vatCode ?? '',
$line->vatValue ?? '',
$line->description ?? '',
), PHP_EOL;
}
foreach ($transaction->vat as $line) {
echo sprintf(
' %-6s %-6s %10s VAT %s on %s',
$line->debitCredit->value,
$line->dim1->code,
$line->value,
$line->vatCode,
$line->vatTurnover ?? '-',
), PHP_EOL;
}
foreach ($total->matches as $set) {
foreach ($set->lines as $match) {
echo ' paid with ', $match->dayBook, ' ', $match->number, ' line ', $match->line, ': ', $match->matchValue,
' on ', $set->matchDate->format('Y-m-d'), PHP_EOL;
}
}
Terminal window
php examples/purchase-transactions/read-purchase-transaction/example.php INK 202600012
Transaction: INK 202600012 (Final)
Invoice: F-2026-0042
Date: 2026-11-03, due 2026-12-03, period 2026/11
Supplier: 2000 Example supplier on 1600
Total: 181.50 EUR, VAT 31.50
Payment: available, open -181.50
debit 7000 100.00 IH 21.00 Consultancy
debit 7000 50.00 IH 10.50 Training
debit 1520 31.50 VAT IH on 150.00

What the SDK sends to Twinfield and what Twinfield sends back, for a call like the one in this example. The responses come from the tests, with example data.

Twinfield documentation: Purchase transactions: Read.

$twinfield->purchaseTransactions()->get('INK', 202600012);

The SDK sends this XML as xmlRequest of ProcessXmlString to processxml.asmx:

<read>
<type>transaction</type>
<office>1000</office>
<code>INK</code>
<number>202600012</number>
</read>

Twinfield answers with this XML in ProcessXmlStringResult:

<transaction location="final" result="1">
<header>
<office name="Example Holding B.V." shortname="">1000</office>
<code name="Inkoopfactuur" shortname="Inkoop">INK</code>
<number>202600012</number>
<period>2026/11</period>
<currency name="Euro" shortname="Euro">EUR</currency>
<regime>Generic</regime>
<date>20261103</date>
<origin>manual</origin>
<originreference/>
<modificationdate>20261104091200</modificationdate>
<user name="Example user" shortname="User">EXAMPLE</user>
<inputdate>20261103101530</inputdate>
<duedate>20261203</duedate>
<invoicenumber>F-2026-0042</invoicenumber>
<freetext1>Order 778</freetext1>
<freetext3/>
</header>
<lines>
<line type="total" id="1">
<dim1 name="Crediteuren" shortname="" dimensiontype="BAS">1600</dim1>
<dim2 name="Example supplier" shortname="" dimensiontype="CRD">2000</dim2>
<debitcredit>credit</debitcredit>
<basevalue>181.50</basevalue>
<rate>1</rate>
<value>181.50</value>
<description>Total</description>
<vatbasetotal>31.50</vatbasetotal>
<vattotal>31.50</vattotal>
<matchstatus>available</matchstatus>
<matchlevel>2</matchlevel>
<relation>2</relation>
<basevalueopen>-181.50</basevalueopen>
</line>
<line type="detail" id="2">
<dim1 name="Inkoop hoog" shortname="" dimensiontype="PNL">7000</dim1>
<debitcredit>debit</debitcredit>
<basevalue>100.00</basevalue>
<rate>1</rate>
<value>100.00</value>
<description>Consultancy</description>
<vatcode name="BTW Hoog" shortname="I Hoog" type="purchase">IH</vatcode>
<vatbasevalue>21.00</vatbasevalue>
<vatvalue>21.00</vatvalue>
<matchstatus>notmatchable</matchstatus>
</line>
<line type="detail" id="3">
<dim1 name="Inkoop hoog" shortname="" dimensiontype="PNL">7000</dim1>
<dim2 name="Algemeen" shortname="" dimensiontype="KPL">00100</dim2>
<dim3 name="Example project" shortname="" dimensiontype="PRJ">P0001</dim3>
<debitcredit>debit</debitcredit>
<basevalue>50.00</basevalue>
<rate>1</rate>
<value>50.00</value>
<description>Training</description>
<vatcode name="BTW Hoog" shortname="I Hoog" type="purchase">IH</vatcode>
<vatbasevalue>10.50</vatbasevalue>
<vatvalue>10.50</vatvalue>
<matchstatus>notmatchable</matchstatus>
</line>
<line type="vat" id="4">
<dim1 name="Te vorderen btw hoog" shortname="" dimensiontype="BAS">1520</dim1>
<debitcredit>debit</debitcredit>
<basevalue>31.50</basevalue>
<rate>1</rate>
<value>31.50</value>
<description>Btw</description>
<vatbaseturnover>150.00</vatbaseturnover>
<vatturnover>150.00</vatturnover>
<vatcode name="BTW Hoog" shortname="I Hoog" type="purchase">IH</vatcode>
<vatbasevalue>0.00</vatbasevalue>
<vatvalue>0.00</vatvalue>
<baseline>1</baseline>
<matchstatus>available</matchstatus>
<matchlevel>1</matchlevel>
<relation>0</relation>
<basevalueopen>31.50</basevalueopen>
</line>
</lines>
</transaction>

View examples/purchase-transactions/read-purchase-transaction/example.php on GitHub.

Made by SolveBeam

Twinfield and Wolters Kluwer are trademarks of Wolters Kluwer. Their names and logos are used only to refer to their products.