Sales Order Sync in Practice: From Kingdee Delivery Notice to Wangdiantong Raw Trade Orders
What This Strategy Solves
A retail enterprise runs its shipping on Kingdee Cloud · Galaxy Flagship, but fulfillment and online order operations live in Wangdiantong. Once a delivery notice is approved in the ERP, it must quickly land in Wangdiantong as a "raw trade order" so downstream tasks—printing, picking, and logistics tracking—can proceed. The essence of this strategy is: fetch the delivery notice (header + line items) from Kingdee, reshape it by shop into Wangdiantong rawTrade + rawTradeOrder arrays, and incrementally write it back on a schedule.
Data Flow and Field Mapping
The flow is one-way: Kingdee Cloud · Galaxy Flagship (source) → Qeasy middleware → Wangdiantong Flagship (target).
The source API is RESTful batchQuery with paging; the target is WebAPI sales.RawTrade.pushSelf2, which takes the order and its line items as arrays in a single payload. The key field mapping looks roughly like this:
| Business meaning | Kingdee source field | Wangdiantong target field | Handling |
|---|---|---|---|
| Document number | billno | rawTradeList[].trade_no | Direct mapping, used as idempotency key |
| Document primary key | id | idCheck validation | Anchor for incremental starting point |
| Shop code | Custom field | shop_no | Code mapping, maintained centrally |
| Order lines | billentry | rawTradeOrderList | Array passed through as a whole |
| Pagination | pageNo / pageSize | — | Paging loop handled in middleware |
Note that rawTradeOrderList on the target side corresponds to the billentry collection on the source. You need to assemble header + lines in the middleware layer and submit them together, otherwise Wangdiantong will reject the request.
How to Configure in Qeasy
We use the Qeasy data integration platform to host this pipeline. A typical configuration has four parts:
- Source data source: register the Kingdee API account, point it at
/kapi/v2/dtog/sm/sm_delivernotice/batchQuery, and enableautoFillResponseso returned fields expand automatically—no manual parsing each time. - Target data source: register Wangdiantong's WebAPI, select
sales.RawTrade.pushSelf2, and reference{{customer_number}}forshop_no, so routing can split by shop. - Field mapping + code mapping: the shop code on the delivery notice is usually an internal ERP code. In Qeasy's "Code Mapping" module, maintain a centralized "ERP shop code ↔ Wangdiantong shop no" table. New shops then only need one update.
- Header/lines staged write: in Qeasy's "Data Processing" node, first use JSONPath to extract
billentry, then use the "Array Constructor" to assemble the two-level structure Wangdiantong expects:rawTradeList + rawTradeOrderList. This header/lines staged approach is the most common pattern we see at customer sites—avoid stuffing everything into a single flat object.
Implementation Steps
At customer sites we generally walk through three stages:
- Stage 1: Anchor the incremental starting point. Run once with
idCheck=trueto confirm that only records after a chosen timestamp are pulled, avoiding replaying tens of thousands of historical delivery notices and tripping the target's rate limit. - Stage 2: Trigger a full baseline run. Filter by business date on the Kingdee side, write the day's delivery notices back in small batches (50 per batch) as a baseline. Qeasy's "Batch Execution" node can run concurrently, typically tens of seconds per batch.
- Stage 3: Enter the scheduling loop. The source crontab is
0-59/3 7-22 * * *(every 3 minutes during business hours); the target is offset by one slot,1-59/3 7-22 * * *, to avoid both ends saturating bandwidth at the same second. This "incremental + full baseline dual-track" approach is very common among Qeasy customers.
Pitfalls and Lessons Learned
- Lines flattened into a single object array. Submitting
billentrydirectly as an object array causes Wangdiantong to return "order details cannot be empty." The safe approach is to first assemblerawTradeList[].rawTradeOrderListvia the Array Constructor before submitting. - Missing shop code mappings. A single delivery notice may carry multiple shops. Mapping only the primary shop causes some orders to silently drop. Recommendation: maintain a full mapping plus a "shop not matched" interception log.
- Duplicate trade_no idempotency keys. When the same batch is re-run, if
trade_nois not unique, Wangdiantong treats it as a new order. In Qeasy's "Data Processing" combinebillno + line numberinto trade_no to ensure idempotency. - Cross-day scheduling windows. With crontab set only to
7-22, urgent orders shipped overnight are queued until 7 a.m., and the business feels the "delay." If the business allows, add an overnight catch-up task to backfill orders from 22:00 to 07:00. - Rate-limit errors silently swallowed. Wangdiantong's rate-limit responses are Chinese text rather than HTTP 429, easy to mistake for data issues. Qeasy's "Exception Handling" node can identify rate-limit responses by keyword and automatically retry with backoff.
Applicable and Non-applicable Scenarios
Applicable for enterprises where the ERP has ready delivery notices and those notices must be synced to an e-commerce fulfillment / ERP-integrated platform for unified printing and logistics tracking. Not applicable for scenarios requiring real-time (second-level) latency, or where order structures differ wildly and require custom development—those cases are better served by event-driven middleware than scheduled polling.