AI Adoption GuideBankingTransact
Merchant category enrichment
ML classifies raw merchant strings to standardized MCC codes, enabling spend analytics, personalized offers, and regulatory reporting.
Banking processAcquireOnboardOpenFundTransactServiceReviewClose
By Don, DoneThat’s AI coach · updated
What a defensible MCC record contains
A quality enrichment result is a four-digit merchant category code, a cite to the exact acquirer string you classified, and the identifier of the rule or model version that produced the code. If the string is unreadable, leave the MCC empty. Empty is the correct quality outcome. Filling a blank with a convenient bucket is not.
The cite is what makes the code usable for spend analytics, offer targeting, and regulatory reporting. Without it, an analyst cannot tell whether 5812 came from a readable restaurant descriptor or from a truncated POS fragment. The version stamp is what lets you replay a prior clearing file when a mapping table or model checkpoint changes.
Store those three fields on the posting: MCC (nullable), raw_merchant_string, enrichment_version. Optional extras that help ops without changing the quality bar: parse tokens, confidence, and whether a human confirmed the code. Do not store a "default MCC" for failed parses.
Do not treat the MCC as a credit attribute. It describes the merchant on this posting. It does not score the cardholder, and it does not authorize or decline the card.
Parse the acquirer string before you classify
Raw merchant descriptors are concatenated acquirer fields: doing-business-as name, sometimes a city or phone fragment, sometimes a processor prefix, often cut at a fixed length. Parse first. Strip known prefixes such as SQ , TST, PAYPAL *, and AMZN MKTP. Drop location and phone tokens that are not the merchant. Keep the residual name you will actually map.
Illustrative example: the clearing file shows SQ *BLUE BOTTLE 415-555. After parse you hold merchant token BLUE BOTTLE, a Square prefix as channel context, and a phone fragment that is not an MCC signal. You classify the token, not the digits. You persist the original uncleansed string next to whatever code you assign. If your dictionary maps BLUE BOTTLE to 5812 (eating places and restaurants) at high confidence, write 5812, cite SQ *BLUE BOTTLE 415-555, and stamp the dictionary version. If the name is not in the dictionary and the model is below threshold, write no MCC.
If parse yields nothing usable (POS ****, MERCHANT, replacement characters, or a garbled encoding), stop. Do not guess. The highest-risk guess on a blurry string is cash or ATM (commonly 6010 or 6011) because those codes look complete in ops dashboards. They recast an unknown merchant as cash, which distorts spend mix, can suppress or enable the wrong offers, and can feed monitoring rules that were never meant to fire.
Map to MCC and keep low confidence uncoded
Mapping is a dictionary lookup plus, where you use it, a model score. It is not a mandate to fill every row. Exact or normalized DBA hits against a published MCC table get a code, the raw-string cite, and the dictionary version. Scores below your threshold stay uncoded. Uncoded is a first-class state: category rollups exclude those rows or park them as uncategorized with cite, regulatory reports do not dump them into cash or gambling residuals, and operations can sample them later.
Low confidence is not an instruction to pick the nearest MCC. Nearest still writes a false category into history.
Publish a short decision table your ops team can audit: dictionary exact match, dictionary fuzzy match above threshold, model above threshold, else empty. Record which branch fired. That branch identifier is part of the version cite, not a second competing code.
When a later dictionary or model version recodes a merchant, apply the new code to new postings only unless you run an explicit, audited restatement. Silently rewriting last year's 5411 grocery codes to 5499 because a vendor refresh shuffled a chain is a failure mode. It breaks trend reports, offer lookbacks, and any annual review document generation that reprints a customer's spend mix as if the past had always used today's table.
Human review for gambling, cash, and other regulated codes
Some MCCs are not only analytics labels. Gambling, money transfer, cash-like, adult, and similar codes can change reporting duties, offer eligibility, and enhanced monitoring. Route a proposed code to a human when confidence is low, when the merchant string is new, or when the proposed code would move the merchant across a regulatory boundary. Do not invent 7995 or any gambling code, and do not invent a cash code, when the string is ambiguous, even if the DBA contains a word that often appears in those categories.
Reviewers see the raw string, the parse, the proposed MCC, the confidence, and the rule or model version. They confirm, reject to empty, or assign a different published code with a reason. A hotel whose DBA includes "casino" is not automatically gambling. A convenience-store string is not cash. Ambiguity resolves to empty, not to the regulated bucket that feels safest for compliance optics.
This queue follows the same operational pattern as dispute pre-triage automation: the model proposes, a person owns the regulated edge, and the system keeps the cite.
Write cited codes into core banking and CRM without a second map
Persist the MCC, the raw-string cite, and the version on the transaction record your finance and payments-ops teams already trust. Core banking platforms such as Temenos and CRM platforms such as Salesforce are destinations for that cited code. They are not a place to maintain a second, undocumented merchant map that diverges from the ledger.
Campaign and case objects may display the category. They must not recode it. A Salesforce campaign that regroups merchants for a product push is a marketing view. It must not overwrite the posting's MCC. A Temenos posting extract that feeds finance must carry the same cite the enrichment job wrote, not a rebuilt category from a local spreadsheet.
When you retrain or refresh mappings, version the artifact, record the effective date, and leave historical postings on the code that was valid when they cleared, unless a documented restatement says otherwise. A string that was unreadable yesterday stays empty until a human or a new, versioned rule can defend a code.
Is this worth automating for you?
Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.
DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.
Measure the baseline first