The power chain
Programs & organizations
A program is one client benefit: a set of products, a member population, and billing rules. An organization owns programs.
The hierarchy
Numbers to hold in your head: about 117 organizations, about 345 programs, and about 886 products exist in production. The portal calls organizations Sponsors and members Recipients; the code and database never do.
Networks: where the cards work
Every program picks a network (programs.NetworkId): the named set of retailers where its OTC cards work. About 66 networks exist. They come in three families:
| Family | Production examples | Used when |
|---|---|---|
| Full network | InComm Full Existing Offers Network | Inclusion offers. Walmart is part of the OTC Network for these. |
| Full minus Walmart | InComm Full Minus Walmart (the most-used network, about 65 programs) | Exclusion offers that are not WM-Managed. Exclusion does not work at Walmart, so Walmart is removed from the retailer set. See The Walmart triangle. |
| Restricted | Kroger Exclusive, Albertsons Only, Incomm Full OTC (MA), InComm Full PLUS Walgreens | The client wants specific retailers or a regional footprint. |
Inclusion catalogs → a full network. Exclusion catalogs → a minus-Walmart network. Picking a full network for an exclusion offer leaves Walmart in the retailer set even though exclusion cards cannot adjudicate there.
Program fields that matter
| Field | Values | Meaning |
|---|---|---|
PaymentType | postpay_invoice · prefunded | Whether the client pays after spend or funds in advance. Most programs are postpay. |
CardSendLogic | by-text-preferred · by-text · by-email-preferred · by-email · by-webhook | How members receive their cards. |
FeatureType | original · marketplace | Normal program, or a marketplace program. Marketplace is defunct: we no longer use the concept. The data and portal pages remain, so you will still see owner and subscriber rows. |
MarketplaceType | none · owner · subscriber | Only meaningful on legacy marketplace programs. |
MaxCardsPerMember | number | Order-time cap on live cards per member in this program. |
AutoClipOnPhysical | bool | When on, recurring sends auto-clip for members who already activated a card. See The clip lifecycle. |
Status | active · inactive | Whether the program is live. |
Program money
Program funds live in four places. Do not mix them up:
| Where | What it holds |
|---|---|
programs.TotalCurrentBalance (+ budget, credit, limit columns) | The current balance state, plus all fee configuration (FeeSetupUsd, FeeCardFixedUsd, FeeMaintenanceUsd, ...). |
programbudgettransactions | The append-only movement ledger. Every balance change is a row carrying the running balance. "Adjust Balance" in the portal writes two offsetting rows. The balance can be rebuilt by summing this table. |
programbudgetoffersvalues | One rollup row per program: offers sent, activated, redeemed, expired, outstanding value, fees. The portal's "available balance" subtracts terms from here. |
invoices + payments | The billing side, Stripe-integrated. Prefunded programs are topped up through invoices with type prefunding (the org sees this as "Manage credits"). |
The journals table is not money. It is the change-audit log (who changed what, with before/after JSON) written automatically for every entity change.
Members join programs, not offers
A member belongs to an organization (members.OrganizationId). A programmembers row enrolls the member into a program with a product. How they got there is recorded in EligibilityProcess:
bulk_upload: the client sent a roster file.self_registration: the member signed up.api_driven: the client's system called our API.manual: someone added them in the portal.
A member can also sit in member groups (membergroups), which can carry their own product entitlements. Groups are used for cohorts inside one organization, for example school groups in a district program.
Orders connect everything
When a program sends cards, the platform creates an orders row (who: member, program, organization) with orderproducts rows (what: product, amount, date window). Every card points back to its orderproducts row. That is how you get from a card to its program in the database: cards → orderproducts → orders → programs. There is no direct card-to-program key. See Database map.