Platform internals
UPC format
Every UPC inside the InComm side of the platform lives in one normalized shape. Learn the rule once and half the catalog bugs disappear.
The rule
That is the whole rule.
Worked example with a retail barcode:
On-pack barcode (UPC-A, 12 digits): 0 41303 01893 5
Drop the last digit (check digit): 0 41303 01893
Pad the front with zeros to 14: 00004130301893 ← InComm space
This is exactly what the platform does to every scanned barcode before catalog lookup: strip the last digit, pad left to 14.
Where each shape appears
| Field | Shape |
|---|---|
incommcatalogitems.Upc | InComm space: 14 digits, no check digit. |
incommcatalogitems.OnPackUpc | The barcode as printed on the package, with its check digit. |
cardevents item code | InComm space: 14 digits. |
Comparison rules
- InComm to InComm: compare directly. Both sides are already in the same space.
- InComm to the outside world (Nielsen, scrapers, retailer feeds): never compare by slicing digits. Those sources carry true barcodes with check digits, in several lengths. Prefer matching check-less value to check-less value when the external source has a well-populated no-check-digit field.
- Never hand-compute check digits to force a match. A check-less 12-digit value can look like a UPC-A and not be one.
Reference databases often carry a computed gtin14 field for items that were never printed as a 14-digit code, especially produce. What we measured in July 2026: fewer than 1% of those synthetic values ever appear as a real scanned barcode in the reference data, so pushing them mostly creates catalog rows no UPC-A scan will match. Prefer the real on-pack barcode minus its check digit.
The open question: some registers transmit GS1 DataBar, which does carry a full GTIN-14. A synthetic GTIN-14 could match those scans. We do not have hard evidence either way yet, so treat synthetic values as low-yield rather than forbidden, and prefer the on-pack form when both exist.
Register reality check
Not every scan at a register is a UPC-A. Random-weight items arrive as price-embedded type-2 codes (for example 0002IIIII00000 shapes with a zeroed price). Some registers send GS1 DataBar with a full GTIN-14 inside. When the wallet scanner and the register disagree, the barcode dialect is the first suspect.