Bot Jualan dengan Reminder Repeat Order
Cara buat bot jualan WhatsApp dengan reminder repeat order. Reorder otomatis, replenishment, tingkatkan retention!
Customer lama lebih valuable dari customer baru!
Tapi sering lupa reorder. Bot bisa reminder otomatis di waktu yang tepat supaya mereka beli lagi!
Produk yang Cocok untuk Repeat Reminder
🔄 Consumables (habis pakai):
- Skincare, makeup
- Makanan, minuman
- Suplemen, vitamin
- Sabun, shampoo
📅 Subscription-like:
- Susu formula
- Pet food
- Refill tinta/cartridge
- Obat rutin
⏰ Seasonal:
- Fashion per musim
- Perlengkapan sekolah
- Dekorasi hari rayaTiming Reminder
CONSUMABLES:
Estimasi habis → Reminder H-7
Contoh:
Skincare 30ml (pemakaian 1 bulan)
Order: 1 Jan
Reminder: 24 Jan (H-7 habis)
SUBSCRIPTION-LIKE:
Fixed interval (30 hari, 60 hari)
SEASONAL:
Mendekati event/musimTemplate Reminder
Standard Repeat Reminder:
🔔 REMINDER REORDER
Hai Kak [NAMA]! 👋
[PRODUK] yang kamu beli sebulan lalu
mungkin sudah mau habis nih!
📦 [NAMA PRODUK]
💰 Harga: Rp [HARGA]
Reorder sekarang:
- REORDER - Beli lagi (sama persis)
- UBAH - Mau ganti varian/qty
🎁 Bonus loyal customer:
Free ongkir untuk reorder! 🚚With Incentive:
🔔 SUDAH MAU HABIS?
Hai Kak [NAMA]!
Serum yang kamu beli kemarin sudah sebulan!
Waktunya restock sebelum kehabisan 😊
📦 [NAMA PRODUK] - Rp [HARGA]
🎁 SPECIAL REORDER:
Diskon 10% untuk pembelian kedua!
Kode: LOYAL10
Mau reorder?
Ketik REORDER untuk beli lagi!Running Low Alert:
⚠️ STOK MUNGKIN TINGGAL SEDIKIT
Hai Kak [NAMA]!
Berdasarkan pembelian terakhir:
📦 [PRODUK] - dibeli [TANGGAL]
Estimasi tersisa: ~1 minggu lagi
Restock sekarang supaya tidak kehabisan!
💰 Rp [HARGA]
🚚 Free ongkir!
- REORDER - Beli sekarang
- NANTI - Ingatkan minggu depan
- STOP - Jangan ingatkan lagiSubscription Offer:
💡 MAU LEBIH PRAKTIS?
Hai Kak [NAMA]!
Kamu sudah 3x reorder [PRODUK]!
Terima kasih atas loyalitasnya 💕
Mau coba LANGGANAN BULANAN?
✅ Auto-kirim setiap bulan
✅ Diskon 15% permanen
✅ Free ongkir selalu
✅ Bisa pause/cancel kapan saja
💰 Rp [HARGA] → Rp [HARGA DISKON]/bulan
- LANGGANAN - Daftar sekarang
- BIASA - Tetap beli manualImplementasi
Track Order for Reminder:
javascript
// Saat order completed, schedule reminder
async function scheduleRepeatReminder(order) {
for (const item of order.items) {
const product = await db.products.findOne({ code: item.productCode });
if (product.replenishmentDays) {
const reminderDate = addDays(
new Date(),
product.replenishmentDays - 7 // Remind 7 days before
);
await db.reminders.insert({
customerId: order.customerId,
customerPhone: order.customerPhone,
productCode: item.productCode,
productName: item.productName,
lastOrderDate: new Date(),
reminderDate: reminderDate,
status: 'pending'
});
}
}
}Product Schema:
javascript
{
code: 'SKC001',
name: 'Serum Vitamin C',
price: 150000,
category: 'skincare',
// Replenishment settings
replenishmentDays: 30, // Habis dalam 30 hari
reminderEnabled: true,
reminderMessage: 'Serum kamu mungkin sudah mau habis!',
// Subscription option
subscriptionAvailable: true,
subscriptionDiscount: 15
}Daily Reminder Cron:
javascript
// Run setiap pagi jam 9
cron.schedule('0 9 * * *', async () => {
const today = new Date();
today.setHours(0, 0, 0, 0);
const tomorrow = addDays(today, 1);
// Get reminders for today
const dueReminders = await db.reminders.find({
reminderDate: { $gte: today, $lt: tomorrow },
status: 'pending'
});
for (const reminder of dueReminders) {
await sendRepeatReminder(reminder);
await db.reminders.update(reminder.id, {
status: 'sent',
sentAt: new Date()
});
}
});Handle Response:
javascript
client.on('message', async msg => {
const text = msg.body.toUpperCase();
if (text === 'REORDER') {
const lastOrder = await getLastOrder(msg.from);
if (lastOrder) {
// Create new order with same items
const newOrder = await createReorder(msg.from, lastOrder);
await msg.reply(formatReorderConfirmation(newOrder));
}
}
if (text === 'NANTI') {
// Reschedule reminder +7 days
await rescheduleReminder(msg.from, 7);
await msg.reply('Oke, akan kami ingatkan minggu depan ya! 😊');
}
if (text === 'STOP') {
// Opt-out from reminders
await optOutReminder(msg.from);
await msg.reply('Baik, tidak akan mengirim reminder lagi untuk produk ini.');
}
});Quick Reorder:
javascript
async function createReorder(customerPhone, lastOrder) {
const customer = await db.customers.findOne({ phone: customerPhone });
// Check stock availability
for (const item of lastOrder.items) {
const stock = await checkStock(item.productCode, item.variant);
if (!stock.available) {
throw new Error(`${item.productName} tidak tersedia`);
}
}
// Create new order with same items
const newOrder = {
customerId: customer.id,
customerPhone,
customerName: customer.name,
address: lastOrder.address, // Same address
items: lastOrder.items,
subtotal: recalculateSubtotal(lastOrder.items),
shipping: lastOrder.shipping,
total: recalculateTotal(lastOrder.items),
isReorder: true,
originalOrderId: lastOrder.id,
status: 'pending_payment',
createdAt: new Date()
};
await db.orders.insert(newOrder);
// Apply loyalty discount if applicable
if (customer.reorderCount >= 3) {
newOrder.discount = newOrder.subtotal * 0.1;
newOrder.total -= newOrder.discount;
}
return newOrder;
}Smart Reminder Timing
javascript
// Personalize based on actual purchase pattern
async function calculateOptimalReminderDate(customerId, productCode) {
// Get purchase history for this product
const history = await db.orders.find({
customerId,
'items.productCode': productCode
}).sort({ createdAt: -1 }).limit(5);
if (history.length < 2) {
// Not enough data, use default
const product = await db.products.findOne({ code: productCode });
return addDays(new Date(), product.replenishmentDays - 7);
}
// Calculate average days between purchases
const intervals = [];
for (let i = 0; i < history.length - 1; i++) {
const days = daysBetween(history[i].createdAt, history[i + 1].createdAt);
intervals.push(days);
}
const avgInterval = intervals.reduce((a, b) => a + b, 0) / intervals.length;
// Remind 7 days before expected reorder
return addDays(new Date(), avgInterval - 7);
}Best Practices
1. Respect Opt-out
Selalu ada opsi STOP.
Jangan spam yang sudah opt-out!2. Relevant Timing
❌ Remind 2 hari setelah beli (too early)
❌ Remind 3 bulan kemudian (too late)
✅ Remind menjelang habis (just right)3. Value, Not Just Reminder
❌ "Beli lagi dong"
✅ "Supaya tidak kehabisan, reorder sekarang + free ongkir!"4. Easy One-Click Reorder
❌ Harus isi form lagi
✅ Ketik REORDER → Sama persis dengan sebelumnyaFAQ
Berapa sering reminder?
Max 1x per product per cycle. Jika tidak response, reminder ulang 7 hari kemudian, lalu stop.
Bagaimana tahu kapan produk habis?
Estimasi berdasarkan rata-rata pemakaian atau packaging (misal 30ml = 30 hari).
Perlu integrasi dengan inventory?
Nice to have untuk suggest restock saat stok tersedia. Tapi basic reminder bisa tanpa integrasi.
Kesimpulan
Repeat reminder = Automated retention!
| Tanpa Reminder | Dengan Reminder |
|---|---|
| Customer lupa | Diingatkan tepat waktu |
| Low retention | Higher retention |
| Missed revenue | Consistent reorders |
Don't let customers forget you!