Return-Inbound Document Sync Strategy: From Marketing Cloud to Kingdee YXC
What this strategy solves
A retail client uses the marketing cloud to receive distributor return requests, while finance needs a red-letter inbound document generated in Kingdee YXC. Manual entry is error-prone and labor-intensive—return volumes are high, SKUs are numerous, and a single wrong code breaks inventory accounts. We used Qeasy as a middleware layer to pull audited returns incrementally, transform them, and write them into the target ERP's sales-inbound interface, achieving single-source entry with consistent data on both sides.
Data flow and field mapping
The pipeline is: Marketing Cloud (QUERY) → Qeasy middleware → Kingdee YXC V2 (EXECUTE). The source uses the marketing cloud's return-order query endpoint, paginating audited returns (status=1). The target writes to Kingdee's sales-inbound interface. The middleware handles cleaning, code translation, and idempotent deduplication.
Key field mapping:
| Business meaning | Marketing cloud field | Middleware handling | Kingdee YXC field |
|---|---|---|---|
| Source flag | — | Fixed write | bill_source = ISV |
| Document date | auditTime | Format as date | bill_date |
| Customer | extCusCode | _findCollection lookup by code | customer_id |
| Remark | remark | Append "from marketing cloud-no." | remark |
| Shipping address | shippingAddress | Pass-through | contact_address |
| Line items | entries[] | Code mapping + line expansion | Entry detail array |
| Document no. | number | As idempotency key | Written into remark |
Configuring on Qeasy
The source strategy is WebAPI/QUERY with POST to the marketing cloud's return-order endpoint. The incremental field binds {{LAST_SYNC_TIME|datetime}} as the start time, and the status filter is fixed at 1 (audited/outbound). One subtle point: passing 0 also pulls draft orders, and those get rejected by the target.
The target strategy is WebAPI/EXECUTE calling Kingdee's sales-inbound endpoint. The customer field uses _findCollection find id from <customer strategy> where number={{extCusCode}}—this depends on the master-data sync running first. A common pattern is centralizing code mapping in Qeasy's customer/material strategies (centralized code mapping), so the return strategy only references the mapping result.
Idempotency relies on two things: source-side idCheck=true to prevent missed records, and number as the idempotency key written into remarks for later reconciliation.
Implementation steps
Phase 1: Lay the master data. First stabilize the customer and material sync strategies, ensuring the extCusCode and product codes in returns can resolve to ids on the Kingdee side. Typically, sequence A and B master-data strategies should run before transactional documents.
Phase 2: Set the incremental starting point. For the first full pull, initialize LAST_SYNC_TIME with a historical window to avoid pulling years-old orders. On-site we usually suggest cold-starting with "audited orders in the last 90 days," then switch to incremental.
Phase 3: Steady-state scheduling. Source runs */8 7-23 * * * (every 8 minutes during business hours); target runs */7 7-23 * * * (every 7 minutes). The 1-minute offset leaves a processing window on the target. High frequency by day, low frequency at night, covering the distributor return peak window.
Phase 4: Reconciliation and replay. Qeasy provides run logs; filter failures by document number. Common failures are "customer not found" and "product code not mapped"—fix the base-data strategy and resend single records.
Pitfalls recap
-
Wrong status flag. When the marketing cloud's status is 0, draft orders are also pulled and rejected by the target's inbound validation—a classic trap. The safe practice is to fix the source at 1 and whitelist exceptional statuses.
-
Code mapping scattered across strategies. If extCusCode or product codes in returns are not mapped in the customer/material strategies, the entire batch fails. We centralize all code mapping in the base-data strategies (centralized code mapping), and business strategies only reference.
-
No incremental starting point design. A direct full backfill pushes three years of old orders at once, straining target performance and triggering rate limits. We recommend explicitly setting an incremental start point: verify in a small window first, then widen.
-
Header and body pushed in one shot. Return orders have many line items; bundling them with the header in one request easily times out. We split header and body submission (phased header and body), which also speeds up failure localization.
-
Weak idempotency key design. Relying only on the document number for idempotency fails when the document number changes on a source resend, causing duplicate inbound. We recommend combining source id + number as the idempotency key and writing it into the remark for traceability.
When to use and when not to use
Use when: marketing cloud return statuses are stable and require near-real-time sync to Kingdee for finance inbound; document volume is concentrated during business hours and sparse at night.
Do not use when: source-side return statuses change frequently and historical orders need to be retroactively amended; the target does monthly batch posting and does not need minute-level response—scheduled batch import is more cost-effective in that case.