Matching own payments in Modern bank reconciliation

Enter the house of pain.001

Matching own payments in Modern bank reconciliation

Trying to reconcile all-standard outbound payments ISO20022 pain.001 CT produced by Dynamics 365 for Finance with a Camt.053 bank statement imported by the Microsoft’s own Advanced bank reconciliation (ABR) Camt.053 format is futile, probably because of the patchwork development of the AP and Bank modules.

The Reconciliation matching rule in the Modern bank reconciliation sub-module will try to look for the Document number in the bank transaction BankAccountTrans, but there won’t be any, while the payment reference (see below) may not be sent back by the bank with the statement.

Credit transfers

For credit transfers, a good way to recognize self-initiated payments may be by the <EndToEndId> element generated by the Electronic Reporting (ER) configuration for ISO20022 Credit Transfer. Dynamics builds this identifier from the Accounts Payable payment journal line by concatenating two or three components separated by dashes:

VoucherNumber-RecIdofLedgerJournalTrans[-optional counter]

The counter is added when multiple attempts are made to generate the same pain.001 file. Example:

				
					<NtryDtls>
  <TxDtls>
    <Refs>
      <AcctSvcrRef>BLA-BLA-BLA</AcctSvcrRef>
      <EndToEndId>APP001547-5637312576-2</EndToEndId>
    </Refs>
  </TxDtls>
</NtryDtls>
				
			

Here, the general ledger voucher APP001547 forms part of the <EndToEndId>. In the Microsoft ABR Camt.053 format, this element is written into the Description field of the imported bank statement line. The reconciliation matching rule (Cash and bank management > Setup > Advanced bank reconciliation setup > Reconciliation matching rules) can then compare the voucher number against the Description.

However, the Contains operator will not help, because the Description is longer than the voucher: the voucher does not contain, it is contained. The In operator (Voucher is contained in the Description) is not available here, and the less “<” operator if not going to help, either. 

To carve out the voucher number only and let the exact match “=” operator to work, you may modify either the ABR Camt.053 format (where the XML file is interpreted) or the ABR Bank statement mapping to destination (where the parsed data is written to the bank statement entity).

To adjust the format, open Organization administration > Electronic reporting > Configurations, find ABR Camt.053 format under Advanced bank reconciliation statement model, press +Create configuration to derive a new from the ABR Camt.053 format. In the Designer, open Map format to model and launch its Designer.

The DATA SOURCES to the left follow the XML structure:

				
					BkToCstmrStmt
 └─ Stmt
     └─ Ntry
         └─ NtryDtls
             └─ TxDtls
                 └─ Refs
                     └─ EndToEndId

				
			

On the right side, …NtryDtls/TxDtls/Refs/EndToEndId maps to Statement/StatementLine/EndToEndId.

By default, the mapping expression is:

IF(AND(@.Refs.IsMatched, @.Refs.Data.EndToEndId.IsMatched), @.Refs.Data.EndToEndId.Data.Str, "")

If your voucher numbers are fixed at nine characters, replace it with:

IF(AND(@.Refs.IsMatched, @.Refs.Data.EndToEndId.IsMatched), LEFT(@.Refs.Data.EndToEndId.Data.Str, 9), "")

Save and close, mark the version as Completed, and assign this format under Cash and bank management > Setup > Advanced bank reconciliation setup > Bank statement format. From that point, the <EndToEndId> will travel through the following path:

Vendor payment journal line Voucher → ISO20022 Credit Transfer → Bank → [ISO20022 pain.002 confirmation] → ABR Camt.053 format → ABR Bank statement mapping to destination → Bank statement line Description → Bank reconciliation worksheet.

Direct debits

For direct debits, where funds are collected from customer accounts via SEPA mandates, the flow differs. There is a <Ref> element which represents the Structured Creditor Reference, and it may be preferable over <EndToEndId>. In Dynamics 365, the Creditor reference corresponds to the Payment ID on the invoice.

Customer payment journal line Payment Id → ISO20022 Direct debit  Bank  ISO20022 Camt.054 or ABR Camt.053 format → Mapping to destination → Bank statement line Creditor reference information → Bank reconciliation worksheet.

