Bot Jualan dengan Update Stok Real-time

Cara buat bot jualan WhatsApp dengan stok real-time. Auto update, low stock alert, prevent oversell. Tutorial lengkap!

Bot Jualan dengan Update Stok Real-time
Bot Jualan dengan Update Stok Real-time

Oversell = Masalah besar!

Customer order, ternyata stok habis. Kecewa, refund, trust hilang.

Solusinya: Bot dengan stok real-time!


Fitur Stok Management

✅ Cek stok otomatis saat customer tanya
✅ Auto update setelah order
✅ Low stock alert ke admin
✅ Auto "Sold Out" jika habis
✅ Restock notification ke customer

Flow Stok Real-time

Customer: "Stok sepatu size 42?"
    ↓
Bot: Query database
    ↓
Bot: "Sepatu A size 42: Ready 5 pcs! ✅"

--- Saat Order ---
Customer: Order 2 pcs
    ↓
Bot: Update stok 5 → 3
    ↓
Bot: "Order confirmed! Stok tersisa: 3"

--- Low Stock ---
Stok = 3 (threshold: 5)
    ↓
Bot: Alert admin "Stok menipis!"

Template Response Stok

Cek Stok:

📦 STOK [PRODUK]

[Gambar Produk]

Size 40: ✅ Ready (8 pcs)
Size 41: ✅ Ready (5 pcs)
Size 42: ✅ Ready (3 pcs)
Size 43: ⚠️ Sisa 1 pcs!
Size 44: ❌ Sold Out

💰 Harga: Rp 250.000

Mau order? Ketik:
ORDER [PRODUK] [SIZE] [QTY]

Stok Habis:

😢 MAAF, STOK HABIS!

[PRODUK] [SIZE/VARIAN] sedang kosong.

Pilihan:
1. Pre-order (estimasi restock: [TANGGAL])
2. Pilih size/warna lain
3. Notif saat restock

Reply:
- PO - untuk pre-order
- LAIN - lihat varian lain
- NOTIF - dapat notifikasi restock

Restock Notification:

🔔 BACK IN STOCK!

Hai Kak [NAMA]!

[PRODUK] yang kemarin habis sudah ready!

📦 Stok: [QTY] pcs
💰 Harga: Rp [HARGA]

Siapa cepat dia dapat!
Reply ORDER untuk beli sekarang.

Low Stock Alert (ke Admin):

⚠️ LOW STOCK ALERT!

Produk: [NAMA]
Varian: [VARIAN]
Stok sekarang: [QTY]
Threshold: [THRESHOLD]

Action needed:
- Restock segera
- Atau update status ke "Pre-order"

Implementasi

Database Schema:

javascript

// Products collection
{
    id: 'PRD001',
    name: 'Sepatu Sneakers A',
    price: 250000,
    variants: [
        { size: '40', stock: 8 },
        { size: '41', stock: 5 },
        { size: '42', stock: 3 },
        { size: '43', stock: 1 },
        { size: '44', stock: 0 }
    ],
    lowStockThreshold: 3,
    notifyOnRestock: ['628xxx', '628yyy'] // Customers waiting
}

Check Stock Function:

javascript

async function checkStock(productId, variant) {
    const product = await db.products.findById(productId);
    const variantData = product.variants.find(v => v.size === variant);
    
    return {
        available: variantData.stock > 0,
        quantity: variantData.stock,
        isLow: variantData.stock <= product.lowStockThreshold
    };
}

// Bot handler
client.on('message', async msg => {
    const text = msg.body.toLowerCase();
    
    if (text.startsWith('stok ')) {
        const productName = text.replace('stok ', '');
        const product = await findProduct(productName);
        
        if (product) {
            await msg.reply(formatStockMessage(product));
        } else {
            await msg.reply('Produk tidak ditemukan. Ketik KATALOG untuk lihat produk.');
        }
    }
});

Update Stock on Order:

javascript

async function processOrder(order) {
    const product = await db.products.findById(order.productId);
    const variant = product.variants.find(v => v.size === order.size);
    
    // Check availability
    if (variant.stock < order.quantity) {
        return { success: false, message: 'Stok tidak cukup!' };
    }
    
    // Decrease stock
    variant.stock -= order.quantity;
    await db.products.update(product.id, { variants: product.variants });
    
    // Check low stock
    if (variant.stock <= product.lowStockThreshold) {
        await sendLowStockAlert(product, variant);
    }
    
    // Check sold out
    if (variant.stock === 0) {
        await notifyWaitingCustomers(product, variant);
    }
    
    return { success: true, remainingStock: variant.stock };
}

Restock & Notify:

javascript

async function restockProduct(productId, variant, quantity) {
    const product = await db.products.findById(productId);
    const variantData = product.variants.find(v => v.size === variant);
    
    const wasOutOfStock = variantData.stock === 0;
    variantData.stock += quantity;
    
    await db.products.update(productId, { variants: product.variants });
    
    // Notify waiting customers
    if (wasOutOfStock && product.notifyOnRestock.length > 0) {
        for (const phone of product.notifyOnRestock) {
            await sendRestockNotification(phone, product, variant);
        }
        
        // Clear notification list
        product.notifyOnRestock = [];
        await db.products.update(productId, { notifyOnRestock: [] });
    }
}

Sync dengan Inventory System

Untuk yang pakai sistem lain:

javascript

// Sync dari sistem inventory external
async function syncInventory() {
    const externalStock = await inventoryAPI.getAll();
    
    for (const item of externalStock) {
        await db.products.update(
            { sku: item.sku },
            { $set: { 'variants.$[].stock': item.quantity } }
        );
    }
}

// Run setiap 5 menit
cron.schedule('*/5 * * * *', syncInventory);

Webhook dari Marketplace:

javascript

// Terima update dari Tokopedia/Shopee
app.post('/webhook/marketplace-stock', async (req, res) => {
    const { sku, newStock } = req.body;
    
    await db.products.update(
        { sku },
        { $set: { stock: newStock } }
    );
    
    res.status(200).send('OK');
});

Best Practices

1. Buffer Stock

Tampilkan stok - buffer untuk safety:

Actual: 10 pcs
Display: 8 pcs (buffer 2)

Mencegah race condition oversell.

2. Real-time vs Near Real-time

Real-time: Setiap transaksi update
Near real-time: Sync setiap 1-5 menit

Untuk volume tinggi, near real-time lebih praktis.

3. Reservation System

Saat customer mulai checkout:
→ Reserve stok 15 menit
→ Jika tidak bayar, release kembali

Mencegah stok "terkunci" oleh yang tidak jadi beli.

FAQ

Bagaimana jika 2 customer order bersamaan?

Gunakan database transaction atau locking untuk prevent race condition. First come first served.

Perlu sync dengan marketplace?

Ideal ya! Jika jualan di Tokopedia + Shopee + WA, stok harus sinkron supaya tidak oversell.

Bagaimana handle pre-order?

Stok 0 tapi masih bisa order = Pre-order mode. Set flag allowPreorder: true dan tampilkan estimasi restock.


Kesimpulan

Real-time stock = No more oversell!

Tanpa Real-timeDengan Real-time
Oversell seringStok akurat
Manual updateAuto update
Customer kecewaCustomer happy

Prevent oversell, build trust!

Setup Stock Bot →


Artikel Terkait