Qeasy Cloud
Get Started

Sales Return Inbound Sync in Practice: Moving Return Orders from Marketing Cloud to Kingdee Cosmos

· 陈洁琳· Integration Solutions· 30 views· 5 min read
汤臣倍健营销云金蝶云星辰退货同步供应链集成轻易云配置增量调度Field Mapping踩坑复盘

What This Strategy Solves

In one retailer's setup, the marketing cloud owns the front-end dealer return requests, and Kingdee Cosmos handles back-end inventory and accounting. Return orders approved in the marketing cloud must land in Cosmos as sales inbound documents so inventory can be reduced and AR/AP updated. When this link breaks, store returns cannot be booked, inventory goes out of balance, and dealer settlements stall. We used the Qeasy data integration platform to take this segment, pushing approved return orders into Cosmos on an incremental schedule.

Data Flow and Field Mapping

Data starts at the marketing cloud, passes through Qeasy's middleware layer for mapping and transformation, and lands on Kingdee Cosmos's sales inbound API. The source side is a query endpoint that only pulls approved returns (status = 1); the target side is an execute endpoint that writes documents.

Key field mapping:

Business MeaningSource FieldMiddleware HandlingTarget Field
Document source—Fixed valuebill_source = ISV
Inbound dateauditTimeFormat yyyy-MM-ddbill_date
CustomerextCusCodeLook up internal id from customer collectioncustomer_id
Remarkremark + numberConcatenate "from marketing-cloud-docNo"remark
AddressshippingAddressPass-throughcontact_address
ContactcontactLinkmanPass-throughcontact_linkman

Line items also require material code translation. Marketing cloud codes must be mapped to Cosmos internal material ids. This is the most failure-prone area and is covered in the lessons-learned section.

How to Configure on Qeasy

In Qeasy, this strategy follows a three-stage pattern: source connector, mapper, target connector.

The source uses WebAPI query mode. The endpoint maps to the marketing cloud's return order query. The primary key is number, and idCheck is enabled to guarantee idempotency. In the request payload, status is hard-coded to 1, and beginTime uses the built-in variable {{LAST_SYNC_TIME|datetime}}. Each scheduled run only fetches data after the last successful sync, avoiding repeated full pulls.

The target side is also WebAPI but with effect set to EXECUTE, hitting Cosmos's sales inbound endpoint. The customer_id is not sent as a raw code; instead, it uses Qeasy's _findCollection syntax to look up the internal id from a customer master collection already synced into the platform. This is a very common "header and body staged" pattern among Qeasy customers: master data is synced first, then transactional documents use platform-internal ids to avoid cross-system code mismatches.

Centralized code mapping is another safe approach. We maintain a material mapping table inside Qeasy with source code as the key and Cosmos internal id as the value. Before each line item is written, the table is queried. Unmatched items go into an exception queue rather than letting the API fail noisily.

Implementation Steps

The rollout is divided into three stages.

Stage one, incremental starting point. Determine the initial value of LAST_SYNC_TIME, typically a few days before the go-live date. Run an initial pull of approved historical returns to confirm that mapping and writing work end-to-end.

Stage two, full backfill. On go-live day, manually trigger a full backfill so historical returns sync into Cosmos in one pass. Immediately advance the cursor to the current time, then switch to incremental mode.

Stage three, schedule frequency. The source cron runs every 8 minutes (07:00–23:00, avoiding midnight), and the target runs every 7 minutes. The two are offset by a few minutes to keep the queue from stalling while preventing idle polling. If marketing cloud return volume is low, the source can be relaxed to every 15 minutes, but the target should keep a higher frequency so approved returns are booked quickly.

Lessons Learned

Pitfall 1: Customer mapping collection was not ready. On go-live day, the customer master in Cosmos had not yet been synced into the platform. Every _findCollection returned empty, and the entire batch of return orders failed. The safe approach is to put master-data sync strategies (sequence A/B, e.g., query customer, query material) online before the return sync and make them hard dependencies: transactional documents only run once master data is in place.

Pitfall 2: Empty auditTime broke bill_date parsing. The marketing cloud occasionally returns dirty records with no audit time. On the Cosmos side, the date format fails and the whole document is rejected. Add a null check in the mapper: fall back to createTime; if that is also empty, fall back to the current date and log a warning.

Pitfall 3: beginTime used creation time instead of update time. The marketing cloud API uses timeType to choose between creation time and update time. By default, it is creation time. If business logic treats "approved" as the trigger, the cursor must follow update time or approvals that lag will be missed. We explicitly set timeType to 1 and use update time for the cursor.

Pitfall 4: Quantity or unit mismatch was rejected by Cosmos validation. Marketing cloud return quantities may use the sales unit, while Cosmos inbound requires inventory units. Without unit conversion, the document cannot be created. Conversion must happen in the mapping stage. Unmapped units go to the exception queue for manual handling and must not be silently dropped.

Pitfall 5: Idempotency keys did not work and reruns produced duplicates. Although we used number as the idempotency key, mid-pipeline failures plus retries can still produce duplicates if the target API does not dedupe by external document number. Qeasy's "dedupe by number + failure rollback" acts as a safety net: if the platform-side persistence fails, nothing is sent to the target API, which prevents dirty data.

When to Use and When Not to Use

Use it when the marketing cloud is the order entry point and Cosmos is the inventory/accounting back end, daily return volume ranges from hundreds to tens of thousands, and incremental, scheduled, idempotent sync is acceptable. Do not use it when sub-second real-time sync is required (use event-driven instead), when return approval flows must penetrate into Cosmos, or when returns involve cross-org transfers that require more complex split logic.

Conclusion

Return inbound sync may look like a single query plus a single write, but it hides four moving parts: master data dependencies, unit conversion, idempotency, and cursor handling. Getting these right once on Qeasy means that the rest of the dozens of document sync strategies in this project (66 in total) can reuse the same mapping and scheduling conventions. One pitfall avoided is one round of rework avoided.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-p158a24-kingdee-cloud-4452-life-space-ca362f5f

Comments