Product Bundle Sync in Practice: Mapping Combo Products from WMS to CRM
What This Strategy Solves
Combo products, bundle deals, and multi-SKU kits are everywhere in retail and distribution. In one real project, the customer needed bundle master data pushed from a source system into a CRM so that sales quoting, order entry, and inventory reservation could all recognize the same bundle definition. On paper it looks like a small extension to product master data, but in practice the differences between systems in how they express child items, pricing rules, and whether a bundle can be sold partially are large. This guide walks through one concrete sync strategy and the engineering decisions behind it.
Data Flow and Field Mapping
The overall path is: source extraction → intermediate mapping → target write. Keep the three stages separated; do not collapse them.
| Aspect | Source side (bundle definition) | Intermediate layer (mapping/cleansing) | Target side (product bundle) |
|---|---|---|---|
| Primary key | Source product code | Centralized code mapping, not scattered across scripts | Target product code |
| Type flag | Bundle vs. simple indicator | Normalize to a binary value (BUNDLE / SIMPLE) | Target product type field |
| Child lines | Child SKUs and quantities | Expand into line-item structure, validate quantity > 0 | Target bundle detail rows |
| Pricing | Bundle price, suggested retail price | Pick which tier to push per business rule | Target price field |
| Status | Active / discontinued | Only push active records | Target enabled flag |
Centralize the code mapping. The classic blow-up we have seen on-site: each engineer maintains their own mapping file, three months later the numbers no longer match on either side, and it takes a full week to reconcile.
How to Configure It on Qeasy
We used the Qeasy data integration platform to deliver this strategy. It is easier to explain in four blocks.
1. Source collector Select the "bundle" data scope, and use "last modified time" as the incremental filter. For the first onboarding, pair it with a one-time full backfill. Split bundles and regular products into two separate collector jobs so a single pull does not time out.
2. Intermediate mapping Maintain the field mapping inside a Qeasy transformer. Bundle-specific handling points:
- Call the source detail interface (or parse the nested payload) to expand child lines before mapping;
- Normalize type via a small dictionary table (e.g., "bundle → BUNDLE, simple → SIMPLE") rather than hard-coding values in scripts;
- Trim price fields per business rule, e.g., push only the bundle price, not the suggested retail price.
3. Target writer Distinguish header from lines: write the bundle header once, then write each child line. Make the order and transactional boundary explicit in the configuration, otherwise you will end up with "header exists, lines missing" dirty data.
4. Exception handling Records that fail at mapping or writing go into a single exception queue on Qeasy for manual replay or rework later.
Implementation Steps
Roll this out in three phases; staged rollout is far safer than a single big-bang.
Phase 1: Incremental start Start with "bundles updated in the last 7 days" to validate the pipeline. The goal here is to verify field mapping and child expansion logic, not to be exhaustive. Get the pipeline stable first.
Phase 2: Full backfill trigger Once the pipeline is stable, manually trigger a full backfill to cover historical bundles. After it finishes, sample-audit: randomly pick 20 bundles and compare child counts, bundle price, and status between source and target.
Phase 3: Steady-state scheduling In steady state, we recommend a dual-track schedule: incremental every 15 minutes plus a full reconciliation once per day. Incremental covers freshness; the nightly full pass repairs anything the incremental missed. This dual-track pattern is very common among Qeasy customers: incremental for the day, full backfill as a nightly self-check.
Lessons Learned
Pitfall 1: Bundles with zero child items still get pushed. Some "bundles" in the source only carry a flag and have an empty child list. Pushing them as-is produces hollow bundles that break downstream order entry. The safe pattern: add a check in the intermediate layer and route any record with child count ≤ 0 to the exception queue; do not write it to the target.
Pitfall 2: Bundle and child codes do not align. In the source the bundle code is A, but the children use codes like A-1, A-2. If mapping only aligns the parent code, the children silently disappear. Always treat the parent-to-child relationship as one unit during mapping.
Pitfall 3: Discontinued bundles get revived downstream. If the status field is missing or wrong, the target system can resurrect bundles that were already discontinued. Map the status field explicitly and treat "discontinued" as a hard blocker.
Pitfall 4: Header succeeds, lines fail, transaction not closed. Bundle writes are classic header-plus-line structures. If the header commits but the lines fail, the target ends up with "header but no lines" dirty data that is hard to roll back. Wrap header and lines in the same transactional unit in the configuration.
Pitfall 5: Full backfill and incremental run concurrently and fight. A full backfill is half-done when an incremental kicks in, both modify the same bundle, and they overwrite each other. The safe pattern: pause incremental during the full window, or add a distributed lock around the full job.
When This Fits, When It Does Not
Fits: Retail or distribution scenarios with thousands to tens of thousands of bundles, frequent child-line changes, and strict code-consistency requirements.
Does not fit: Scenarios with only a handful of bundles whose child relationships can be maintained manually; also avoid bundling "bundle sync" and "price sync" into the same strategy, since failures become much harder to diagnose.