The structure in the pain.008 file appears as: 

				
					BkToCstmrStmt
 └─ Stmt
     └─ Ntry
         └─ NtryDtls
             └─ TxDtls
                 └─ RmtInf
                     └─ Strd
                         └─ CdtrRefInf
                             └─ Ref

				
			
				
					<RmtInf>
  <Strd>
    <CdtrRefInf>
      <Tp>
        <CdOrPrtry>
          <Cd>SCOR</Cd>
        </CdOrPrtry>
      </Tp>
      <Ref>RFxx123456789</Ref>
    </CdtrRefInf>
  </Strd>
</RmtInf>

				
			

According to EPC142-08 (https://www.europeanpaymentscouncil.eu/sites/default/files/KB/files/EPC142-08-EPC-Guidance-on-Creditor-Reference-ISO-Std.pdf) the bank must return this structured reference. Unfortunately, Dynamics 365 cannot currently produce a proper Payment ID compliant with the Mod 97 checksum required for structured creditor references, since the so-called “Norwegian” Payment ID is not flexible enough.

You can vote for an improvement here: Dynamics Idea Portal – Structured Creditor Reference.

As a workaround, assuming invoice numbers contain only digits, you can form a pseudo-structured reference by prefixing the invoice number with RF00 with the feature NO-00002 Customer payment based on payment ID – Finance | Dynamics 365 | Microsoft Learn. This synthetic reference can then be used by the reconciliation rule to match incoming customer payments in the bank statement:

Amend GDPdU = GoBD = FEC

Amend GDPdU = GoBD = FEC

The audit export file in Dynamics 365 for Finance may be easily extended, a power user can do it on his/her own. For example, the auditors often ask for a “system date” or time column in the audit file for their DATEV applications: in a nutshell, they need to know when the invoice was really posted, not only the invoice date.

Here is how to fulfil this requirement:

  1. Open the Electronic reporting workspace (Organisation administration >  Workspaces). Make sure a custom “provider” is selected as “active”. Check here to learn how and why: Electronic Reporting (ER) Cookbook 2: new tips from the kitchen
  2. Click the Reporting configurations tile and locate the root Data export model node. To amend the French FEC file, select the  French FEC model mapping instead.
  3. Click +Create configuration and select the “Model Mapping based on data model Data export model” option. Namely, the model itself is very abstract in the case of this data export, the interesting stuff is hidden in the model mapping.
  4. Select the new model mapping in the tree and use the Designer, then click Designer again.
  5. In the Model mapping designer, look for the odd looking objects like _01xxxx, _02xxxx etc. at the bottom of the Data sources list. These are the “Table metadata” objects. I have a feeling that these artifacts were invented solely for this usage scenario of generic data exports with variable columns. In our case, choose _01Sachkonten, then Edit, then Editor.
  6. The Table metadata editor has a unique UI. In the leftmost list, select the Sachkontobuchungen table. In the rightmost list, locate the $Entries/$GeneralJournalEntry/createdDateTime node and Add it to the middle list of fields (see the screenshot above). Rename the new field, if necessary.
  7. That’s it, hit Save, close the table editor, confirm with OK and save the changes in the model mapping designer ultimately.
  8. In the end, Change status of your custom model mapping to Complete and mark it as the Default for model mapping to inactivate the standard one.
  9. If you need to format the date-time column in a special way, you’d need to make a format derived from the standard German audit file output, too. In that one, you’d need to modify the Transformation fmtdatatime. You will learn in the blog Electronic Reporting (ER) Cookbook 3: Working with dates how to do it.
  10. To test your changes, launch General ledger > Periodic tasks > Data export, select the Format mapping (choose your own if you modified it at step 9). Select Table Group = Ledger accounts, choose the dates, launch and verify the output in one of files in the resulting ZIP offered for download:


"130300-001-";2025-02-21;"Period 2";"68721077482";"Benutzung";"Verkauf - Lieferschein-Umsatzerlös, Gegenkonto";"Nein";"Nein";499,96;"EUR";499,96;"";21.02.2025;"SPS-1000165";21.02.2025;"SPK-000166";"Aktuell";"";"";68719785542;"SPK-000166"


"140200-001-";2025-02-21;"Period 2";"68721077479";"Benutzung";"Kosten der gelieferten Einheiten";"Nein";"Ja";-315,50;"EUR";-315,50;"";21.02.2025;"SPS-1000165";21.02.2025;"SPK-000166";"Aktuell";"";"";68719785542;"SPK-000166"

By the way, you may use the parameter Include “Create by” field to comply with another common requirement: export the user ID to prove to the auditor that it is the accountant who makes the ledger transactions, not an IT consultant 😉

Troubleshoot the VAT Declaration in D365 for Finance

Troubleshoot the VAT Declaration in D365 for Finance

Users of the VAT declarations (both Excel and XML) in the financial department are often shocked by error messages of this kind:

  • Evaluating binding of format component Excel/Sheet1/I_Turnover/Box_200
  • Fehler beim Bewerten des Ausdrucks für Pfad ‚Boxes/Box81_Base‘
  • Fehler beim Bewerten des Ausdrucks für Pfad ‘Boxes/Box_150’.

The exact error message differs by country: the first is produced by the “VAT Declaration Excel (CH)” / “VAT Declaration XML (CH)” for Switzerland, the second one is from Germany, the 3rd is from Spain. In reality, the error has nothing to do with the “Boxes” i.e. the Excel layout but a clear sign that the Application specific parameters / Setup fail to classify a specific VAT use case. Namely, a VAT code was used in a module / situation not envisioned by the FiCo functional consultant who configured the VAT Declaration.

Update 09.06.2025: meanwhile, the recent versions of VAT declarations in Electronic reporting give an exact hint which code and tax direction fell through the grate, for example: “…(Code): „ESIN0“, … (TransactionClassifier): „Purchase“…”, and the below cumbersome algorithm of finding the date, code, and the transaction classifier became obsolete.

1. Use division by dichotomy to find the exact date

… when it happened. Most of the European VAT declarations are returned monthly, and it takes on average 7 attempts to narrow down the date. Locate the VAT declaration in the Organisation administration > Workspaces > Electronic reporting, Reporting configurations tree under the Tax declaration model node. Keep starting the report with the Run button above, variate the dates.

2. Find uncommon combinations of VAT code and Direction

Having spotted the date, filter tax transactions by that date and the VAT settlement period using the query Tax > Inquiries and reports > VAT inquiries > Posted VAT (hereafter I refer to the en-gb language of the D365 UI). Export the results into Excel. Build a pivot table by the VAT code and direction, counting the vouchers (= business cases) at the cross sections. Start looking for outliers, pay particular attention to the low counts i.e. seldom use cases. Often the mistake is obvious:

VAT code Duty-free purchase Duty-free sale Use tax VAT payable VAT receivable
euSt 1 7 1
exSt 7
FoodR 15
R 2 5
ServSt 11
St 39

In this example, the euSt code designates VAT exempt intra-community sales, or intra-community acquisitions at the standard tax rate of 19% (= “use tax” or Import VAT / purchase VAT in en-gb, see Minimalistic EU VAT Configuration in Dynamics 365). This code is not supposed to appear in the context of a VAT free purchase, but someone managed to make such a transaction in a general ledger journal when entering a EU supplier invoice.

You cannot fix the tax transactions, but the Application specific parameters may be amended to account for this irregularity. Open this list of Conditions and filter it by the tax code in question to validate the suspicion:

You have to add a new line with this combination of the Tax code and the Transaction classifier to capture this exceptional case. Namely, a pair euSt–PurchaseExempt must be added. Try the VAT declaration one more time to confirm that the problem is now gone.

3. Use a fallback condition

Sometimes it is not that easy to spot a pattern: the occurrences may be too many even on a single day. Your next approach may be to leverage the placeholders *Not blank* for the Tax code and *Not blank* for the Transaction classifier. These lines must be placed at the very bottom of the list of conditions (note the Move down button).

Use these fallback lines with placeholders to redirect the total tax amount of the questionable nature into a separate VAT declaration cell which is typically empty, for example to the cell 61-InputTaxCorrection on the German “UVA” tax declaration. This will give you an idea how much is missing in tax, and what the tax origin amount may be.

Do not keep the placeholders in your PROD setup for long: by doing so, you are resigning and testifying that you don’t really know what is happening in the tax ledger but play dice with the tax authority, which is a very bad idea.

You may also have some tax transactions that do not need to be reported to the tax authority at all. Capture such a case with a combination of a VAT code and direction, and send it into the Other cell i.e. into oblivion:

4. If nothing helps

…then you may have encountered a true bug in the VAT declaration, a case that does not fit into any of the Transaction classifier categories but an Error one!

Indeed, recently we discovered that the reversal of a customer transaction settlement with a realised cash discount is accompanied by a positive adjustment of the VAT payable (i.e. we again own more VAT to the state, which is correct). But this adjustment is not attributed to the VAT direction of Sales, it results in an Error in the VAT declaration instead.

Add lines with the explicit Transaction classifier = Error to manage this case: