การเชื่อมต่อ WMS สำหรับอีคอมเมิร์ซขนาดเล็ก
ธุรกิจอีคอมเมิร์ซขนาดเล็กมักต้องพิจารณาว่าเมื่อใดจึงคุ้มที่จะเชื่อมต่อระบบจัดการคลังสินค้า (WMS) เร็วกว่าที่คาด สเปรดชีตใช้งานได้ดีจนถึงจุดที่ไม่พอ และจุดเปลี่ยนมักไม่ใช่ปริมาณคำสั่งซื้อ แต่เป็นความซับซ้อน เช่น SKU หลายรายการที่ต้องติดตามรูปแบบย่อยของสินค้า ชุดสินค้า คำสั่งซื้อค้างส่งจากหลายจุดจัดส่ง หรือความต้องการจำนวนสินค้าที่รับปากจัดส่งได้อย่างแม่นยำในขั้นตอนชำระเงิน บทความนี้เล่าประสบการณ์เชื่อมต่อ GreaterWMS กับธุรกิจอีคอมเมิร์ซขนาดเล็ก ทั้งสิ่งที่ได้ผล สิ่งที่ต้องออกแบบมากกว่าที่คาด และกรณีที่สเปรดชีตยังเป็นคำตอบที่เหมาะสม
ทำไมจึงเลือก GreaterWMS
GreaterWMS เป็นระบบจัดการคลังสินค้าโอเพนซอร์สที่มี REST API ใช้ Django เป็น backend และ Vue เป็น frontend รองรับสินค้าคงคลังหลายคลัง การติดตามล็อตและชุดการผลิต การจัดการคำสั่งรับสินค้าเข้าและส่งสินค้าออก และรายงานพื้นฐาน โค้ดยังได้รับการดูแลอย่างต่อเนื่อง และเอกสาร API แม้ไม่ครอบคลุมทุกอย่าง ก็อธิบายการทำงานหลักไว้
เราเลือกแทนบริการที่ผู้ให้บริการดูแลให้ด้วยสองเหตุผล ประการแรก เรามีโครงสร้างพื้นฐานที่ติดตั้งและดูแลเองอยู่แล้ว และไม่ต้องการพึ่ง SaaS เพิ่มที่คิดราคาต่อคำสั่งซื้อเมื่อขยายงาน ประการที่สอง ความเป็นโอเพนซอร์สทำให้ขยายแบบจำลองข้อมูลได้โดยไม่ต้องรอรอบการพิจารณาคำขอฟีเจอร์จากผู้ให้บริการ ความยืดหยุ่นนี้สำคัญต่อธุรกิจเล็กที่ต้องติดตามวันหมดอายุของล็อตเป็นพิเศษ
เรานำระบบขึ้นใช้งานด้วย Docker Compose ซึ่งประกอบด้วยแอปพลิเคชัน Django, PostgreSQL และ Redis ส่วนไฟล์ Compose ของโครงการต้นทางมีเฉพาะคอนเทนเนอร์ frontend และ backend และการตั้งค่าเริ่มต้นใช้ SQLite บน VPS สเปกไม่สูงก็ทำงานร่วมกับบริการอื่นได้สบาย การตั้งค่าเริ่มต้นใช้ไม่กี่ชั่วโมง แต่งานเชื่อมต่อระบบใช้เวลานานกว่านั้นมาก
รูปแบบการเชื่อมต่อผ่าน API
GreaterWMS ใช้การยืนยันตัวตนด้วยโทเคน ผู้ใช้แต่ละรายมีโทเคน (ค่า openid) ซึ่งส่งผ่านเฮดเดอร์คำขอที่กำหนดเองชื่อ token แทนการส่งเป็น Bearer token ในเฮดเดอร์ Authorization ไม่มีขั้นตอน OAuth หรือกลไกหมุนเวียนคีย์ API ในตัว จึงควรสร้างผู้ใช้สำหรับบริการโดยเฉพาะและให้สิทธิ์เท่าที่จำเป็น แทนการใช้บัญชีผู้ดูแลระบบ
API ส่วนใหญ่เป็นแบบ RESTful และส่งข้อมูล JSON ทรัพยากรหลักที่ใช้เชื่อมต่ออีคอมเมิร์ซคือ goods ซึ่งหมายถึงแคตตาล็อกสินค้าใน WMS, inventory ซึ่งเป็นจำนวนสินค้าคงเหลือแยกตามคลังและสินค้า, inbound orders สำหรับคำสั่งซื้อจากผู้จัดหาและการคืนสินค้า และ outbound orders สำหรับคำสั่งซื้อของลูกค้าที่ต้องจัดการและจัดส่ง
รูปแบบหนึ่งที่เรากำหนดตั้งแต่แรกคือไม่เรียก WMS API แบบรอผลในเส้นทางชำระเงิน WMS ไม่อยู่บนเส้นทางธุรกรรมหลัก และหากช้าหรือใช้ไม่ได้ชั่วคราว ก็ไม่ควรกระทบการซื้อของลูกค้า การติดต่อ WMS ทั้งหมดผ่านคิวแบบไม่รอผล ขั้นตอนชำระเงินบันทึกคำสั่งซื้อในฐานข้อมูลหลักและเผยแพร่เหตุการณ์ ตัวประมวลผลงานเบื้องหลังรับเหตุการณ์แล้วสร้างคำสั่งส่งสินค้าออกใน GreaterWMS หากล้มเหลวจะลองใหม่โดยเพิ่มระยะรอแบบทวีคูณ และแจ้งเตือนหากยังล้มเหลวต่อเนื่อง การแยกส่วนนี้เป็นข้อกำหนดที่ต่อรองไม่ได้
การซิงค์คำสั่งซื้อ
คำขอสร้างคำสั่งส่งสินค้าออกต้องระบุ goods ID จำนวน และที่อยู่ปลายทาง ต้องรักษาการจับคู่ระหว่างรายการในคำสั่งซื้ออีคอมเมิร์ซกับ goods ID ของ WMS อย่างชัดเจน เราเก็บ WMS goods ID เป็นฟิลด์เพิ่มเติมของสินค้าแต่ละรูปแบบย่อยในฐานข้อมูลแคตตาล็อก กำหนดการจับคู่ด้วยตนเองเมื่อสร้างสินค้าใหม่ และตรวจในตัวประมวลผลงานซิงค์ก่อนส่งคำขอสร้างคำสั่งส่งสินค้าออก
การซิงค์สถานะทำงานในทิศทางตรงข้าม GreaterWMS อัปเดตสถานะคำสั่งส่งสินค้าออกตามการดำเนินงานของคลัง และระบบอีคอมเมิร์ซต้องแสดงสถานะนั้นด้วย GreaterWMS ไม่ส่งการเปลี่ยนสถานะมาให้ จึงต้องสอบถามเป็นระยะ เรามีงานสอบถามทุกไม่กี่นาทีเพื่อดูคำสั่งส่งสินค้าออกที่มีสถานะ “in progress” ว่าเปลี่ยนเป็น “dispatched” หรือ “cancelled” หรือยัง หากเปลี่ยนแล้ว เราอัปเดตคำสั่งซื้อที่ตรงกันในฐานข้อมูลอีคอมเมิร์ซและเรียกงานต่อเนื่อง เช่น ส่งอีเมลแจ้งลูกค้าและอัปเดตเลขติดตามพัสดุ
การทำซ้ำโดยไม่เกิดผลซ้ำซ้อน (idempotency) สำคัญต่อการสร้างคำสั่งส่งสินค้าออก หากตัวประมวลผลงานเบื้องหลังลองใหม่หลังความขัดข้องชั่วคราว ต้องไม่สร้างคำสั่งซ้ำใน GreaterWMS เราบันทึก ID ของคำสั่งส่งสินค้าออกใน WMS ลงในข้อมูลคำสั่งซื้อภายในทันทีหลังสร้างสำเร็จ เมื่อลองใหม่ ตัวประมวลผลงานตรวจว่ามี WMS ID แล้วหรือไม่ก่อนเรียกสร้าง หากมีจะข้ามการสร้างและทำงานต่อเนื่องที่กำลังพยายามทำอยู่ การตรวจนี้ไม่ครอบคลุมกรณีที่การเรียกสร้างสำเร็จใน GreaterWMS แต่คำตอบสูญหายก่อนบันทึก ID กรณีเหล่านี้ยังต้องตรวจสอบเทียบกับ WMS ก่อนลองใหม่
การอัปเดตสินค้าคงคลัง
การรักษาจำนวนสินค้าคงคลังของอีคอมเมิร์ซให้ตรงกับ WMS เป็นส่วนที่ต้องใส่ใจต่อเนื่องมากที่สุด มีสองทิศทางคือแพลตฟอร์มอีคอมเมิร์ซต้องมีจำนวนสินค้าคงเหลือที่แม่นยำเพื่อป้องกันขายเกิน และ WMS ต้องสะท้อนการซื้อกับการคืนสินค้าที่เริ่มจากภายนอก
สำหรับการอ่านจำนวนสินค้าคงเหลือ เราดึงภาพรวมสินค้าคงคลังจาก GreaterWMS inventory API ตามกำหนด แล้วเขียนลงแคช Redis ที่หน้าร้านอีคอมเมิร์ซอ่านใช้ ความถี่ขึ้นกับอัตราการขาย สินค้าขายช้าใช้รายชั่วโมงได้ แต่สินค้าที่ขายพุ่งเป็นช่วงต้องสอบถามถี่ขึ้น หรือมีรูปแบบจองสินค้า โดยเมื่อลูกค้าใส่สินค้าลงตะกร้าจะจองไว้ชั่วคราวโดยไม่ขึ้นกับรอบซิงค์ WMS
การคืนสินค้าซับซ้อนที่สุด สินค้าที่คืนอาจกลับเข้าคลัง ไปยังพื้นที่แยกเพื่อตรวจสอบ หรือถูกตัดออกจากสินค้าคงคลัง GreaterWMS มีขั้นตอนรับสินค้าเข้าสำหรับการคืน แต่ต้องออกแบบการจับคู่สถานะคืนสินค้าของอีคอมเมิร์ซกับสถานะคำสั่งรับสินค้าเข้าอย่างชัดเจน เราสร้างกลไกสถานะที่แปลงรหัสเหตุผลการคืนจากระบบอีคอมเมิร์ซเป็นรหัสวิธีจัดการสินค้าใน WMS และทบทวนการจับคู่กับทีมคลังทุกครั้งที่เพิ่มเหตุผลการคืนใหม่ หากไม่มีการจับคู่นี้ สินค้าที่คืนจะไม่กลับมาอยู่ในจำนวนพร้อมขายโดยไม่มีสัญญาณเตือน
ภาวะแข่งขันในการเข้าถึงทรัพยากรและสินค้าสำรอง
แม้ซิงค์สินค้าคงคลังด้วยการสอบถามเป็นระยะ ก็ยังเกิดภาวะแข่งขันในการเข้าถึงทรัพยากรได้ หากคำสั่งซื้อสองรายการมาพร้อมกันและอ่านจำนวนในแคชเดียวกันก่อนที่รายการใดจะถูกสะท้อนใน WMS อาจขายเกินเท่ากับจำนวนที่ขายได้ในช่วงระหว่างรอบสอบถาม สำหรับสินค้าที่ขายเกินไม่ได้ เช่น รุ่นจำกัดหรือสินค้าเน่าเสียง่ายที่มีข้อจำกัดล็อตเข้มงวด แนวทางที่เหมาะคือชั้นจองสินค้าที่ลดจำนวนพร้อมขายในระบบภายในเมื่อชำระเงิน และกระทบยอดกับ WMS แบบไม่รอผล
วิธีลดความเสี่ยงที่ง่ายกว่าคือสินค้าสำรอง เก็บจำนวนพร้อมขายในฐานข้อมูลอีคอมเมิร์ซเป็นจำนวนใน WMS หักจำนวนสำรองเล็กน้อย คำสั่งซื้อจะลดจำนวนที่กันไว้ เมื่อจำนวนนี้เป็นศูนย์ หน้าร้านแสดงว่าสินค้าหมดแม้ WMS ยังมีสินค้า วิธีนี้เสี่ยงเล็กน้อยที่จะมีสินค้าซึ่งลูกค้าสั่งไม่ได้ แต่ลดความเสี่ยงขายเกินและไม่ต้องมีตรรกะการจอง สำหรับธุรกิจเล็กส่วนใหญ่ วิธีสำรองสินค้าเป็นทางเลือกที่คุ้มค่า
เมื่อใดควรใช้ WMS แทนสเปรดชีต
ระบบจัดการคลังสินค้าเพิ่มความซับซ้อนในการเชื่อมต่อ ภาระในการดำเนินงาน และระบบใหม่ที่ต้องดูแล ก่อนเริ่มเชื่อมต่อ ควรประเมินตรง ๆ ว่าปัญหาที่ต้องการแก้จำเป็นต้องใช้ WMS จริงหรือไม่
สเปรดชีตเพียงพอเมื่อจำนวน SKU น้อยและคงที่ มีคลังหรือจุดจัดส่งแห่งเดียว ประมวลผลคำสั่งซื้อด้วยมือและมีปริมาณต่ำ และไม่ต้องแสดงจำนวนที่รับปากจัดส่งได้แบบเรียลไทม์ในขั้นตอนชำระเงิน ในกรณีนี้ ต้นทุนสร้างและดูแลการเชื่อมต่อ WMS สูงกว่าปัญหาที่แก้ได้
WMS เริ่มคุ้มเมื่อมีหลายคลังหรือหลายจุดหยิบสินค้า ต้องติดตามล็อตหรือชุดการผลิตเพื่อการปฏิบัติตามกฎระเบียบหรือคุณภาพ อัตราคืนสินค้าสูงจนต้องจัดการอย่างเป็นระบบ หรือประมวลผลคำสั่งซื้ออัตโนมัติและต้องจองสินค้าอย่างแม่นยำเพื่อป้องกันขายเกิน เหล่านี้เป็นปัญหาการดำเนินงานที่สเปรดชีตแก้ให้รัดกุมในระดับสมเหตุผลไม่ได้จริง
งานเชื่อมต่อในบทความนี้ใช้เวลาวิศวกรรมหลายสัปดาห์รวมการทดสอบ เวลาดังกล่าวใช้ประสานงานคลังด้วยมือได้มากทีเดียว ก่อนเริ่มต้องระบุให้ชัดว่าจะแก้ปัญหาใด และซอฟต์แวร์เป็นเครื่องมือที่เหมาะหรือไม่