iQpay Internal

The power chain

Inclusion vs exclusion

Every InComm offer restricts what members can buy. There are two opposite ways to write that restriction, and the whole platform behaves differently depending on which one an offer uses.

The two models

ModelThe catalog lists…At the registerTag looks like
InclusionItems members can buyItem on the list → approved. Everything else → declined.OREGON1, Fresh-Produce1
ExclusionItems members cannot buyItem on the list → declined. Everything else → approved.X-Alcohol-10262023, X-Tobacco-1, X-BAD-…

Example: the ATF offer is an exclusion offer. Its catalogs list Alcohol, Tobacco, and Firearms. Members can buy anything that is not on those lists.

Who actually decides

Two different systems adjudicate, and they are not the same:

  • At the register: InComm decides. We push our catalogs to InComm, and their authorization system approves or declines each item. Our platform sits out of the transaction entirely; the outcome reaches us afterward, when InComm's redemption webhook arrives and a background job turns it into card events.
  • In the wallet: our scanner predicts. The wallet's barcode scanner calls our own API, which mirrors the catalog logic from our copy of the data. It is a preview, not the register's decision.

How our scanner mirror decides

For each scanned barcode, our API:

  1. Normalizes the barcode: strip the last digit (the check digit), then pad the front with zeros to 14 digits. See UPC format.
  2. Collects the offers on the wallet's funded cards.
  3. Splits each offer's PrimaryCatalog on commas into tags.
  4. Applies one of four rules:
Tag situationRule
All tags plain (no X-)Inclusion. Allow only if the UPC is present and active in one of the catalogs.
All tags start with X-Exclusion. Deny if the UPC is present. Allow if it is absent.
Mixed plain and X- tags on one offerHard error. The platform refuses to adjudicate.
No catalogs at allFall back to the offer's literal PrimaryUpc list.
⚠️
The X- prefix is functionally load-bearing.

The prefix sits on the catalog's tag, not its name, and the tag prefix is the mechanism: the platform decides inclusion vs exclusion by testing whether the tag starts with X-. There is no separate "exclusion" column backing it up, so nothing catches a mistake. Never create an exclusion catalog without the X- prefix on its tag.

How reliable is the wallet scanner?

The scanner reads the same catalogs we push to InComm, from the Upc field in our database (the column a catalog Excel download prints as GTIN_FOR_CATALOG). Every catalog update writes our DB and calls InComm's API in the same operation, so the two sides should stay in sync. Reliability then depends on the path:

PathScanner reliabilityWhy
InComm-adjudicated offers (everything not below)Reliable. Same catalogs on both sides.InComm enforces the catalogs we pushed; the scanner reads our copy of the same lists.
Walmart Submitted offers, at WalmartA guess.Walmart adjudicates with its own submitted list, not by querying InComm's catalog at scan time. We often still enable the scanner here because the preview helps the member more than it misleads.
WM-Managed offers, at WalmartDoes not work.Walmart enforces by fine-line category. We have no copy of that logic.
Walmart cards (promo codes)Does not work. Usually disabled.No catalog exists at all; the promo scope lives inside Walmart.

Even on the reliable path, a few edge cases can still surprise. All are verified in code:

Edge caseDetail
Catalogs onlyThe register also enforces offer windows, clip and purchase limits, and balances. The scanner checks only funded cards' catalogs, so an eligible item can still decline for a non-catalog reason.
Barcode dialectsThe scanner decodes UPC-A, UPC-E, and GS1 DataBar, but the API strips the last digit and pads to 14 no matter what. DataBar and UPC-E payloads get mangled and produce false "not eligible" answers. See UPC format.
Mixed offers on one walletIf one offer is catalog-backed and another is UPC-list-only, the scanner consults only the catalog-backed offers.
TimingThe scanner answers instantly from our DB. Register outcomes arrive later, by webhook, in batches. See Card events.
ℹ️
SecondaryCatalog and SecondaryUpc are never used.

The fields exist on every offer, and zero of our 205 offers populate them. The scanner ignores them too. Treat them as dead columns.

Why we sometimes must use exclusion

Inclusion is tighter control, so why does Nutrition Essentials run on exclusion? Weighted items. UPC codes for weighted items (meat, deli, some produce) differ across stores, so no inclusion list can name them all. An exclusion catalog sidesteps the problem: it blocks the known-bad categories and lets every store-specific meat code through. Any offer that must cover meat, like Nutrition Essentials or the Turkey offer, is exclusion-based for this reason.

Why exclusion offers have a Walmart problem

Walmart's systems cannot enforce our exclusion UPC lists. So an exclusion offer cannot be used at Walmart on its own. There are two ways around it:

  • WM-Managed: Walmart works with InComm and enforces the restriction with its own fine-line category adjudication instead of our UPC list.
  • Either/Or: we pair the exclusion InComm offer with a Walmart promo card and let the member pick a side.

Either way, an exclusion program that is not WM-Managed should run on a minus-Walmart network (typically InComm Full Minus Walmart), so Walmart is not in the retailer set at all. See Programs & organizations.

Inclusion offers have no such problem. Walmart accepts them through the normal Walmart Submitted path. Full detail in The Walmart triangle.

Where the catalogs live

Catalogs are rows in incommcatalogs (about 111 of them). Their items are rows in incommcatalogitems (about 15 million UPCs). The offer references catalogs by tag string, not by foreign key. Items join to their catalog by the local IncommCatalogId, not by InComm's own IncommId. See Database map.

iQpay internal. Do not share outside the company.