Qeasy Cloud
Get Started

Syncing Sales Orders from Xiaoman OKKICRM to KIS Private Cloud: A Single-Strategy Tutorial

· 王浩宇· Integration Solutions· 3 views· 4 min read
KIS私有云小满OKKICRM销售订单同步轻易云数据集成供应链集成Field Mapping

What This Strategy Solves

Sales orders are among the most sensitive business documents. In one retail engagement, sales reps enter and approve orders in Xiaoman OKKICRM on the CRM side, while the ERP side (KIS Private Cloud) needs the same orders for inventory pre-allocation and downstream fulfillment. Once encodings, semantics, or time windows drift between the two, finance and warehouse figures stop reconciling within three months. We use the Qeasy data integration platform to consolidate this pipeline into a single observable, replayable, phased sync strategy whose sole job is: sales orders in Xiaoman land in KIS via the target API, scoped by a business time window, with no duplicates and no losses.

Data Flow and Field Mapping

The overall flow is Xiaoman OKKICRM (source) → Qeasy middle layer (orchestration + mapping + idempotency) → KIS Private Cloud (target). The source uses a GET query API, the target uses a POST write API, and authentication is handled by each system's own credentials — the middle layer only orchestrates.

Key field mapping (excerpted from production configuration):

DimensionSource (Xiaoman)Middle LayerTarget (KIS)
Business order no.order_no (idempotency key)Pass-throughObject.id (reconciliation key)
Line item primary keyorder_idCompose line numberObject.entries[].id
Query time windowstart_time / end_timeTake LAST_SYNC_TIME / CURRENT_TIME—
Paginationstart_index, count=10Loop, aggregate, then dispatch—
Soft-delete filterremoved=0Default: only non-deleted; =1 goes to compensation channel—
Write endpoint——POST /koas/app007099/api/salesorder/create
Account-set isolation——AccountDB carried as a request field

We centralize encoding mapping: a Xiaoman product/customer code → KIS code mapping table lives in Qeasy's Mapping Center. At execution time, the strategy looks up by primary key instead of embedding mapping logic in every request. Later, when either side changes its encoding, you change one table.

How to Configure on Qeasy

In the Qeasy console, this strategy is configured in four blocks:

  1. Source connector: Choose Xiaoman OKKICRM, supply app credentials and the query API /v1/invoices/order/list, method=GET, pagination fields start_index / count.
  2. Target connector: Choose KIS Private Cloud, endpoint /koas/app007099/api/salesorder/create, method=POST, configure AccountDB as a "fixed parameter + variable concat" so it is not repeated on every request.
  3. Field mapping: Map source flat fields into the target's nested Object. The header/body split is the critical part — header fields go to Object.*, line items go to Object.entries[], and in the mapping panel enable "array expansion".
  4. Filter and idempotency: Enable idCheck on the source side; the middle layer deduplicates on order_id; before write, do an existence check on the target side using the business order number id to avoid duplicates.

Implementation Steps

We split the schedule into three phases — incremental seed → full reconciliation → steady-state incremental:

  • Phase 1: Incremental seed (cold start). Trigger one manual run in Qeasy, initialize LAST_SYNC_TIME to the required historical seed (e.g., 00:00 on go-live day), and pour in a batch of historical orders. The goal of this phase is to flatten history in one shot, not to let it mix with the daily schedule.
  • Phase 2: Full reconciliation (validation). Run a full sync during off-peak hours and reconcile against KIS manually. We once hit a phantom case where "both sides matched but line counts differed by one" — the root cause was the source collapsing merged rows into one while the target required per-SKU expansion. This phase is a regression test for encoding mapping and line-split rules, and should not be skipped.
  • Phase 3: Steady-state incremental (routine). Source schedule 0-59/20 7-22 * * * (every 20 minutes during business hours); target writes staggered at 2-59/45 7-22 * * * (starting 2 minutes past the hour, every 45 minutes). The stagger prevents both ends from contending for the same network segment and target connection pool when pulling and writing simultaneously.

Pitfalls and Lessons

  1. Do not flatten header and body into one mapping sheet. Early on we spread all fields flat and ended up only capturing the first line item. The safe approach is two sub-sheets: header 1:1, body 1:N, explicitly assembled in the middle layer as Object.entries[].
  2. Do not hard-code the system clock for the time window. start_time / end_time must use Qeasy's LAST_SYNC_TIME / CURRENT_TIME variables, calibrated to the source's timezone — otherwise you lose or duplicate orders across day boundaries.
  3. The default removed=0 is a double-edged sword. Daily jobs only see non-deleted orders, but if a "delete-then-recreate with the same order number" event happens inside the sync window, incremental will miss it. Open a compensation channel: run a low-frequency job that pulls removed=1 and does diff reconciliation.
  4. Do not be greedy with page count. The source's default is count=10. In practice, beyond a threshold the source sporadically times out — the middle layer must keep retries and a resume point (continuing from the last start_index).
  5. idCheck on the target side is the last gate. Even if the middle layer already deduplicates, the target API's idempotency key (id) must be re-checked before write; otherwise, concurrent runs produce duplicate orders.

When to Use and When Not to Use

Use when: orders are created in a CRM/e-commerce front end and fulfilled by an ERP back end, you need a "trusted order flow" between them, and both sides allow time-window querying plus idempotent writes. Do not use when: the source offers no time-window query (only full scans), the target has no idempotency key, or order volume is so small that a middle layer is overkill — in those cases, a direct API connection is enough, and introducing Qeasy only enlarges the failure surface.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-kis-okkicrm-6426-kis-a684620f

Comments