Bulk import with errors
Saves three bank transactions in one request with saveMany(), where the second one has an account that does not exist. This changes data in Twinfield; the example deletes the saved transactions again.
Twinfield documentation: Bank transactions.
Twinfield saves the valid transactions and refuses the others, so saveMany() does not throw: it returns a SaveManyResult with, per input in the same order, a SavedTransaction (with the transaction) or a FailedTransaction (with the errors and where they are). Use saved(), failed() and allSaved() to handle them.
$twinfield = Example::twinfield();
$bank = $twinfield->bankTransactions();$costs = Example::profitAndLossAccount($twinfield);$base = BankTransactionInput::forBankBook(Example::bankBook($twinfield), new DateTimeImmutable());
// Three statements in one request; the second has an account that does not exist.$result = $bank->saveMany( $base->statement(1)->pay($costs, '1.00', description: 'Example day 1'), $base->statement(2)->pay('NOPE9999', '2.00', description: 'Example day 2'), $base->statement(3)->pay($costs, '3.00', description: 'Example day 3'),);
foreach ($result as $item) { echo sprintf('[%d/%d] ', $item->index + 1, count($result)), match (true) { $item instanceof SavedTransaction => 'saved as ' . $item->transaction->number(), default => 'failed: ' . $item->message(), }, PHP_EOL;}
echo count($result->saved()), ' saved, ', count($result->failed()), ' failed', PHP_EOL;
// Clean up: delete the provisional example transactions again.foreach ($result->saved() as $saved) { $bank->delete($saved->transaction->dayBook(), $saved->transaction->number(), 'twinfield-php example');}php examples/bank-transactions/bulk-import-with-errors/example.php[1/3] saved as 202600049[2/3] failed: transactions/transaction[2]/lines/line[2]/dim1: Grootboekrekening NOPE9999 bestaat niet.[3/3] saved as 2026000502 saved, 1 failedWhat 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.
Create
Section titled “Create”Twinfield documentation: Bank transactions: Create.
$base = BankTransactionInput::create('BNK', '1010', new DateTimeImmutable('2026-11-03'));
$twinfield->bankTransactions()->saveMany( $base->receive('1300', '50.00', customer: '1000'), $base->receive('1300', '75.00', customer: '9999'),);The SDK sends this XML as xmlRequest of ProcessXmlString to processxml.asmx:
<transactions> <transaction destiny="temporary"> <header> <office>1000</office> <code>BNK</code> <date>20261103</date> </header> <lines> <line type="total" id="1"> <dim1>1010</dim1> <debitcredit>debit</debitcredit> <value>50.00</value> </line> <line type="detail" id="2"> <dim1>1300</dim1> <dim2>1000</dim2> <debitcredit>credit</debitcredit> <value>50.00</value> </line> </lines> </transaction> <transaction destiny="temporary"> <header> <office>1000</office> <code>BNK</code> <date>20261103</date> </header> <lines> <line type="total" id="1"> <dim1>1010</dim1> <debitcredit>debit</debitcredit> <value>75.00</value> </line> <line type="detail" id="2"> <dim1>1300</dim1> <dim2>9999</dim2> <debitcredit>credit</debitcredit> <value>75.00</value> </line> </lines> </transaction></transactions>Twinfield answers with this XML in ProcessXmlStringResult:
<transactions result="0"> <transaction destiny="temporary" result="1" location="temporary"> <header> <office name="Example Holding B.V." shortname="Holding">1000</office> <code name="Bank" shortname="Bank">BNK</code> <currency name="Euro" shortname="Euro">EUR</currency> <date>20261103</date> <period>2026/11</period> <number>202600047</number> <user name="Example user" shortname="User">EXAMPLE</user> <startvalue>0.00</startvalue> <closevalue>0.00</closevalue> </header> <lines> <line type="total" id="1"> <dim1 name="Bank" type="BAS">1010</dim1> <debitcredit>debit</debitcredit> <value>50.00</value> <rate>1</rate> <basevalue>50.00</basevalue> <matchstatus>notmatchable</matchstatus> </line> <line type="detail" id="2"> <dim1 name="Debiteuren" type="BAS">1300</dim1> <dim2 name="Example customer" type="DEB">1000</dim2> <debitcredit>credit</debitcredit> <value>50.00</value> <rate>1</rate> <basevalue>50.00</basevalue> <matchstatus>available</matchstatus> </line> </lines> </transaction> <transaction destiny="temporary" result="0"> <header> <office name="Example Holding B.V." shortname="Holding">1000</office> <code name="Bank" shortname="Bank">BNK</code> <currency name="Euro" shortname="Euro">EUR</currency> <date msgtype="warning" msg="Datum valt buiten de periode.">20261103</date> </header> <lines> <line type="total" id="1"> <dim1>1010</dim1> <debitcredit>debit</debitcredit> <value>75.00</value> </line> <line type="detail" id="2"> <dim1>1300</dim1> <dim2 msgtype="error" msg="Relatie 9999 bestaat niet.">9999</dim2> <debitcredit>credit</debitcredit> <value>75.00</value> </line> </lines> </transaction></transactions>Source
Section titled “Source”View examples/bank-transactions/bulk-import-with-errors/example.php on GitHub.
Twinfield and Wolters Kluwer are trademarks of Wolters Kluwer. Their names and logos are used only to refer to their products.