iQpay Internal

Reference

Gotchas

The muddy list. Words that carry more than one meaning, fields that lie, and conventions with no schema behind them. Check here before debugging anything strange.

Terminology drift

TrapReality
"Card" means two thingsiQpay card = one clip (CardId). InComm card = a customer (ingenId + PAN). Full page.
"Offer" means two thingsAn InComm offer is the numbered contract at InComm. But half the portal calls products offers: the Send cards wizard, Advanced Offers, and the member's wallet all say offer while handling products. "Send an offer" and "send a card" are used interchangeably, and both send a product. See Products.
"Sponsors" and "Recipients"Portal-only words. Sponsors are organizations; Recipients are members. The code and DB never use the portal words.
Three names, one conceptMenu "Recurring products", page "Create Advanced Offer", code "advanced product". All the same ProductType=advanced row. Full page.
Activity vs Transactions vs RedemptionsOne page, one endpoint, one table (cardevents). The title switches by role; only the Excel export differs (redemptions export filters Purchase/Return/Void).
"Offer type" means two thingsincommoffers.OfferType is InComm's SPEND/DISCOUNT. But product report filters named OfferType actually filter ProductType (original/advanced/marketplace). Same words, different axis.
"Banner" is not a tableBanners live as rows in retailers. The join table incommoffer_x_banner is the only place the word survives in the schema.
"Redeem At" is not a columnThe admin form field Redeem At is stored as products.RedeemOptions.
CardIssuer vs CardIssuerTypeCardIssuer = who mints (incomm, walmart, open_mastercard). CardIssuerType = acceptance scope for open-loop cards. Unrelated fields with sibling names.
"Advanced Offer" vs "advanced product"Same thing. The UI says Advanced Offers, the schema says ProductType = advanced.

Schema traps

TrapReality
The X- prefix lives on the tagExclusion is decided by the catalog's tag, not its name: the platform tests whether the tag starts with X-, and no schema column backs it up. The prefix is necessary on every exclusion catalog's tag. Full page.
Money in centsInComm-facing values are cents: incommoffers.Value = 9200 is $92. Fields named AmountUsd are dollars.
cards.AmountRemoved is not spendIt is the leftover balance clawed back at expiry or deactivation. Real spend is in card events.
No card→program keyRoute through cards → orderproducts → orders → ProgramId.
membereligibilities has no MemberIdMatch on ExternalId.
Catalog items join on the local idincommcatalogitems.IncommCatalogId → local incommcatalogs.Id, not the InComm-side IncommId.
Card data is not in MongoDBcardevents.SourceData is a JSON document stored as text in a MySQL column, which makes people assume Mongo. All card, member, and transaction data is MySQL; the Mongos hold only scraped and reference product data.

Behavioral traps

TrapReality
Empty items[] on a declineNot diagnostic. Unqualified items are never echoed back. Full page.
Pre-July-2025 decline recordsThe code and description fields are swapped in old SourceData. Query both.
PAN looks like an InComm numberiQpay mints it and registers it with InComm. Walmart PANs come from Walmart's processor.
Walmart cards reuse InComm columnsOn CardIssuer = walmart rows, AccountId holds a Fiserv trace number (the processor's reference for that issuance) and SecurityCode holds the EAN. Do not read them as ingenId and CVV. See Trace number in the glossary.
Walmart data is a day lateWalmart redemptions arrive by settlement file, not webhook. Missing "today" is normal.
Clip-deleted orphanTwo overlapping monthly cards on one customer: the old card's expiry can delete the shared clip and everything declines. Careful re-clip required. Full page.
The wallet scanner is a preview, not the verdictInComm decides at the register; our scanner mirrors catalogs only and skips limits, windows, balances, and secondary catalogs. Known divergence table in Inclusion vs exclusion.
A second, inclusion-only scanner endpoint existsThe admin-only per-product ProductScanner endpoint uses a lookup with no X- handling. Nothing member-facing calls it; do not use it to test exclusion offers.
Catalog sync to InComm is one-wayWe push catalogs; pulling InComm's state back is a manual admin action. No scheduled reconciliation exists, so mirrors can drift.
Dead billing surfaces/payments/list is a stub page; the paymentmethods table (BlueSnap) is empty. Real payments run through Stripe invoices.
Albertsons banners share one idAll Albertsons-family banners carry the same InComm retailer identifier, 26471. Do not use it to tell Safeway from Jewel-Osco.
ℹ️
Found a new one?

Send it to Tunc and it gets added here. This page only works if it stays current.

iQpay internal. Do not share outside the company.