Qeasy Cloud
Get Started

Sales Return Order Sync in Practice: Incremental and Idempotent Design from Wangdiantong to Yongyou BIP

· 系统管理员· Integration Solutions· 48 views· 4 min read
WDT用友BIP销售退货同步Incremental Sync幂等设计轻易云

What This Strategy Solves

In an omni-channel retail business, offline and e-commerce returns and exchanges are first recorded in the retail e-commerce platform (Wangdiantong·QiMen in this case), where they go through approval, refund, receipt, and settlement. But financial accounting, receivables offsetting, and inventory reconciliation all live in the large-scale ERP (Yongyou BIP). Without integration, the finance team ends up re-keying returns manually, inventory numbers diverge, and customer sub-ledgers do not match.

The goal is to push return orders that have already been settled (or partially settled) in Wangdiantong into Yongyou BIP as sales return vouchers, so that "once approved, it's in the books."

Data Flow and Field Mapping

The overall flow is: Wangdiantong·QiMen → Qeasy integration platform (middle layer) → Yongyou BIP sales return voucher.

DimensionSource (Wangdiantong)Middle Layer (Qeasy)Target (Yongyou BIP)
Document numberrefund_norefund_nocode / resubmitCheckKey
Unique keyrefund_idrefund_idid
Incremental windowLast modified timeLAST_SYNC_TIME → CURRENT_TIME-
Sales orgshop_noLook up mapping_sale_orgsalesOrgId
Customershop_noLook up mapping_customeragentId
Transaction typeFixed business meaningFixed valuetransactionTypeId
Retail investor flagDerived from source statusRule fieldretailInvestors

Key point: shop_no is a store code on the source side, but on the target side it must be translated into two master keys: sales organisation and customer. Do not scatter this mapping across strategies. Maintain it centrally in a dedicated "store-to-customer/org mapping" strategy, and have all other strategies reference it via _findCollection. Change once, apply everywhere. This centralised mapping pattern is the most common practice among Qeasy customers.

How to Configure It in Qeasy

Source configuration (QUERY)

  • Use the wdt.refund.query API, POST method. Start with the default page size of 40 and tune upward only after load testing.
  • Bind start_time / end_time to the platform variables LAST_SYNC_TIME and CURRENT_TIME so nothing is missed.
  • Filter on process_status at the source side. Pull only orders that are clearly settled ("completed: 90", "partial received: 70/71"). Skip in-flight ones such as "pending review: 20" or "pending receipt: 60" so the finance system does not have to flip-flop on offsets.
  • Use refund_id (or refund_no) as the number field and enable idCheck. The platform will deduplicate automatically.

Target configuration (EXECUTE)

  • Use the /yonbip/sd/vouchersalereturn/singleSave API. The single-save variant fits non-standard documents generated by returns.
  • Generate resubmitCheckKey client-side. In Qeasy, compose it as {{refund_no}}-4 with a business suffix to keep it globally unique and human-readable.
  • For the code field, pass refund_no unconditionally. Whether Yongyou BIP actually uses it depends on the numbering rule set there (auto-numbering ignores it, manual numbering requires it). Passing it unconditionally is the safer choice.
  • salesOrgId and agentId are resolved through _findCollection lookups. If the lookup fails, short-circuit the whole document rather than writing a half-formed one into finance.

Implementation Steps

Phase 1: Baseline alignment (pre-go-live) Run a one-off full pull to backfill all already-settled returns. Confirm the mapping table has full coverage, then run a reconciliation pass on the target side.

Phase 2: Switch to incremental (go-live) On the source side, switch start_time to LAST_SYNC_TIME and schedule every 10 minutes (1-59/10). On the target side, stagger to 5-59/10 so writes do not start before the source pull finishes. The dual-track pattern (full pull as a safety net, incremental as the steady state) is the most common go-live path used by Qeasy customers.

Phase 3: Exception monitoring (run) Watch for three failure modes: 1) shop_no missing from the mapping table; 2) resubmitCheckKey collision (target-side retries polluting idempotency); 3) target returns success but no voucher is posted in finance (header saved, but the approval chain did not complete). Catch the first two in Qeasy alerts directly. The third requires a joint review with a reconciliation job.

Pitfalls and Lessons Learned

Pitfall 1: Incremental window drift. Wangdiantong filters on "last modified time." If customer service keeps editing a refund amount, the same refund_no will be pulled multiple times. Fix: use refund_id as the idempotency key, not refund_no.

Pitfall 2: Missing shop_no mapping. A new store opens, its shop_no is not yet registered in the mapping table, and source documents start arriving. The result is full-document create failures on the target side with no signal at the source. The symptom is inventory drift. Safest approach: alert on missing mappings, never default to an empty value.

Pitfall 3: Header passes, line items fail. Yongyou BIP's singleSave submits header and lines together. If one SKU in the lines is unknown on the target side, the entire document is rolled back, triggering retry storms. The common Qeasy pattern here is staged header/line processing: write the header first in a draft state with empty lines, then fill the lines, and retry only the lines on failure rather than the whole document.

Pitfall 4: Treating partial settlement as final. Statuses 70/71 (partial receipt) will continue to receive goods. If pushed to finance as final, the second settlement will create a "returned but still in transit" state mismatch. Either filter these out at the source, or push them to an intermediate "pending settlement" state on the target.

Pitfall 5: Non-unique resubmitCheckKey. Using refund_no directly as the idempotency key breaks if the source resets the refund_no sequence (year-end, migration). New and old documents may share a key, and the target will silently drop one of them. Always append a business suffix.

When It Fits, When It Doesn't

Fits: Multi-store, multi-sales-org retail and omni-channel businesses where the e-commerce ERP and the financial ERP are separate, and returns must enter financial accounting and inventory offsetting.

Does not fit: When the source and target are the same system (use the built-in document conversion instead of a middle layer), or when returns do not need to enter finance at all and only serve logistics and after-sales tracking (a ticketing system is lighter for that).

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-wdt-bip-6322-n884e1fa3-6f78804d

Comments