Logo
Afbeelding

Analyzing Transactions to (High-Risk) Countries (CAMT and FATF List)

Written by The Audit Analytics | 5 minutes

Every transaction tells a story, but some lead to high-risk countries. This analysis helps you uncover them using bank data. Discover in one simple data analysis to which countries payments were made. This check helps you detect potential money laundering or fraud risks and uses the international FATF list in combination with your bank transactions (CAMT-053).

Payments to high-risk countries

Every financial audit includes an assessment of cash flows. Not only to understand where money comes from and where it goes, but also to ensure there are no payments made to high-risk countries. Such payments may indicate money laundering or fraud.

The FATF list (Financial Action Task Force) contains countries with an increased risk in these areas. Organizations active in international trade, for example, importers, donation platforms, or logistics companies, are particularly exposed to such risks.

As an auditor or controller, you can use data analysis to easily identify suspicious cash flows. We use bank statements in the CAMT.053 format and analyze them using Python.

Required Data and Packages

For this analysis, we use CAMT files. These are XML files used by banks to report transactions. Nearly all European banks will provide exports in this format from 2025 onward.

You can find more information about the format here, and another article offers a converter to Excel.

We'll use Python for the analysis, with one additional package ('pandas'). It's easy to install, and you can find more information about pandas in auditing on the website.

Step 1: List of High-Risk Countries

First, we define a list of high-risk countries based on the FATF list. You can find the latest version here:
https://www.fatf-gafi.org/en/countries/black-and-grey-lists.html

# Example list of high-risk countries
high_risk_country_codes = {"IR", "KP", "SY", "SD", "PK", "YE", "MM", "CU", "AF", "ZM"}

Step 2: Read the CAMT.053 File

We read the bank transactions and extract key fields: date, amount, debtor, creditor, and IBAN. The example script below is a simplified version. You can find more details about the CAMT converter in the linked article.

import xml.etree.ElementTree as ET
import pandas as pd

def parse_camt053(file_path):
    tree = ET.parse(file_path)
    root = tree.getroot()
    ns = {'ns': 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02'}

    transactions = []
    for entry in root.findall('.//ns:Ntry', ns):
        try:
            amount = float(entry.find('ns:Amt', ns).text)
        except (ValueError, AttributeError):
            amount = 0.0

        currency = entry.find('ns:Amt', ns).attrib.get('Ccy', 'N/A')
        date = entry.find('.//ns:BookgDt/ns:Dt', ns).text or '-'
        debtor = entry.find('.//ns:Dbtr/ns:Nm', ns).text or '-'
        debtor_iban = entry.find('.//ns:DbtrAcct/ns:Id/ns:IBAN', ns).text or '-'
        creditor = entry.find('.//ns:Cdtr/ns:Nm', ns).text or '-'
        creditor_iban = entry.find('.//ns:CdtrAcct/ns:Id/ns:IBAN', ns).text or '-'

        transactions.append({
            "Date": date,
            "Debtor": debtor,
            "Debtor IBAN": debtor_iban,
            "Creditor": creditor,
            "Creditor IBAN": creditor_iban,
            "Amount": amount,
            "Currency": currency
        })
    
    return pd.DataFrame(transactions)

# Load the CAMT file
file_path = "camt053_dummy.xml"
df = parse_camt053(file_path)
print(df.head())

Step 3: Extract Country Codes from IBAN

The first two letters of an IBAN indicate the country code. This allows you to determine in which country the account is held.

def get_country_from_iban(iban):
    return iban[:2]

df["Creditor Country"] = df["Creditor IBAN"].apply(get_country_from_iban)
df["Debtor Country"] = df["Debtor IBAN"].apply(get_country_from_iban)

Step 4: Filter Transactions from High-Risk Countries

Now we filter transactions where either the payer or the recipient is located in a high-risk country.

df_high_risk = df[
    df["Creditor Country"].isin(high_risk_country_codes) |
    df["Debtor Country"].isin(high_risk_country_codes)
]

Step 5: Summarize the Results

Finally, we summarize how many payments were made and the total amounts involved.

df_analysis = df_high_risk.groupby(["Creditor Country"]).agg(
    Transaction_Count=("Amount", "count"),
    Total_Amount=("Amount", "sum")
).reset_index()

print(df_analysis)

Creditor Country Transaction Count Total Amount


IR 5 12500 PK 3 7600 YE 7 18100 CU 2 3200

Interpretation and Next Steps

This analysis shows to which countries payments have been made and how frequently. As an auditor, you should further investigate:

  • Are these legitimate payments (e.g., regular suppliers)?\
  • Are there new accounts, unusual names, or unexpected amounts?\
  • Are there transactions to countries unrelated to business activities?

This provides a quick overview of potential risks of money laundering or unauthorized payments.

Limitations of IBAN Country Codes & BIC

Not all countries use IBAN numbers. The International Bank Account Number (IBAN) is mainly used within Europe and countries that participate in the SEPA standard (Single Euro Payments Area). Outside these regions, banks often use different account structures or national formats.

When analyzing CAMT files or other payment data, keep in mind:

  • Check whether the 'IBAN' field is actually filled. Missing values might mean the transaction originates from a non-IBAN country.
  • Use additional fields such as BIC (Bank Identifier Code) to determine the country of origin or destination.
  • For international SWIFT payments, the BIC or country code in the transaction can often help identify the correct country.

Note that some banks route international payments through intermediary accounts. This can cause the original country code to be missing in the IBAN field, potentially distorting your analysis.

In short: while IBAN is a reliable indicator within Europe, for payments outside the SEPA area you should use alternative fields or perform additional checks to accurately identify the transaction's origin.

Toolkit

Want to go further? Check out the CAMT Analytics Toolkit.
This toolkit includes extended scripts, documentation, and dummy data to perform this and similar analyses. It also contains a BIC-based analysis for even more accurate tracing of transaction origins. More information about the available toolkits can be found here.