A WeChat Mini Program Replaces Industrial PDAs for Warehouse Scanning: Concurrency Control and Four Pitfalls
WeChat Mini Program as a PDA for Barcode-Based Warehouse Inbound/Outbound: Inventory Concurrency Control and 4 Pitfalls
Author: baiyunfan
Target scenario: warehouses of small and micro enterprises (10–200 employees). No PCs deployed, no industrial PDAs purchased; the warehouse keeper has only a mobile phone. This article records how we got barcode-based inbound/outbound working with a WeChat Mini Program — why we didn't use an industrial PDA, whether a Mini Program is good enough as a barcode scanner, and how to let a Mini Program safely read data from an on-premises ERP.
1. The problem: no computers in the warehouse, records kept on paper and WeChat
Let's set the scene first, otherwise the selection will go off track.
We serve manufacturing and trading/distribution companies. Their warehouses typically look like this:
| Current state | What it looks like | Consequence |
|---|---|---|
| No PC | Warehouse is next to the workshop or in a separate building; running network cable and setting up PCs is considered a hassle | Inbound/outbound can only be entered back at the office |
| Paper documents | Sign the delivery note → take it back to the office → re-enter into ERP | Every entry is another chance to make an error |
| Excel | Warehouse keepers maintain their own Excel ledger, so there are two sets of books: Excel and ERP | At month-end they don't match, so a stocktake is needed |
| Take photos of inbound/outbound and send to a group chat; office staff enters them by looking at photos | Messages get buried as soon as they scroll by; missed entries are routine |
The core contradiction in one sentence: the ERP in the office is accurate, but the warehouse floor is wrong — and the real change in inventory happens on the warehouse floor.
2. Selection: why not an industrial PDA, but a WeChat Mini Program
The conventional approach here would be to buy industrial PDAs. We ran the numbers and gave up on that.
| Option | Hardware cost | Deployment/maintenance | Scanning capability | Camera | Connectivity | Label printing |
|---|---|---|---|---|---|---|
| Industrial PDA | 2,000–5,000 RMB per unit | Install APK on each unit, configure IP, upgrade one by one | Strong (laser / professional scan engine) | Average | Requires Wi-Fi coverage | Built-in Bluetooth printing, strong |
| Native App | Zero hardware | Need to distribute install packages; iOS also requires signing | Medium (uses camera) | Good | Works over mobile network | Good Bluetooth printing support |
| WeChat Mini Program | Zero hardware | Zero install, zero upgrade | Medium (wx.scanCode, good enough) |
Good | Works over mobile network | ⚠️ Limited capability |
Three decisive reasons:
The warehouse keeper already has a scanner in their pocket. Any current smartphone camera can recognize Code128 part-number labels and EAN-13 product barcodes without any trouble. Spending 3,000 RMB on hardware just for “scanning” doesn't make economic sense.
Zero install, zero maintenance. This matters most to small and micro enterprises. The worst part of industrial PDAs isn't buying them; it's what comes after — broken devices need replacement, system upgrades must be done unit by unit, and when staff turn over, devices must be reconfigured. With a Mini Program, you scan a QR code and it works; upgrades happen server-side and the client does nothing.
No training required. Employees use WeChat every day, so the interaction habits are already there. This matters especially during workshop rollout — many ERP projects fail not because of functionality but because employees don't want to learn.
The trade-offs need to be stated too (see Section 6): the Mini Program is limited in Bluetooth label printing and long-duration offline work. If those are real hard requirements, an industrial PDA is still a better fit. Our judgment: most small warehouses should first solve “accurate scanning, real-time data”; printing can be postponed.
3. Overall flow
Phone (WeChat Mini Program)
├─ wx.scanCode Scan part-number label / product barcode
├─ Manual entry Fallback when scanning fails (fuzzy search)
└─ Camera Delivery notes, receipts
↓ HTTPS
Gateway layer (HTTP API)
↓ Reuses existing business logic
ERP inventory / documents
↓
Real-time inventory write-back (server-side transaction processing)
One design principle runs through everything: the Mini Program only does “capture + display”; all calculation and writes happen server-side. The reason is in 4.3.
4. Four key implementation points
4.1 Scanning: practical configuration of wx.scanCode
The Mini Program's scanning capability comes from wx.scanCode. A single call can specify the symbology and source:
wx.scanCode({
onlyFromCamera: true, // Warehouse scenario: camera only, disallow picking from album (to prevent selecting the wrong image)
scanType: ['barCode', 'qrCode'], // Code128/EAN13 are barCode; QR codes are qrCode
success(res) {
// res.result → scanned content (part number / barcode)
// res.scanType → recognized symbology
// res.charSet → character set (pay attention for Chinese code values)
handleCode(res.result);
},
fail() {
wx.showToast({ title: 'No barcode recognized, you can enter manually', icon: 'none' });
}
});
In practice, three details are worth noting:
onlyFromCamera: truemust be added. Without it, old photos may exist in the album; an employee casually picks the wrong image and it scans as a different part number — that kind of error is extremely hard to trace.Restrict
scanTypeto the symbologies actually used in the warehouse. Leaving all of them enabled slows recognition; keeping only the two types in use makes recognition faster and more stable.Verify
charSetfor Chinese part numbers. If part numbers contain Chinese characters, the encoding of scan results may differ across Android devices. Recommendation: use pure alphanumeric characters when designing part numbers, avoiding this pitfall at the source.
4.2 Look up materials by barcode: one query returns all fields
Scanning only gives you a string of characters. The real value is using it to pull up the entire material record without typing.
Scan → barcode → call query API (look up material by barcode)
→ returns: part number, name, specification, unit, current stock
→ the person only enters “quantity”
The experience difference is huge here: manual entry requires typing and checking the part number, name, specification, and unit field by field; after scanning, you only need to type a quantity.
This also incidentally solves the real-world problem of “multiple coding schemes” — many factories have both customer part numbers and their own part numbers, and delivery notes print the customer's. Our approach is to maintain a mapping table so that a barcode from either side can look up the internal material (this was also the earliest effective feature in real customer feedback: just enabling the part-number mapping saved one full-time reconciliation staff member's workload; see Section 7).
4.3 Inventory deduction must be server-side, with concurrency control
We stepped on this pitfall, so it gets its own section.
Wrong approach: the Mini Program reads stock as 100, calculates “100 - outbound 10 = 90” on the UI, then submits 90. The logic looks fine, but in reality —
Warehouse keeper A: reads 100, prepares to issue 30
Warehouse keeper B: reads 100, prepares to issue 20
both submit almost simultaneously
final stock = 70 (should be 50) ← one update is lost
This is the classic concurrent overwrite. Multiple people working at once is normal in a warehouse. Once an update is lost, books and actual stock disagree, and there is no error at all — the worst kind of bug.
Correct approach:
- The frontend only submits the “action + quantity” (issue 10), not a precomputed result value.
- The server performs the increase/decrease inside a transaction, and locks the stock row or uses a version number for optimistic locking:
-- Executed inside a transaction: check the version first, then update
UPDATE stock
SET qty = qty - @outQty, version = version + 1
WHERE item_id = @itemId
AND version = @expectedVersion; -- if version doesn't match, affected rows = 0, meaning someone changed it
-- affected rows = 0 → roll back and show “Stock has changed, please refresh and retry”
- Insufficient stock should be blocked and reported, not allowed to go negative (unless the business genuinely allows it, in which case it must still leave an audit trail).
Lesson learned: for any operation that changes a quantity, never use the “read → calculate → write back” pattern. This isn't a Mini Program problem; it's a classic trap in any multi-client system.
4.4 Gateway layer: the Mini Program doesn't connect to the database directly; it uses generalized APIs
This section has the biggest impact on long-term maintenance cost in the whole solution.
Core constraint: WeChat Mini Programs can only access HTTPS legal domains (requires ICP filing and whitelist configuration in the Mini Program admin console), and cannot directly connect to an internal database. So a gateway layer is required in between.
WeChat Mini Program → HTTPS gateway → reuse existing business logic → database
We did not write a new set of APIs for the Mini Program. Instead, we built the gateway as 6 generalized APIs:
| API | Purpose |
|---|---|
login |
Log in and exchange for a session identifier |
menu |
Get menus visible to the current account (filtered by permissions) |
meta |
Get field metadata for lists/documents |
query |
Generic query (pass template ID + parameters, not hardcoded SQL) |
save |
Generic save (master/detail/sub-detail three-level payload) |
exec |
Execute actions (submit, approve, etc.) |
Why these six are enough: all queries and saves are driven by “templates” — the server maintains a template table, and each template contains its corresponding query statement, visible fields, column widths, and other metadata. The Mini Program only needs to know the template ID:
/query?template=xxx¶ms=yyy
The benefits are very practical:
Adding a new query page requires zero backend changes → just add one template configuration. This is exactly the technical premise for “maintainable without dedicated IT staff”.
No SQL appears in the client → permissions and data scope are controlled uniformly server-side, and won't leak because the client is decompiled.
Desktop and mobile share the same logic → avoids misalignment problems like “it can be found on the PC but not on the phone”.
By the way: this setup only works if the existing system already centralizes SQL management. If SQL is scattered around, building the gateway will be very painful — the return on this investment only shows up later.
5. Four pitfalls we hit
Pitfall 1: Everything works in development, then all requests fail after release
Symptom: local debugging works fine; after submitting for review and releasing, all API requests fail.
Cause: WeChat Mini Program network requests have a hard constraint — they must be HTTPS, and the domain must be configured as a legal domain in the Mini Program admin console in advance. During development you can check “do not validate legal domains”, so the problem doesn't show up locally.
Checklist:
- Is the API domain HTTPS? (Self-signed certificates don't count; it must be issued by a trusted CA.)
- Has the domain completed ICP filing? (Unfiled domains cannot be added to the whitelist.)
- Has it been configured under Mini Program admin → Development Management → Server Domains? (Request domains and upload domains must be configured separately.)
- Does the domain include a port number? (If so, it must be written out, and some scenarios restrict ports.)
- After changing a domain, you must submit for review again — whitelist changes do not affect the already-released version; a new release is required.
Lesson learned: this kind of problem must be verified before the first review submission, not discovered after approval. The release process should include a step: “configure domain whitelist first, then submit for review.”
Pitfall 2: Each scan pops a page; scanning ten times requires popping ten times
Symptom: wx.scanCode uses a “open a full-screen scan interface → return result” model. If it's called repeatedly within a page, it can end up as “after one scan, the page gets popped”.
Cause: scanning is a separate page. If the page stack isn't handled properly on return, the navigation hierarchy gets confused. This is especially noticeable on Android.
Handling:
- Handle scan results with callbacks; don't rely on page-return events.
- Let the scan page maintain its own “continuous scanning” state; don't re-invoke the stack each time.
- Keep a persistent back button — when a warehouse keeper scans the wrong code, they need to return to the list in one tap. Don't rely only on the system back gesture; in a workshop with gloves on, the gesture often doesn't trigger.
Item 3 was changed based on real feedback: for any interface where employees wear gloves or operate with one hand, the system gesture cannot be the only way back.
Pitfall 3: Unstable barcode recognition, especially for self-printed labels
Symptom: factory-printed product barcodes scan fine, but part-number labels printed with your own label printer often fail to scan.
The root cause is almost always the label itself, not the scanning code:
| Cause | Handling |
|---|---|
| Low print resolution, blurry barcode edges | Increase printing DPI; don't shrink the barcode too much |
| Label applied to a curved surface (e.g., wire reels, round cans) | Switch to smaller labels; avoid spanning the curved surface |
| Lamination glare / oil or dirt covering the barcode | Prompt the user to fall back to “manual entry + fuzzy search” |
| Label too small, camera can't focus | Provide a “zoom viewfinder” hint in the Mini Program |
The most important one: you must provide a fallback path of manual entry + fuzzy search. Scanning is an efficiency tool, not the only entry. If a scan failure completely blocks the workflow, employees will simply abandon the whole system — that's the real reason many warehouse systems fail after rollout.
Pitfall 4: Shared accounts across multiple people cause mixed-up data attribution
Symptom: to save trouble, several people in the warehouse share one account. As a result, the operator on every inbound/outbound record is the same person.
The problem isn't technical; it's in permission design: ERP documents need an operator trace. Sharing an account means the audit trail is broken — when something goes wrong, you can't tell who did it.
Handling: one account per person, at very low cost. With ERP's per-user pricing, opening a few more accounts for warehouse roles costs far less than the loss from one stocktake discrepancy. Also apply permission tightening:
Warehouse keeper account → can only see: inbound/outbound, stock queries
→ cannot see: finance, purchase prices, customer information
This isn't just an administrative requirement; it's also the data isolation that any multi-client system must implement — if a phone is lost or an account is stolen, the scope of damage must be controllable.
6. Boundaries: which scenarios are not suitable for a Mini Program PDA
This must be stated clearly, otherwise it sets wrong expectations.
| Scenario | Mini Program suitable? | Notes |
|---|---|---|
| Barcode inbound/outbound, stock queries | ✅ Very suitable | The scenario of this article |
| Photo-based document entry (delivery notes, receipts) | ✅ Suitable | Naturally pairs with OCR recognition |
| Single-person low-frequency work (dozens of times per day) | ✅ Suitable | A phone is entirely enough |
| High-frequency sorting in a large warehouse (thousands of times per day) | ❌ Not suitable | Industrial PDAs are far more efficient with physical keys and professional scan engines |
| Signal-free warehouses (basement / cold storage) | ⚠️ Needs extra design | Requires local caching + deferred upload after recovery; complexity rises significantly |
| On-site label printing | ⚠️ Limited capability | Mini Program Bluetooth printer support is weaker than native; recommend cloud printers or keep a PC |
In one sentence: Mini Programs suit “lightweight, multi-person, real-time” warehouse floor work, not “high-frequency, heavy-duty, strongly offline” sorting centers.
7. Results
After getting it running, the actual improvements are mainly on three levels:
| Aspect | Before | After |
|---|---|---|
| Scanning tool | None (or industrial PDA purchased, 2,000–5,000 RMB/unit) | Employees' own phones, zero hardware cost |
| Data timeliness | Back at the office to re-enter, half a day to a day delay | Immediate on site, inventory accurate in real time |
| Fields entered | Part number, name, specification, unit, quantity all typed manually | Scanning brings in the first four; only quantity needs to be typed |
| Maintenance cost | Install APKs, upgrade unit by unit | Zero install, server-side upgrade |
In real customer feedback, the fastest benefit is usually not “how much time was saved” but the disappearance of discrepancies between books and actual stock:
An existing customer (a 50-person electronics company) completed full-process rollout within one month. Of that, just the “customer part number reverse lookup to internal part number” feature saved the workload of one full-time reconciliation staff member — because previously reconciliation required manually translating the customer part numbers on delivery notes into internal part numbers; now scanning does it automatically.