tva
← Insights

小規模 EC 向け WMS 統合

The question of when a warehouse management system is worth integrating comes up earlier than most small e-commerce operations expect. Spreadsheets work well until they don’t — and the inflection point is usually not order volume but order complexity: multiple SKUs with variant tracking, bundles, backorders across multiple fulfilment locations, or the need for accurate available-to-promise figures at checkout. This post covers our experience integrating GreaterWMS with a small e-commerce operation, what worked, what required more design than we anticipated, and where spreadsheets are still the right answer.

なぜ GreaterWMS か

GreaterWMS is an open-source warehouse management system with a REST API, a Django backend, and a Vue frontend. It supports multi-warehouse inventory, lot and batch tracking, inbound and outbound order management, and basic reporting. The codebase is actively maintained and the API documentation, while not exhaustive, covers the core operations.

We chose it over hosted alternatives for two reasons. First, we were already running self-hosted infrastructure and did not want to add another SaaS dependency with per-order pricing at scale. Second, the open-source nature meant we could extend the data model without waiting for a vendor feature request cycle. For a small operation with specific needs around lot expiry tracking, that flexibility mattered.

The deployment is a Docker Compose stack with the Django application, PostgreSQL, and Redis. On a modest VPS it runs comfortably alongside other services. The initial setup takes a few hours; the integration work takes considerably longer.

API 統合パターン

GreaterWMS uses token-based authentication. You generate a token per user through the admin interface and pass it as a Bearer token in the Authorization header. There is no OAuth flow or API key rotation mechanism built in, which means you should create a dedicated service user with minimal permissions rather than using an admin account.

The API is largely RESTful with JSON payloads. The main resources you interact with for an e-commerce integration are: goods (your product catalogue in WMS terms), inventory (current stock levels per warehouse and goods), inbound orders (purchase orders and returns), and outbound orders (customer orders for fulfilment).

One pattern we established early: never call the WMS API synchronously from the checkout path. The WMS is not on your critical transaction path, and if it is slow or temporarily unavailable, it should not affect your customer’s ability to complete a purchase. All WMS interactions go through an async queue. The checkout records the order in your primary database and publishes an event. A background worker picks up the event and creates the outbound order in GreaterWMS. Failures in the worker are retried with exponential backoff and alert on persistent failure. This decoupling is non-negotiable.

注文同期

The outbound order creation call takes a goods ID, a quantity, and destination address information. The mapping between your e-commerce order line items and WMS goods IDs needs to be maintained explicitly. We store the WMS goods ID as an additional field on each product variant in our catalogue database. This mapping is set manually when a new product is created and checked in the sync worker before dispatching the outbound order creation request.

Status synchronisation runs in the opposite direction: GreaterWMS updates the outbound order status as the warehouse processes it, and your e-commerce system needs to reflect that. GreaterWMS does not push status changes; you poll. We run a polling job every few minutes that queries outbound orders with a status of “in progress” and checks whether the status has changed to “dispatched” or “cancelled”. When it has, we update the corresponding order in our e-commerce database and trigger any downstream actions — customer notification emails, tracking number updates.

Idempotency in the outbound order creation is important. If the background worker retries after a transient failure, it must not create duplicate outbound orders in GreaterWMS. We store the WMS outbound order ID on our internal order record immediately after a successful creation call. On retry, the worker checks whether a WMS ID already exists before making the create call. If it does, the worker skips creation and proceeds with whatever downstream action it was attempting.

在庫更新

Keeping your e-commerce inventory counts in sync with the WMS is the part that requires the most ongoing attention. There are two directions: your e-commerce platform needs accurate stock levels to prevent overselling, and the WMS needs to reflect purchases and returns that originate outside of it.

For stock level reads, we pull inventory snapshots from the GreaterWMS inventory API on a scheduled basis and write the figures to a Redis cache that the e-commerce storefront reads. The polling interval depends on your sales velocity. For slow-moving products, hourly is fine. For products that sell in bursts, you need either a shorter interval or a reservation model at checkout — where a customer placing an item in the cart temporarily reserves stock regardless of the WMS sync cycle.

Returns are the most complex case. A returned item may re-enter stock, go to a quarantine location for inspection, or be written off. GreaterWMS has an inbound order flow for returns, but mapping your e-commerce return states to WMS inbound order states requires explicit design. We created a state machine that translates return reason codes from the e-commerce system into WMS disposition codes, and we review the mapping with the warehouse team whenever a new return reason is added. Without this mapping, returned stock silently fails to reappear in available inventory.

競合状態とバッファ在庫

Even with polling-based inventory sync, race conditions are possible. If two orders arrive simultaneously and both read the same cached stock level before either has been reflected in the WMS, you can oversell by the polling interval’s worth of units. For products where overselling is unacceptable — limited edition items, perishables with tight lot constraints — the right approach is a reservation layer that decrements a local available count at checkout and reconciles with the WMS asynchronously.

A simpler mitigation is buffer stock: maintain an available count in your e-commerce database that is the WMS stock level minus a small reserve. Orders deplete this buffer. When the buffer hits zero, the product shows as out of stock even if the WMS still shows units. This creates a small risk of holding stock that customers cannot order, but it eliminates the oversell risk and requires no reservation logic. For most small operations, the buffer approach is the right trade-off.

WMS がスプレッドシートより合理的な場合

A warehouse management system adds integration complexity, operational overhead, and a new system to maintain. Before committing to an integration, it is worth being honest about whether the problems you are trying to solve actually require a WMS.

Spreadsheets are adequate when: your SKU count is small and stable, you have a single warehouse or fulfilment location, orders are processed manually and volume is low, and you do not need real-time available-to-promise at checkout. In this case, a WMS integration costs more to build and maintain than the problems it solves.

A WMS starts paying off when: you have multiple warehouses or pick locations, you need lot or batch tracking for compliance or quality reasons, your return rate is high enough that return disposition needs systematic handling, or your order processing is automated and requires accurate stock reservation to prevent oversells. These are operational problems that spreadsheets genuinely cannot solve at any reasonable level of rigour.

The integration work we describe in this post took several weeks of engineering time, including testing. That time could have funded a significant amount of manual warehouse coordination work. Be precise about which problems you are solving and whether software is the right tool for them before starting.


関連インサイト

関連記事