Sales Return Order Sync in Practice: A Single-Strategy Implementation from WMS to Kingdee
What This Strategy Solves
In ToB businesses, syncing sales return orders from online channels back to the ERP is the most underestimated piece of supply chain integration. In one real project, a retail enterprise initially only synced sales outbound orders. Return orders were entered manually on both sides. Three months later, when the accounts did not match, they found the WMS held over 120 return orders while the ERP only had 60. The root cause: nobody owned the dedicated "sales return order query" strategy.
The value of this strategy is straightforward: pull the WMS's return stock-in orders on a fixed cadence (every hour at minutes 24 and 54 in the source material), then write them into Kingdee Cosmos/Star, forming a traceable return archive. Automation here is not just about saving labor — it is about keeping the document numbers, dates, warehouses, and shop codes aligned on both sides.
Data Flow and Field Mapping
The overall chain is unidirectional A_TO_B: source system (Wangdiantong flagship Qimend) → Qeasy data integration platform as the orchestration layer → target system (Kingdee Cosmos/Star).
The source side calls a query-type API wdt.wms.stockin.refund.querywithdetail, POST method, with order_no (stock-in number) as the idempotency key, and both pagination and business parameters wrapped inside a params object. The target side writes via the batch-save API batchSave, also POST, with FBillNo as the primary key id, and idCheck enabled to prevent duplicate writes.
Key field mapping (desensitized):
| Source field (Wangdiantong) | Target field (Kingdee) | Notes |
|---|---|---|
order_no | FBillNo | Stock-in number, idempotency key |
check_time | FDate | Audit date, converted via {{check_time|dateTime}} |
warehouse_no | Fwarehouse_no | Warehouse code |
shop_no | Fshop_no | Shop code |
details_list (line items) | FEntity (document body array) | Lines expanded as array |
status | (mapped by business rules) | Status is not directly mapped, handled by business logic |
How to Configure on Qeasy
In the Qeasy data integration platform, this strategy typically lives under an "Integration Strategy" node, named by business module for easy retrieval. Key configuration points:
First, centralize code mapping. Warehouses, shops, and customers are master data. A common practice among Qeasy customers is to maintain a separate mapping table (or even a dedicated master data sync strategy) instead of hard-coding in each strategy. Fwarehouse_no in the return order must be mapped first; otherwise, internal source IDs will not match Kingdee's warehouse archives.
Second, handle header and body in stages. The header should be deduplicated by order_no and skip existing records. The body FEntity is expanded from the details_list array and written line by line. The "header-body staged" pattern in Qeasy is practically standard for return scenarios, because returns frequently follow a "header first, lines later" two-step process.
Third, separate request parameters and response mapping. The source request only carries pager and params. The target request injects response fields through template variables like {{order_no}}, {{check_time|dateTime}}, and {{details_list}}. Setting autoFillResponse=true exposes response fields to downstream mapping, which is very convenient during debugging.
Fourth, be cautious with crontab edits. The source defaults to 24,54 * * * * (twice per hour), while the target crontab reads 1 1 1 1 1. This looks disabled but is actually Qeasy's placeholder for "manual trigger only"; in production it relies on upstream events or manual triggers, and should not be changed to a high frequency.
Implementation Steps
Step 1: Confirm the incremental starting point. In Qeasy, set the starting cursor for order_no, ideally seven days before the last manual reconciliation date to leave a buffer. A typical pitfall is setting it to "full" — the first run then pushes years of historical return orders, causing errors or data bloat on the target.
Step 2: Trigger a one-time full sync. Run only at project go-live or when discrepancies are large. After completion, archive logs immediately, verify document counts match on both sides, then switch to daily scheduling.
Step 3: Daily scheduling uses an "incremental + scheduled" dual track. Incremental is driven by source timestamps; scheduled runs follow the source crontab twice per hour. A common robust pattern among Qeasy customers is: scheduled runs as the safety net, incremental runs for speed, both sharing the same deduplication table.
Step 4: Isolated queue for abnormal documents. Documents that fail mapping or required-field validation go into a quarantine queue — never let one dirty record block the whole batch.
Pitfall Retrospective
-
Going live without enabling idCheck. Duplicate
order_norecords pulled from the source create N duplicate return archives on the target. The safe approach isidCheck=truecombined withidbound toFBillNo, performing a primary-key check before any write. -
No template conversion on date format. The source
check_timemay be a timestamp or string, while Kingdee requires standard datetime. The source material uses{{check_time|dateTime}}— seemingly trivial, removing it causes failure. -
Raw warehouse/shop code transmission. Source internal IDs and Kingdee's archive IDs are two different systems. Passing
{{warehouse_no}}directly without mapping almost certainly results in "warehouse does not exist" errors. -
Forgetting to expand the body array.
details_listis an array and must be replaced wholesale via{{details_list}}in the template. Do not pick the first element outside a loop, or multi-line returns will only land the first line. -
Accidentally setting crontab to high frequency. The 24/54 minute cadence is intentional — it avoids peak-hour query spikes on the source. Changing it to
* * * * *triggers source-side rate limiting.
Applicable and Non-Applicable Scenarios
Applicable: ToB scenarios with stable return rhythms, clear document structure, and clear idempotency keys (order number, stock-in number) in small-to-medium retail or distribution enterprises; also projects in early go-live stages that need to quickly establish a return ledger.
Not applicable: Group enterprises where returns need cross-organization or cross-book coordination (split into multiple strategies); systems where source APIs change frequently or field semantics are unstable (fix API governance first); scenarios where returns are tightly coupled with reversal or cost accounting (this strategy only handles document landing, not financial accounting logic).