Sales Return Inbound Sync in Practice: A Single-Strategy Tutorial from Marketing Cloud to Kingdee YXC
What This Strategy Solves
Cross-system sync of return documents is one of the most underestimated pieces of supply chain integration. In one retail scenario, the return workflow lives in a marketing cloud while finance and inventory posting live in Kingdee YXC. Without real-time sync, "returns already approved and shipped out in the marketing cloud" never flow back into Kingdee stock, reconciliation drags on, and warehouse books stay inflated. This article zooms in on one single strategy—sales return inbound sync—and shows how to land it reliably with the Qeasy Data Integration Platform.
Data Flow and Field Mapping
The flow is: Marketing Cloud (source) → Qeasy middle layer → Kingdee YXC (target). The source pulls audited returns (status=1) through POST /erp/api/order/query/saleReturnOrder by time window; the target writes sales inbound documents through POST /jdy/v2/scm/sal_in_bound.
Key field mapping (excerpted from the strategy config):
| Business meaning | Source field (Marketing Cloud) | Middle layer | Target field (Kingdee YXC) |
|---|---|---|---|
| Document number | number | Pass-through | Suffix into remark |
| Audit time | auditTime | {{auditTime|date}} truncate to date | bill_date |
| Source flag | — | Constant | bill_source = ISV |
| Customer | extCusCode | _findCollection lookup customer PK by code | customer_id |
| Shipping address | shippingAddress | Pass-through | contact_address |
| Item lines | items | Split rows, UOM/batch mapping | Entry lines |
A few source-API parameters worth flagging: tenantId identifies the dealer and is configured per tenant; status=1 ensures only audited returns are pulled; beginTime uses {{LAST_SYNC_TIME\|datetime}} for incremental pulls—this is what keeps the schedule alive.
How to Configure on Qeasy
In Qeasy, this strategy maps to one integration flow. Key configuration points:
- Source component: Marketing Cloud adapter, endpoint
query/saleReturnOrder,idCheckon, primary keynumberto avoid duplicate pulls. - Incremental watermark: Inject
{{LAST_SYNC_TIME\|datetime}}intobeginTime, setendTimeto now; the platform records the max update time as the next starting point. - Data cleansing: Maintain code mappings centrally in Qeasy's field-mapping panel—this is the most common pattern among Qeasy customers: centralized code mapping management. Reuse across similar documents; one change applies everywhere.
- Customer PK lookup: The target's
customer_iddoes not accept codes. Use the standard_findCollection find id from ... where number={{extCusCode}}action. On failure, route to the error queue for manual fix-up. - Target component: Kingdee YXC adapter,
sal_in_bound, hard-codebill_sourceasISV, append "来自营销云-document number" toremarkfor traceability. - Idempotency: Target
idCheck=true, usingidas the idempotency key. Re-runs won't create duplicates.
Implementation Steps
We usually recommend three phases:
Phase 1 — Seed the incremental watermark. Before go-live, choose a sensible beginTime (typically 00:00:00 of the launch date) and run a full backfill of historical returns. All daily runs thereafter are incremental.
Phase 2 — Full trigger and reconciliation. On day one, manually trigger a full run, then reconcile document numbers and amounts on both sides. Qeasy logs everything; pull a source/target reconciliation report and investigate deltas one by one. Don't skip this—dual-track incremental + full is a battle-tested steady-state pattern in Qeasy projects.
Phase 3 — Daily scheduling. Source polls every 8 minutes between 08:00 and 21:00 (*/8 8-21 * * *); target writes every 7 minutes between 07:00 and 23:00 (*/7 7-23 * * *). Staggered polling avoids simultaneous bursts. Night-time quiet hours align with business rhythms and reduce wasted calls.
Lessons Learned from the Field
statusmissing or wrong: A typical mistake is pulling everything by default, syncing drafts into Kingdee and creating piles of voided documents. The safe move is to hard-codestatus=1at the source and add another filter layer in Qeasy.beginTimenot normalized for time zones: The source returns timezone-aware strings. Without|datetimenormalization, day boundaries can cause "same doc pulled twice" or missed docs. Always format explicitly in the mapping layer.- Customer PK lookup failures: Dealer codes may have been renamed in Kingdee. The safe approach is to maintain a fallback "code → customer ID" mapping table in Qeasy and log alerts when the live lookup misses.
- Re-runs causing duplicate inbound: Even with
idCheck, if the source edits line details after approval under the samenumber, targetiddiffers and it's treated as new. Append the sourcenumberintoremarkto support manual reconciliation. - Night-time scheduling capturing pre-audit edits: If the source performs "un-approve → edit → re-approve" overnight, the incremental window catches multiple state changes. The robust approach is header first, then lines, staged commit in Qeasy, so failures roll back per segment instead of nuking the whole document.
When to Use and When Not to Use
Use when: returns live in a marketing cloud, inventory and finance live in Kingdee YXC, daily volume is tens to thousands, and returns must flow back to inventory in near real time—typical for retail and distribution. Do not use when: the source return workflow is still unstable with shifting status semantics, or when bidirectional sync is required (Kingdee returns must also write back to the marketing cloud). The latter should be split into two independent strategies to avoid circular dependencies.