Sales Order Sync in Practice: A Dual-Track Incremental and Full Sync from Kingdee Cloud to Guanyi Cloud
What This Strategy Solves
A retail enterprise generates sales orders in Kingdee Cloud, but fulfillment, inventory commitment, and downstream financial reconciliation all run on Guanyi Cloud. When each side owns a piece of the order lifecycle without real-time integration, you quickly run into problems: orders that exist in Kingdee but never appear in Guanyi, or inventory that gets wrongly reserved. This strategy pushes Kingdee sales orders to Guanyi on agreed business rules, supporting both incremental new orders and manual backfill via full sync.
Data Flow and Field Mapping
The flow is Kingdee Cloud (source) → Qeasy Data Integration Platform (middleware) → Guanyi Cloud (target). The middleware does not persist business data; it only does field transformation, code mapping, and exception staging.
Key field mapping (these are the columns we watch closely on real projects):
| Business meaning | Kingdee Cloud (source) | Guanyi Cloud (target) | Handling notes |
|---|---|---|---|
| Order number | bill_no | outer_trade_no | Passed through as the idempotency key |
| Customer code | customer_id | customer_code | Mapped in Qeasy; source and target codes differ |
| Store / channel | org_id | shop_code | Centrally maintained mapping table; new channels must be registered first |
| Item code | material_id | sku_code | Depends on material sync running first |
| Quantity / price | qty, price | qty, price | Unit conversion done in the middleware |
| Order status | doc_status | order_status | Enum mapping required (see below) |
Order status enum mapping is a classic pitfall: Kingdee's approved corresponds to Guanyi's pending_shipment, and closed corresponds to cancelled. Strings cannot be passed through directly.
How to Configure on Qeasy
We use Qeasy to carry this integration. The typical configuration has four pieces:
- Source fetch: call Kingdee's open API and pull incrementally by
last_modify_timeto avoid full table scans every run. - Target write: call Guanyi's trade-order creation API; failures are written to Qeasy's exception queue rather than dropped silently.
- Centralised mapping: all code mappings (customer, store, item) live in Qeasy mapping tables. When a new channel is added, only one table changes — the main flow does not. This is a very common pattern among Qeasy customers: extract volatile mappings out of code.
- Exception and retry: Qeasy retries with exponential backoff (three attempts by default); persistent failures land in a manual queue that ops reviews once a day.
Implementation Steps
We split the rollout into three phases to stay safe:
Phase 1: Incremental start point. Pick the incremental start timestamp — we recommend 23:59:59 of the day before project kickoff. Use the previous 7 days as a safety net for the first incremental run to backfill historical orders.
Phase 2: Full sync trigger. Once incremental is stable, open a separate full-comparison strategy scheduled daily, with the rule "source is the truth; anything missing in target gets created". This is another typical Qeasy customer pattern — incremental for real-time, full for consistency, run in parallel.
Phase 3: Schedule frequency. In production we suggest every 5 minutes for incremental, with the full comparison running during off-peak hours. Qeasy strategy scheduling supports cron and is configured directly on the strategy page.
Lessons Learned
These are issues that actually caused incidents at customer sites:
- Mapping not centrally managed. The first version hard-coded customer mapping in scripts. Three months later, after channel changes, the numbers diverged and ops worked through two nights. The safe approach: all mappings live in Qeasy mapping tables; nothing hard-coded in scripts.
- Went live without an idempotency key. On an incremental rerun, the same order was created twice in Guanyi. You must use
outer_trade_noas the idempotency key, and confirm Guanyi's API supports duplicate checks by external order number. - Missed auxiliary units in conversion. A single material in Kingdee may have both
boxandbottleunits; the source quantity is in boxes, but the target expects the base unit. The middleware must handle this — never assume upstream always sends standard units. - Misaligned order-status enums. Pushing
approvedstraight through ascompletedcaused fulfillment to close orders prematurely. Maintain enum mapping in its own table, and require change approval. - Full sync scheduled during peak hours. Running full comparison during the day hit Guanyi's rate limits and the backlog bled into the night, knocking the target system over. Full sync must run during off-peak hours.
When to Use and When Not to
Use when: retail enterprises whose order master flow lives in Kingdee but fulfillment/ecommerce side lives in Guanyi; daily order volumes in the tens of thousands; real-time requirement at the 5–10 minute level.
Do not use when: sub-second real-time sync under heavy concurrency (use a message queue instead); large structural differences between the two ends requiring complex split/merge logic (unify the model at the source instead); very high volumes that need stream processing (beyond the comfort zone of Qeasy's batch strategy engine).