Sales Order Incremental Query Strategy: Sync Design from Xiaoman OKKICRM to Zhibang ERP
What This Strategy Solves
Sales order sync from CRM to ERP looks like just "moving" a document, but the real challenge is idempotency, recoverability, and traceability. On a private-deployment project we delivered for a manufacturer, the CRM and ERP sit in different rooms; business peaks during the day, and reconciliation runs at night. The strategy's goal is clear: pull incremental orders steadily through a time window plus paging cursor, land them on the integration platform, and let downstream strategies write them into ERP sales contracts.
Data Flow and Field Mapping
The flow is one-way: CRM → Qeasy Integration Platform → ERP. This strategy only covers "pull + staging".
| Dimension | Source (Xiaoman OKKICRM) | Middle layer (Qeasy) | Target (Zhibang ERP) |
|---|---|---|---|
| API | /v1/invoices/order/list GET | Write-empty operation | Triggered by downstream strategy |
| Business number | name | number | 0 (placeholder) |
| Unique ID | order_id | id | 0 |
| Time window | start_time / end_time | LAST_SYNC_TIME → CURRENT_TIME | — |
| Paging | start_index / count | default 1 / 10 | — |
| Deleted flag | removed=0/1 | pass-through | — |
| Schedule | */15 7-22 * * * | — | 23 2 * * * |
Note: the target metadata marks idCheck=true and api=写入空操作. This is deliberate: this strategy only lands data into the platform's staging table; a follow-up strategy (sequence B) writes to ERP. Coupling pull and write in one step makes rollback painful later.
How to Configure on Qeasy
- Register the source platform: onboard Xiaoman OKKICRM as a data source; mark
palatom.codeto identify the source for lineage tracing. - Parameterize the request: bind
start_timeto{{LAST_SYNC_TIME|datetime}}andend_timeto{{CURRENT_TIME|datetime}}. This is the lifeline of incremental sync, revisited in the pitfalls section. - Paging parameters: default
start_index=1,count=10. In production we usually raise this to 50–100, but keep it conservative for the first launch. - Target strategy node: pick the "write-empty" API, turn on
idCheckto keep duplicate IDs from dirty-writing the staging table. - Centralize code mapping: keep shared code values—customer, product, price conditions—in a single mapping center on the platform rather than scattered across each strategy's script. This is one of the most common patterns among Qeasy customers.
Implementation Steps
- Phase 1 · Cold-start full load: manually rewind
LAST_SYNC_TIMEto a clear historical point (e.g., the start of the month) and run a full load to land all historical orders. Schedule this at the off-peak hours after midnight. - Phase 2 · Switch to incremental start: once the historical data reconciles cleanly, switch to the
*/15 7-22 * * *incremental window aligned with peak business hours. - Phase 3 · Scheduling cadence: every 15 minutes during the day to cover peak business; stop at night to leave room for the 02:23 reconciliation job (
23 2 * * *). This is the classic dual-track of incremental and full load: high-frequency small batches by day, low-frequency large batches by night. - Phase 4 · Anomaly circuit breakers: configure three thresholds—consecutive empty pages, consecutive failures, missing fields—and alert + pause the strategy when triggered.
Pitfalls We Hit in the Field
- Time window in local time, not UTC: in one cross-time-zone deployment, the CRM returned
order_timeas a local-timezone string, while we used UTC forLAST_SYNC_TIME—orders were missed for three days. The safe approach is to parse source time fields uniformly in ISO8601 with timezone. counttoo large causing API timeouts: one customer jumped straight tocount=500; a single response took 40 seconds and tripped the upstream gateway's circuit breaker. Start at 10 and step up gradually.- Forgot the
removedflag: early in go-live we only queried non-deleted records. The CRM later deleted a batch of test orders, but they still existed on the ERP side. Lesson: even if v1 doesn't consume deletions, storeremoved=1data separately as reconciliation evidence. idCheckleft off on the target side: rerunning batches produced many duplicateorder_idrows in the staging table and broke downstream metrics.idCheckmust be on—this is where "write-empty landing" strategies most often go wrong.- Dependency not declared: this strategy sits in sequence B and is depended on by the "write ERP" strategy, but
depends_onwas never set explicitly, so they fired in parallel and raced. Always draw the dependency chain explicitly in metadata.
When to Use This and When Not To
Use it when: CRM and ERP are heterogeneous, orders can be pulled incrementally by time window, and a private-deployment project needs a staging layer for reconciliation—especially in multi-strategy coordination scenarios where header and body are phased and code mapping is centralized. Don't use it when: the source doesn't expose time-window or cursor APIs, order volume is huge and needs streaming push, or the business demands strong real-time (sub-second) sync. Those cases fit change-log or message-queue designs better.