You want to build a subscription manager, a spending overview, or an affordability model, and the transaction feed hands you a terminal string. Six fields, most of them abbreviated, one of them a shop name that reads like a licence plate. Either you are blocked before launch because none of it renders cleanly, or you shipped anyway and the feature underperforms because half the merchants come back unrecognisable.
This article explains what those six fields give you and what two separate operations, cleansing and enrichment, each add on top.
The feature that stalls at the transaction feed
A card feed gives you a fixed set of raw fields for every transaction: a terminal identifier (posID), a merchant ID, a merchant description, city, country, and an MCC. That is the input. It is enough to record that money moved and to place the transaction on a statement. It is not enough to tell a user which shop they paid, or to group that payment with the other times they paid the same brand.
Two positions are common at this point. The first is blocked before launch: the feed arrives, the strings are unreadable, and the feature cannot ship on top of them. The second is live and underperforming: the app renders TESCO LDN HTRW as-is, users half-recognise it, and the subscription detection misses recurring charges that hide behind a payment gateway. Both come from the same root. The raw fields describe a transaction. They do not resolve an identity.
Given those six fields, what does cleansing do to them? What does enrichment do to them, and which one does your feature actually depend on?
Three transaction sources, three different starting points
Before either operation runs, the amount of raw material differs by where the transaction came from.

Card payments are the richest starting point. Full card data provides nine useful input datapoints for identifying the terminal behind a transaction, according to Tapix analysis of open banking versus card data. That is the best case: the merchant description, terminal and merchant IDs, MCC, and location fields all arrive together.
Open banking is thinner. The same analysis finds open data typically carries two useful datapoints and practically never more than four. A feature that resolves merchants accurately on card data will degrade the moment it runs on an open banking feed, because there is simply less to work from. Same logic, less input, lower hit rate.
SEPA and other bank transfers are different again. There is no terminal here. What arrives is an IBAN, an account name, and a free-text reference. A transfer string such as DE04300700100270704000/VF GMBH resolves to Vodafone, with a logo and a category attached, but only if something reads the account name correctly and matches it to a known merchant. Transfer standards also differ by market, so the parsing work is one template per country.
What cleansing does
Cleansing breaks down a raw string into standardised fields. It takes the single line the bank sends and splits it into named columns: merchant description here, city there, country in its own field.
Take a real card string: PAYPAL *DISNEYPLUS; 35314369001; NLD. A remittance-info regex splits it on the semicolons and populates three fields. Merchant_description receives PAYPAL *DISNEYPLUS, country receives NL. And city receives 35314369001.
That last one is the honest outcome. The regex did its job. It matched the pattern and filled every field. But the third segment was never a city; it was a phone number, and the parser had no way to know that. Cleansing gives you structure without meaning. The fields are populated, correctly split, and one of them holds a phone number labelled as a place.
This is the layer most in-house builds reach and stop at. Split the string, standardise the columns, ship it. It is real work and it is necessary. It is also where the transaction is still just a string that has been tidied up, not a payment whose merchant and shop are known.
What enrichment does
Enrichment resolves the cleansed fields to an actual identity, and that identity has three levels. A merchant owns shops. A shop has terminals or a payment gateway. A terminal carries a single identifier. Keeping these three distinct is the whole point.
At the merchant level you get the exact brand name and a high-resolution logo. At the shop level you get the individual outlet: its address, GPS coordinates, Google Places ID, website, category and store-level tags. Enriched data for one payment combines both. Cleansing returned the string TESCO PRAHA EDEN; resolution returns Tesco the merchant, and the specific Tesco outlet in the Eden centre, distinct from the registered head office and from every other Tesco in the country.

Work it on the PayPal example. Cleansing gave you PAYPAL*DISNEYPLUS in the merchant field. Enrichment reads that correctly: PayPal is the gateway the money passed through, Disney+ is the merchant behind it. The gateway is not the shop. Without that distinction, a subscription manager files the charge under PayPal and never spots that it is a recurring Disney+ payment.
The same care applies to sub-brands and franchises. Marks & Spencer and Marks & Spencer Foods are not the same merchant. Amazon and Amazon Prime are not the same merchant. A store inside a shopping centre is a shop in its own right, resolved to the outlet rather than the brand's registered office.
Categorisation follows the same principle. Instead of inheriting the merchant's MCC, enrichment assigns a category at transaction level: 25 main categories and over 530 store-level tags, set against roughly 600 flat MCC codes that were built for scheme reporting rather than for describing what a customer bought. The MCC tells you a rough industry. The store-level tag tells you the shop.
How the data stays accurate
Identity resolved once is a snapshot, and merchants do not hold still. They move premises, rebrand, and reassign terminals to new locations. A resolution that was correct at launch doesn’t hold up afterwards unless something maintains it.
The decay is measurable. Terminals have a lifetime of three to four years, which means roughly a quarter of them are reassigned every year, as Tapix's shift from manual cleaning to automated enrichment states. Around 8% of merchant logos change annually. A terminal moving from a closed shop to a new occupant is the routine case. If your resolution logic treats identity as fixed, one transaction in four is drifting toward wrong within a year.

Two mechanisms answer this. The first is invalidations: rather than reprocessing the entire history, the client is told which specific records changed, and only those are refreshed. The second is a feedback loop: when a user reports a wrong name, logo, or location, that report feeds back and the record improves. Underneath both, the classification model suggests and a human reviews and approves, so corrections are checked rather than trusted blind.
The point is not that these are API features. The point is that accuracy is not a property you achieve once. It is a property you maintain against a merchant environment that changes every week, and a resolution layer without a maintenance mechanism is accurate only on the day it launches.
From clean data to a transactional data foundation
Once transactions are resolved and maintained, the enriched layer stops being one feature's private input and becomes something several teams read from. Enrich once into the warehouse, then serve every system from there.
Product reads it for transaction history, spending overviews, and subscription management. Risk reads the labelled income and spending signals for creditworthiness scoring. Marketing reads category-level and merchant-level segmentation. Dispute management reads shop identity to answer the recognition question at source, because most disputes start with a customer who did not recognise a charge.
What a shared foundation removes is duplicated logic. Without it, every team rebuilds its own merchant-matching, its own categorisation, its own idea of what counts as a subscription, and the four versions disagree. One enriched layer, read by all of them, is the difference between a data foundation and four parallel workarounds.
What this means for the build decision
Ask three questions. Does the feature need shop-level identity behind gateways and across borders, or is a cleaned-up merchant name enough? Does it need accuracy that holds as merchants move and rebrand, or accuracy that is fine at launch and drifts after? And when the data is wrong, does the team need a correction path, or is a support ticket acceptable?
If a spending overview only ever labels merchant strings, cleansing may carry it. If a subscription manager has to see Disney+ behind PayPal, or an affordability model has to distinguish a grocery run from a betting site, the feature depends on resolution, not just structure. You now have enough to tell which one you are building.
You can test the difference on your own transactions in the Tapix sandbox.