A guide to combining, splitting, and flagging sales records for rewards — bundles, commission splits, up-sells, and returns — plus how to preview every change safely with dry-run mode before it touches a single record.
What a record matcher does
A record matcher scans a sales data series for sets of records that fit some criteria — a bundle of products bought together, a single large sale that should be split between two roles, a category a customer hasn't bought before — and generates a corresponding destination record for it. Record matchers always run before points allocation sources, so anything they generate is immediately eligible for normal points allocation.
A source record can feed more than one match, and a match can consume more than one source record — it's a many-to-many relationship, tracked so you can always trace a generated reward record back to exactly which sales produced it (and vice versa).
| Type | Matches on | Produces |
|---|---|---|
| Bundle | A fixed list of SKUs bought by the same participant | One new record per complete set, quantity- and amount-weighted |
| Commission split | Every source record | One new record per configured role, each carrying its share |
| Up-sell | A category not previously sold to this participant | A reward record marking the first sale into that category |
| Return | A return record sharing a transaction id with an earlier sale | No new record — links the two so the original can be invalidated |
Finding & adding one
Open a sales data series and go to its Record Matchers tab, alongside General, Points and Statistics. The tab lists every matcher configured on the series, in the order they'll run.

ScreenshotRecord Matchers tab — existing matchers, and the two controls that drive everything on this page.
+ Add new record matcher opens a two-step wizard. Step one is the same for every type; step two changes shape depending on the type you picked.
- Basic detailsTitle, type (locked once created), an optional destination series (leave as “same series” unless the generated records are conceptually different, like a bundle reward), and how many months back to scan for candidate records.
- ConfigurationThe fields specific to the chosen type — see each type below.

ScreenshotStep 1 — title, type, destination series, and scan window
Matchers run top-to-bottom in the list. A return/reversal-detecting matcher should usually be positioned above the forward matchers (bundles, splits, up-sells) it might invalidate — use the up/down arrows on the list to reorder them.
The four matcher types
Bundle
Rewards a participant for selling a fixed set of products together. List the required SKUs; one matching record per SKU is combined into a single generated record. List a SKU twice if the bundle needs two units of it.
| Field | What it controls |
|---|---|
| SKUs | Comma-separated list required to complete the bundle, e.g. p1,p2,p3. |
| Destination SKU | SKU assigned to the generated bundle record. |
| Destination amount | Fixed amount for the generated record. Left blank, it uses the quantity-weighted sum of the matched records' own amounts instead (see the worked example below). |
| Quantity field | Which field holds how many units a single record represents. Leave as “1 unit” if records always represent a single sale — otherwise pick a custom field (or “Amount”). The same field also carries the completed bundle's own quantity on the record it generates. |

ScreenshotBundle configuration step.

ScreenshotA real bundle matcher — SKUsp1,p2, quantity field mapped to a customquantityfield collected on each sale.
Worked example — quantity-weighted amounts
Three source records exist for participant bob, matched by the bundle1 matcher above (SKUs p1,p2, quantity field quantity):
| Record | SKU | Quantity | Amount |
|---|---|---|---|
| #38 | p1 | 2 | $600.00 |
| #115 | p1 | 2 | $400.00 |
| #116 | p2 | 3 | $300.00 |
Every group needs one p1 and one p2. Record #116 has enough p2 capacity (3 units) to help complete two separate groups, so it gets consumed across both — split by exactly how much of its capacity each group uses:
#382 of 2 units → 100%of $600 + #1162 of 3 units → 66.7%of $300 → bundle1 · qty 2 · $800.00
#1151 of 2 units → 50%of $400 + #1161 of 3 units → 33.3%of $300 → bundle1 · qty 1 · $300.00
Each generated record's own quantity (2, then 1) is written back onto its quantity field, so a downstream report can see at a glance how many bundles a record actually represents — not just its dollar value.
Role-based commission split
Splits a single large sale into several destination records — one per role involved in the deal — each carrying its share of the original amount. Every source record is split at most once by a given matcher.
| Field | What it controls |
|---|---|
| Split ratios | Comma-separated role=ratio pairs, e.g. Sales=0.6,Manager=0.4. Ratios don't need to add up to 1 — each is applied independently against the source record's own amount. |
| Role field | Field on each generated destination record that holds the role name (Sales or Manager, above) from the split ratios. |
| Destination SKU | SKU assigned to the generated records. Left blank, it reuses the source record's own SKU. |

ScreenshotCommission split configuration step.
Destination records default to the same participant as the source record — splitting a sale to a different participant per role isn't currently supported.
Up-sell
Rewards selling into a category a participant hasn't bought from before — encouraging reps to widen what they sell, not just sell more of the same thing.
| Field | What it controls |
|---|---|
| Category field | The field representing product category. A record matches as an up-sell once its category value hasn't appeared in this participant's previous sales within the lookback window. |
| Lookback months | How far back to check for a prior sale in that category before calling it a new up-sell. Defaults to 12 months if left blank. |

ScreenshotUp-sell configuration step.
Return (by transaction id)
Detects a return by matching it back to its original sale via a shared transaction id. Unlike the other three types, it doesn't generate a new record — it just links the two records together, which is enough to invalidate a bundle or split that already consumed the original sale. This is why return matchers should run first (see the reordering tip above).
| Field | What it controls |
|---|---|
| Transaction id field | Field identifying the original sale — typically a custom field holding a unique transaction/order id. |
| Return reference field | Field on the return record holding the original sale's transaction id, if it's stored under a different field name there. Defaults to the same field as above. |
| Return indicator field | Field which, if present and non-blank on a record, marks it as a return. Left as the default, any record with a negative amount is treated as a return instead. |

ScreenshotA real return matcher — matching on theinvoiceidcustom field, with the default negative-amount return indicator.
Running matchers
Matching currently runs on demand: click Run record matchers on the tab, and every active matcher on the series runs in list order, oldest candidate records first. Matched groups become immediately eligible for points allocation.
Selecting matches on a matcher's History tab and clicking Delete manually undoes them — handy for testing or correcting a misconfiguration. It never deletes the underlying sales records, and never reverses points already awarded.
Dry-run mode
Every series has a Points calculation mode, set on its General tab: Manual, Auto, or Dry Run. Dry Run is the safest option while you're setting up or adjusting matchers — nothing gets created or changed. Instead, every matched group and invalidation is written to a preview spreadsheet you can inspect before switching back to a real calculation mode.
The same toggle governs the Points tab's own points-allocation preview and the Record Matchers tab's match preview — each keeps its own separate preview spreadsheet, but both follow the same “nothing real happens yet” rule.
ScreenshotThe confirmation shown before every dry-run scan.
ScreenshotPreview spreadsheet for the worked example above — both groups, their source record ids, amounts, and quantities.
ScreenshotHistory tab —Activematch consuming
ScreenshotGenerated record #114 — its own