Category: XML Templates Last Updated: 2026-02-12 Applies To: EU DAC8 / OECD CARF XML Schema
---
Overview
The DAC8/CARF framework requires Reporting Crypto-Asset Service Providers (RCASPs) to categorise transactions by type when building XML reports. Each transaction type has specific reporting requirements, value determination rules, and aggregation logic. Getting the transaction type encoding right is essential for compliant reporting.
This article covers the transaction type codes defined in the OECD CARF schema, what each one means, and how to encode them correctly in your XML output.
Transaction Types in the CARF Schema
The OECD CARF framework defines the following primary categories of reportable transactions:
| Code | Description | Typical Scenario |
|---|---|---|
EXCHANGE_FIAT | Exchange of crypto-asset for fiat currency | User sells BTC for EUR |
EXCHANGE_CRYPTO | Exchange of one crypto-asset for another | User swaps BTC for ETH |
TRANSFER | Transfer of crypto-asset to a wallet not controlled by the RCASP | User withdraws BTC to an external wallet |
RETAIL_PAYMENT | Payment for goods or services using crypto-assets | User pays a merchant with BTC |
> Note: The exact code values may differ in the final published schema. Some jurisdictions may use a simplified set (e.g., a single EXCHANGE code covering both fiat and crypto exchanges). Always verify against the XSD your tax authority requires.
XML Encoding
Exchange Transactions (Crypto-to-Fiat)
<TransactionSummary>
<TransactionType>EXCHANGE_FIAT</TransactionType>
<NumberOfTransactions>23</NumberOfTransactions>
<AggregateGrossProceeds currCode="EUR">15750.00</AggregateGrossProceeds>
<CryptoAssetDetails>
<AssetCode>BTC</AssetCode>
<TotalUnits>0.45000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
For crypto-to-fiat exchanges, the AggregateGrossProceeds is the total fiat amount received by the user across all transactions of this type during the reporting period. This is typically straightforward because the fiat value is directly available from the trade records.
Exchange Transactions (Crypto-to-Crypto)
<TransactionSummary>
<TransactionType>EXCHANGE_CRYPTO</TransactionType>
<NumberOfTransactions>12</NumberOfTransactions>
<AggregateGrossProceeds currCode="EUR">8200.00</AggregateGrossProceeds>
<CryptoAssetDetails>
<AssetCode>BTC</AssetCode>
<TotalUnits>0.25000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
For crypto-to-crypto exchanges, you must determine the fair market value of the crypto-asset disposed of (or acquired) at the time of the transaction. This value must be expressed in the reporting currency (typically EUR for EU jurisdictions). See the article on crypto-to-crypto reporting for valuation details.
Transfer Transactions
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<NumberOfTransactions>5</NumberOfTransactions>
<AggregateTransferValue currCode="EUR">12000.00</AggregateTransferValue>
<CryptoAssetDetails>
<AssetCode>ETH</AssetCode>
<TotalUnits>4.20000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
Transfer transactions use AggregateTransferValue rather than AggregateGrossProceeds. The value is the fair market value of the transferred crypto-asset at the time of the transfer. Only transfers to wallets or addresses not controlled by the same RCASP are reportable.
Retail Payment Transactions
<TransactionSummary>
<TransactionType>RETAIL_PAYMENT</TransactionType>
<NumberOfTransactions>3</NumberOfTransactions>
<AggregateGrossProceeds currCode="EUR">450.00</AggregateGrossProceeds>
<CryptoAssetDetails>
<AssetCode>BTC</AssetCode>
<TotalUnits>0.01500000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
Retail payments are exchanges where crypto-assets are used to pay for goods or services. The value to report is the amount of the payment (the value of goods or services, or the fair market value of the crypto-asset disposed of).
Determining the Correct Transaction Type
The classification logic should be applied at the individual transaction level before aggregation:
- Did the user receive fiat currency in exchange for crypto? This is an
EXCHANGE_FIATtransaction.
- Did the user receive a different crypto-asset in exchange for another crypto-asset? This is an
EXCHANGE_CRYPTOtransaction.
- Did the user transfer crypto-assets to an external wallet (not on your platform)? This is a
TRANSFERtransaction.
- Did the user use crypto-assets to pay a merchant or for goods/services? This is a
RETAIL_PAYMENTtransaction.
Edge Cases
Internal transfers between user accounts on the same platform: These are generally not reportable as transfers, since the crypto-assets remain under the control of the same RCASP.
Staking rewards and airdrops: The classification of incoming crypto-assets from staking, airdrops, or similar mechanisms may depend on how the jurisdiction interprets DAC8. Consult local guidance. If they are treated as reportable, you may need to determine the appropriate transaction type or use a specific code if one is defined.
Fees: Network fees (gas fees) and platform trading fees are generally not reported as separate transactions. However, they may affect the gross proceeds calculation. Clarify with local authority guidance whether fees should be included in or excluded from aggregate values.
Failed or reversed transactions: Transactions that were initiated but did not complete (e.g., failed blockchain transactions) should not be included in the report. Only settled transactions count.
Aggregation Rules
Transaction summaries are aggregated per:
- Transaction type (each type gets its own
TransactionSummaryblock) - Crypto-asset (each distinct asset gets its own block within the same type)
- Reporting period (calendar year)
This means a user who traded BTC and ETH in both exchange and transfer transactions would have up to four TransactionSummary blocks:
<!-- BTC exchanges -->
<TransactionSummary>
<TransactionType>EXCHANGE_FIAT</TransactionType>
<!-- BTC exchange data -->
</TransactionSummary>
<!-- ETH exchanges -->
<TransactionSummary>
<TransactionType>EXCHANGE_FIAT</TransactionType>
<!-- ETH exchange data -->
</TransactionSummary>
<!-- BTC transfers -->
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<!-- BTC transfer data -->
</TransactionSummary>
<!-- ETH transfers -->
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<!-- ETH transfer data -->
</TransactionSummary>
Implementation Recommendations
- Tag transactions at execution time. Store the transaction type in your database when the transaction occurs, rather than trying to classify transactions after the fact during report generation.
- Validate classification logic thoroughly. Incorrect transaction type assignment will produce inaccurate reports and may trigger queries from tax authorities.
- Handle schema variations. Some jurisdictions may define additional or different transaction type codes. Build your XML generation logic to be configurable per jurisdiction.
Need help with DAC8 reporting?
Our team handles XML generation, TIN validation, and submission for CASPs across all 27 EU Member States.