# Segmentasi Pelanggan RFM - Bisnis Frozen Food Berikut 5 segmen pelanggan yang dirancang berdasarkan pola beli khas bisnis frozen food (repeat order tinggi, siklus pembelian pendek-menengah): --- ## 🌟 1. JUARA (Champions) **Kriteria RFM:** Recency tinggi, Frequency tinggi, Monetary tinggi (skor 4-5 semua) **Karakteristik:** Beli rutin, belanja besar, baru-baru ini order **Strategi Sales:** - Prioritaskan stok & pengiriman tercepat - Tawarkan program loyalitas/harga khusus - Jadikan referensi/testimoni untuk pelanggan baru --- ## 💎 2. PELANGGAN SETIA (Loyal Customers) **Kriteria RFM:** Recency sedang-tinggi, Frequency tinggi, Monetary sedang-tinggi **Karakteristik:** Order konsisten tiap periode, meski nominal tidak sebesar Juara **Strategi Sales:** - Cross-selling produk baru - Bundling promo untuk naikkan nilai transaksi - Reminder order rutin (WA blast otomatis) --- ## ⚠️ 3. BERISIKO KABUR (At Risk) **Kriteria RFM:** Recency rendah, Frequency tinggi, Monetary tinggi (dulu bagus, sekarang mulai jarang) **Karakteristik:** Dulu pelanggan besar, tapi sudah lama tidak order **Strategi Sales:** - **Prioritas follow-up manual** oleh sales - Tanya kendala (kompetitor? masalah pengiriman? harga?) - Tawarkan diskon "welcome back" atau insentif khusus --- ## 🌱 4. PELANGGAN BARU (New Customers) **Kriteria RFM:** Recency tinggi, Frequency rendah, Monetary rendah-sedang **Karakteristik:** Baru 1-2x order, potensi berkembang **Strategi Sales:** - Follow up cepat untuk order kedua (masa kritis konversi) - Edukasi katalog produk lengkap - Berikan pengalaman layanan terbaik di awal --- ## 💤 5. TIDUR/HIBERNASI (Hibernating/Lost) **Kriteria RFM:** Recency rendah, Frequency rendah, Monetary rendah (skor 1-2 semua) **Karakteristik:** Sudah lama tidak order, dulu pun jarang & kecil nominalnya **Strategi Sales:** - Masukkan ke database low-priority - Broadcast promo massal (biaya rendah) saja - Tidak perlu alokasi waktu sales khusus, kecuali ada respon balik --- ## 📊 Ringkasan Matriks Cepat | Segmen | Recency | Frequency | Monetary | Prioritas Sales | |---|---|---|---|---| | Juara | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | Jaga & Kembangkan | | Pelanggan Setia | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | Upselling | | Berisiko Kabur | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | **URGENT - Reaktivasi** | | Pelanggan Baru | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ | Nurturing | | Tidur | ⭐ | ⭐ | ⭐ | Low-cost campaign | --- **Tips implementasi:** Gunakan warna berbeda di CRM/spreadsheet (Hijau=Juara, Biru=Setia, Merah=Berisiko, Kuning=Baru, Abu=Tidur) agar tim sales bisa langsung visual mengenali prioritas kontak harian.
# Query SQL untuk Menghitung Skor RFM
## Versi 1: PostgreSQL / MySQL 8+ (menggunakan NTILE)
```sql
WITH rfm_base AS (
-- Step 1: Hitung Recency, Frequency, Monetary per customer
SELECT
customer_id,
DATEDIFF(CURRENT_DATE, MAX(transaction_date)) AS recency_days,
COUNT(DISTINCT transaction_date) AS frequency,
SUM(amount) AS monetary
FROM transactions
GROUP BY customer_id
),
rfm_score AS (
-- Step 2: Beri skor 1-5 menggunakan NTILE
-- Recency: semakin kecil hari (baru beli) = skor tinggi, jadi urutan dibalik (5,4,3,2,1)
-- Frequency & Monetary: semakin besar nilai = skor tinggi
SELECT
customer_id,
recency_days,
frequency,
monetary,
NTILE(5) OVER (ORDER BY recency_days DESC) AS r_score,
NTILE(5) OVER (ORDER BY frequency ASC) AS f_score,
NTILE(5) OVER (ORDER BY monetary ASC) AS m_score
FROM rfm_base
)
-- Step 3: Gabungkan skor & buat segmen
SELECT
customer_id,
recency_days,
frequency,
monetary,
r_score,
f_score,
m_score,
CONCAT(r_score, f_score, m_score) AS rfm_score,
(r_score + f_score + m_score) AS total_score,
-- Segmentasi otomatis berdasarkan kombinasi skor
CASE
WHEN r_score >= 4 AND f_score >= 4 AND m_score >= 4
THEN 'Juara'
WHEN r_score >= 3 AND f_score >= 4
THEN 'Pelanggan Setia'
WHEN r_score <= 2 AND f_score >= 4 AND m_score >= 4
THEN 'Berisiko Kabur'
WHEN r_score >= 4 AND f_score <= 2
THEN 'Pelanggan Baru'
WHEN r_score <= 2 AND f_score <= 2 AND m_score <= 2
THEN 'Tidur/Hibernasi'
ELSE 'Lainnya'
END AS segment
FROM rfm_score
ORDER BY total_score DESC;
```
---
## Versi 2: Jika Ingin Set Parameter Tanggal Referensi (Rekomendasi)
```sql
WITH params AS (
-- Set tanggal analisis (bisa diganti manual atau pakai CURRENT_DATE)
SELECT DATE '2024-12-31' AS analysis_date
),
rfm_base AS (
SELECT
t.customer_id,
DATEDIFF(p.analysis_date, MAX(t.transaction_date)) AS recency_days,
COUNT(DISTINCT t.transaction_date) AS frequency,
SUM(t.amount) AS monetary
FROM transactions t
CROSS JOIN params p
GROUP BY t.customer_id, p.analysis_date
),
rfm_score AS (
SELECT
customer_id,
recency_days,
frequency,
monetary,
NTILE(5) OVER (ORDER BY recency_days DESC) AS r_score,
NTILE(5) OVER (ORDER BY frequency ASC) AS f_score,
NTILE(5) OVER (ORDER BY monetary ASC) AS m_score
FROM rfm_base
)
SELECT
customer_id,
recency_days,
frequency,
monetary,
r_score,
f_score,
m_score,
CONCAT(r_score, f_score, m_score) AS rfm_code,
CASE
WHEN r_score >= 4 AND f_score >= 4 AND m_score >= 4 THEN 'Juara'
WHEN r_score >= 3 AND f_score >= 4 THEN 'Pelanggan Setia'
WHEN r_score <= 2 AND f_score >= 4 AND m_score >= 4 THEN 'Berisiko Kabur'
WHEN r_score >= 4 AND f_score <= 2 THEN 'Pelanggan Baru'
WHEN r_score <= 2 AND f_score <= 2 AND m_score <= 2 THEN 'Tidur/Hibernasi'
ELSE 'Lainnya'
END AS segment
FROM rfm_score
ORDER BY (r_score + f_score + m_score) DESC;
```
---
## 📌 Catatan Penting
| Fungsi | PostgreSQL | MySQL 8+ | SQL Server |
|---|---|---|---|
| Hitung selisih hari | `CURRENT_DATE - MAX(date)` | `DATEDIFF(NOW(), date)` | `DATEDIFF(day, date, GETDATE())` |
| Window function NTILE | ✅ Native | ✅ Native | ✅ Native |
**Jika pakai PostgreSQL**, ganti bagian `DATEDIFF()` dengan:
```sql
(CURRENT_DATE - MAX(transaction_date)) AS recency_days
```
---
## 🎯 Cara Kerja Query Ini
1. **CTE `rfm_base`** → Hitung 3 metrik dasar per customer
2. **CTE `rfm_score`** → Gunakan `NTILE(5)` untuk bagi customer jadi 5 kelompok sama rata berdasarkan ranking
3. **Final SELECT** → Gabungkan 3 skor jadi kode RFM (misal: `545`) dan otomatis mapping ke nama segmen
---
## 💡 Tips Tambahan
Jika ingin **threshold custom** (bukan otomatis dari NTILE), Anda bisa ganti scoring manual:
```sql
r_score = CASE
WHEN recency_days <= 7 THEN 5
WHEN recency_days <= 14 THEN 4
WHEN recency_days <= 30 THEN 3
WHEN recency_days <= 60 THEN 2
ELSE 1
END
```
Ini lebih cocok untuk **frozen food** karena siklus beli biasanya mingguan/2 mingguan, jadi threshold bisa disesuaikan bisnis proses real, bukan sekadar pembagian rata (NTILE).
Mau saya buatkan versi dengan **threshold manual** yang lebih sesuai pola order frozen food (misal siklus mingguan)?
# Strategi Follow-Up Detail per Segmen RFM ### (Bisnis Distribusi Frozen Food) --- ## 🌟 1. JUARA (Champions) ### ⏰ Kapan Dihubungi - **Frekuensi:** 1x per minggu (proaktif, bukan menunggu mereka order) - **Waktu terbaik:** H-2 sebelum siklus order biasa mereka - **Channel:** WhatsApp personal + kunjungan langsung tiap bulan ### 🗣️ Nada Bicara - **Apresiatif & personal** — perlakukan seperti partner bisnis, bukan sekadar pembeli - Gunakan nama pemilik toko/bisnis, tanyakan kabar usaha - Hindari kesan "jualan", lebih ke *relationship maintenance* ### 💬 Contoh Script > "Selamat pagi Pak Budi! Gimana kabar tokonya? Stok ayam & nugget masih aman kah? Saya siapin batch fresh minggu ini, mau saya kirim seperti biasa atau ada tambahan item baru yang mau dicoba?" ### 🎁 Penawaran - **Prioritas stok** saat produk favorit langka - Harga khusus / diskon volume tanpa diminta - Info produk baru **duluan** sebelum pelanggan lain - Bonus kecil (free ongkir, sample produk baru) sebagai bentuk apresiasi ### ✅ Goal Pertahankan & tingkatkan nilai transaksi, jadikan brand advocate. --- ## 💎 2. PELANGGAN SETIA (Loyal Customers) ### ⏰ Kapan Dihubungi - **Frekuensi:** Sesuai siklus order mereka (mingguan/2 mingguan), +reminder H-1 - **Waktu terbaik:** Pagi hari (jam 08.00-10.00) sebelum mereka buka toko/mulai jualan - **Channel:** WhatsApp otomatis (template) + sales follow-up manual sesekali ### 🗣️ Nada Bicara - **Ramah & efisien** — fokus ke kemudahan proses order - Tidak perlu terlalu personal, tapi tetap hangat - Nada seperti "partner rutin yang dipercaya" ### 💬 Contoh Script > "Halo Bu Sari, sudah waktunya order mingguan nih! Stok chicken nugget & bakso lagi banyak, mau order jumlah biasa atau ada request tambahan?" ### 🎁 Penawaran - **Cross-selling**: tawarkan varian produk baru yang relevan - Bundling promo (beli 2 kategori dapat diskon) - Program poin/reward untuk order konsisten - Tawarkan **subscription order** agar makin rutin ### ✅ Goal Naikkan frequency & basket size, dorong ke level Juara. --- ## ⚠️ 3. BERISIKO KABUR (At Risk) ### ⏰ Kapan Dihubungi - **Frekuensi:** **SEGERA** dalam 1-3 hari setelah masuk kategori ini (jangan tunda!) - **Waktu terbaik:** Kapan saja, prioritaskan kontak personal (telepon > WA) - **Channel:** **Telepon langsung** dari sales senior, bukan WA broadcast ### 🗣️ Nada Bicara - **Empatik & investigatif** — tunjukkan kepedulian, bukan menuntut - Dengarkan keluhan tanpa defensif - Hindari kesan "menagih" atau "kenapa gak order lagi" ### 💬 Contoh Script > "Selamat siang Pak Joko, saya dari [Nama Perusahaan]. Sudah lama nih kita gak dengar kabar order dari Bapak, semoga usaha lancar ya. Boleh tau ada kendala apa? Apakah dari sisi stok, harga, atau mungkin ada yang kurang dari pelayanan kami kemarin?" ### 🎁 Penawaran - **Diskon "kami rindu Anda"** — potongan harga khusus untuk order berikutnya - Tanya kebutuhan spesifik & sesuaikan penawaran (jangan generic) - Jika masalah harga → nego atau tawarkan volume lebih kecil dulu - Jika masalah kompetitor → tunjukkan value tambahan (kualitas, kecepatan kirim) - Berikan **garansi/trial produk gratis** untuk buktikan komitmen ### ⚡ Prioritas Ini adalah segmen **PALING URGENT** — kehilangan pelanggan besar lebih mahal dari akuisisi baru. ### ✅ Goal Reaktivasi order dalam 7-14 hari, cari akar masalah churn. --- ## 🌱 4. PELANGGAN BARU (New Customers) ### ⏰ Kapan Dihubungi - **Frekuensi:** H+3 setelah transaksi pertama, lalu reminder H+10-14 (perkiraan siklus order kedua) - **Waktu terbaik:** Jangan terlalu cepat (kesan pushy), tapi jangan lupa follow-up - **Channel:** WhatsApp dengan sentuhan personal, disertai foto/katalog ### 🗣️ Nada Bicara - **Antusias & edukatif** — perkenalkan lebih jauh tentang bisnis Anda - Tunjukkan Anda peduli pengalaman pertama mereka - Nada seperti "menyambut member baru" ### 💬 Contoh Script > "Halo Kak Rina! Terima kasih sudah order minggu lalu 🙏 Gimana produknya, sesuai ekspektasi? Oh ya, kita juga punya varian lain seperti dimsum & bakso ikan yang lagi favorit pelanggan lain, mau saya kirimkan catalog lengkapnya?" ### 🎁 Penawaran - **Diskon order kedua** (untuk dorong repeat purchase — ini masa kritis konversi!) - Edukasi lengkap: kirim katalog, price list, cara order - Tawarkan **konsultasi kebutuhan** (misal: "biasanya toko sejenis order apa aja ya?") - Informasi minimum order & sistem pembayaran yang jelas ### ✅ Goal Konversi ke Pelanggan Setia — masa kritis di 2-3 transaksi pertama menentukan retensi jangka panjang. --- ## 💤 5. TIDUR/HIBERNASI (Hibernating/Lost) ### ⏰ Kapan Dihubungi - **Frekuensi:** Broadcast massal 1x per bulan (low-cost effort) - **Waktu terbaik:** Tidak perlu personal timing khusus - **Channel:** WhatsApp broadcast / SMS blast / email (bukan telepon personal — tidak worth effort) ### 🗣️ Nada Bicara - **Umum & promosional** — seperti campaign biasa, tidak perlu personalisasi mendalam - Fokus pada penawaran menarik untuk "memancing" respon ### 💬 Contoh Script > "🎉 PROMO KHUSUS! Sudah lama gak order frozen food dari kami? Yuk order lagi, dapatkan diskon 20% khusus hari ini untuk semua produk. Stok terbatas, buruan order sebelum kehabisan!" ### 🎁 Penawaran - **Promo generik** dengan diskon besar (untuk "test the water") - Bundling paket hemat - Free ongkir minimum order tertentu - **Tidak perlu** effort tinggi seperti approach personal ### ⚙️ Automasi Gunakan tools broadcast otomatis (WA Business API), tidak perlu alokasi waktu sales manual — kecuali ada respon balik, baru sales follow-up personal. ### ✅ Goal Reaktivasi dengan biaya rendah, atau biarkan alami churn jika tidak respon setelah beberapa kali broadcast. --- ## 📋 Ringkasan Cepat (Cheat Sheet untuk Tim Sales) | Segmen | Kapan | Channel | Nada | Fokus Tawaran | |---|---|---|---|---| | **Juara** | Mingguan, proaktif | WA personal + visit | Apresiatif | Prioritas stok, harga khusus | | **Setia** | Sesuai siklus order | WA + reminder | Ramah, efisien | Cross-sell, bundling | | **Berisiko Kabur** | **Segera (1-3 hari)** | **Telepon langsung** | Empatik | Diskon reaktivasi, cari masalah | | **Baru** | H+3, lalu H+10 | WA personal | Antusias | Diskon order ke-2, edukasi | | **Tidur** | Bulanan (broadcast) | WA/SMS blast | Promosional | Diskon besar generik | --- **💡 Tips Implementasi:** Buat **template pesan otomatis** di CRM/WA Business untuk 5 segmen ini, tapi tetap beri ruang sales untuk personalisasi kalimat pembuka (nama, referensi obrolan sebelumnya) — terutama untuk segmen Juara & Berisiko Kabur yang butuh sentuhan manusia lebih dalam.
# Template Pesan WhatsApp - Segmen "Berisiko Kabur" (At Risk) --- ## 📱 Variasi 1: Pendekatan Personal & Perhatian ``` Selamat pagi Pak/Bu [Nama] 🙏 Ini [Nama Sales] dari [Nama Perusahaan]. Sudah beberapa minggu nih kita nggak dengar kabar order dari [Nama Toko/Bapak/Ibu]. Semoga usahanya lancar-lancar aja ya Pak/Bu 😊 Boleh saya tau kabarnya gimana? Apakah ada kendala dengan stok kami kemarin, atau mungkin ada hal lain yang bisa kami bantu? Kami senang dengar masukan apapun, karena kepuasan Bapak/Ibu penting banget buat kami. Ditunggu kabarnya ya Pak/Bu 🙏 ``` **Kapan pakai:** Kontak pertama setelah masuk kategori at risk, untuk pelanggan yang cukup lama & besar nilainya. --- ## 📱 Variasi 2: Pendekatan dengan Penawaran Langsung ``` Halo Pak/Bu [Nama]! 👋 Kami di [Nama Perusahaan] kangen nih sama order rutin dari [Nama Toko]. Terakhir order tanggal [tanggal terakhir], udah [X] hari nggak ada kabar. Sebagai bentuk apresiasi ke pelanggan setia seperti Bapak/Ibu, kami mau kasih: ✅ Diskon 15% khusus untuk order berikutnya ✅ Free ongkir untuk area [wilayah] ✅ Bonus sample produk baru kami Kalau ada kendala stok/harga, kami juga terbuka untuk diskusi & cari solusi terbaik. Mau saya bantu proses order sekarang, Pak/Bu? 🙏 ``` **Kapan pakai:** Follow-up kedua (jika variasi 1 tidak direspon dalam 2-3 hari), atau untuk pelanggan yang value-nya tinggi & butuh insentif konkret. --- ## 📱 Variasi 3: Pendekatan Singkat & Tidak Memaksa ``` Selamat siang Pak/Bu [Nama] 😊 Sekadar nyapa dari [Nama Perusahaan]. Kami perhatikan udah lama nggak ada order dari [Nama Toko]. Kalau berkenan, boleh kasih tau kami: 1️⃣ Masih butuh supply frozen food? 2️⃣ Ada kendala yang bisa kami bantu? 3️⃣ Atau mungkin sudah beralih ke supplier lain? Feedback Bapak/Ibu sangat berarti buat kami evaluasi pelayanan ke depannya. Terima kasih waktunya 🙏 ``` **Kapan pakai:** Follow-up ketiga/terakhir (jika 2 pesan sebelumnya tidak direspon), fokus untuk *closing the loop* — dapat info kenapa churn, meski tidak berhasil reaktivasi. --- ## 📋 Panduan Penggunaan Sequence | Urutan | Timing | Template | Tujuan | |---|---|---|---| | **1** | Hari ke-1 (segera setelah masuk At Risk) | Variasi 1 | Buka komunikasi, tunjukkan perhatian | | **2** | Hari ke-4 (jika tidak respon) | Variasi 2 | Beri insentif konkret untuk dorong aksi | | **3** | Hari ke-8 (jika masih tidak respon) | Variasi 3 | Cari tahu alasan, evaluasi internal | --- ## ⚠️ Catatan Penting 1. **Personalisasi wajib** — isi `[Nama]`, `[Nama Toko]`, `[tanggal terakhir]` sesuai data real, jangan generic 2. **Jika ada respon** (apapun jawabannya), **eskalasi ke telepon langsung** — jangan lanjut chat WA saja untuk segmen ini 3. **Track response rate** tiap variasi untuk tahu template mana paling efektif direspon pelanggan Anda 4. Jika setelah 3x follow-up tidak ada respon sama sekali → pindahkan ke segmen **Hibernasi**, alihkan ke broadcast massal saja
# Fungsi PHP - Auto Assign Template Pesan Berdasarkan Segmen RFM
---
## 📄 Kode Lengkap
```php
<?php
/**
* Class untuk mengelola template pesan WhatsApp berdasarkan segmen RFM
*/
class RFMMessageTemplate
{
private $customer;
private $followUpCount;
/**
* Constructor
*
* @param array $customer Data customer (nama, segment, last_order_date, dll)
* @param int $followUpCount Ke berapa kali follow-up (untuk segmen At Risk yang punya sequence)
*/
public function __construct(array $customer, int $followUpCount = 1)
{
$this->customer = $customer;
$this->followUpCount = $followUpCount;
}
/**
* Fungsi utama untuk generate pesan sesuai segmen
*
* @return array ['template_name' => string, 'message' => string, 'channel' => string]
*/
public function generateMessage(): array
{
$segment = $this->customer['segment'] ?? 'unknown';
switch (strtolower($segment)) {
case 'juara':
case 'champions':
return $this->championsTemplate();
case 'pelanggan setia':
case 'loyal customers':
return $this->loyalCustomersTemplate();
case 'berisiko kabur':
case 'at risk':
return $this->atRiskTemplate();
case 'pelanggan baru':
case 'new customers':
return $this->newCustomersTemplate();
case 'tidur/hibernasi':
case 'hibernating':
return $this->hibernatingTemplate();
default:
return $this->defaultTemplate();
}
}
/**
* Template untuk segmen JUARA (Champions)
*/
private function championsTemplate(): array
{
$nama = $this->customer['nama'] ?? 'Bapak/Ibu';
$message = "Selamat pagi {$nama}! 🌟\n\n";
$message .= "Gimana kabarnya usahanya? Stok produk favorit masih aman kah?\n\n";
$message .= "Saya siapin batch fresh minggu ini, mau saya kirim seperti biasa atau ada tambahan item baru yang mau dicoba?\n\n";
$message .= "Sebagai pelanggan prioritas kami, ada juga info produk baru khusus untuk {$nama} duluan sebelum yang lain 😊";
return [
'template_name' => 'champions_weekly_checkin',
'message' => $message,
'channel' => 'whatsapp_personal',
'priority' => 'high',
'follow_up_needed' => false
];
}
/**
* Template untuk segmen PELANGGAN SETIA (Loyal Customers)
*/
private function loyalCustomersTemplate(): array
{
$nama = $this->customer['nama'] ?? 'Bapak/Ibu';
$message = "Halo {$nama}! 👋\n\n";
$message .= "Sudah waktunya order rutin nih! Stok produk favorit lagi banyak, mau order jumlah biasa atau ada request tambahan?\n\n";
$message .= "Oh ya, ada promo bundling menarik minggu ini, mau saya infokan?";
return [
'template_name' => 'loyal_reminder_order',
'message' => $message,
'channel' => 'whatsapp_broadcast',
'priority' => 'medium',
'follow_up_needed' => false
];
}
/**
* Template untuk segmen BERISIKO KABUR (At Risk) - dengan sequence
*/
private function atRiskTemplate(): array
{
$nama = $this->customer['nama'] ?? 'Bapak/Ibu';
$namaToko = $this->customer['nama_toko'] ?? 'toko Anda';
$lastOrderDate = $this->customer['last_order_date'] ?? '-';
$daysSinceOrder = $this->calculateDaysSince($lastOrderDate);
// Sequence berdasarkan followUpCount
switch ($this->followUpCount) {
case 1:
$message = "Selamat pagi {$nama} 🙏\n\n";
$message .= "Sudah beberapa minggu nih kita nggak dengar kabar order dari {$namaToko}.\n\n";
$message .= "Semoga usahanya lancar-lancar aja ya! Boleh saya tau kabarnya gimana? ";
$message .= "Apakah ada kendala dengan stok kami kemarin, atau mungkin ada hal lain yang bisa kami bantu?\n\n";
$message .= "Ditunggu kabarnya ya 🙏";
$templateName = 'at_risk_followup_1_personal';
break;
case 2:
$message = "Halo {$nama}! 👋\n\n";
$message .= "Kami kangen nih sama order rutin dari {$namaToko}. ";
$message .= "Terakhir order tanggal {$lastOrderDate}, udah {$daysSinceOrder} hari nggak ada kabar.\n\n";
$message .= "Sebagai bentuk apresiasi, kami mau kasih:\n";
$message .= "✅ Diskon 15% khusus order berikutnya\n";
$message .= "✅ Free ongkir untuk area Anda\n";
$message .= "✅ Bonus sample produk baru\n\n";
$message .= "Mau saya bantu proses order sekarang? 🙏";
$templateName = 'at_risk_followup_2_offer';
break;
case 3:
default:
$message = "Selamat siang {$nama} 😊\n\n";
$message .= "Sekadar nyapa, kami perhatikan udah lama nggak ada order dari {$namaToko}.\n\n";
$message .= "Kalau berkenan, boleh kasih tau kami:\n";
$message .= "1️⃣ Masih butuh supply frozen food?\n";
$message .= "2️⃣ Ada kendala yang bisa kami bantu?\n";
$message .= "3️⃣ Atau mungkin sudah beralih ke supplier lain?\n\n";
$message .= "Feedback Anda sangat berarti buat kami 🙏";
$templateName = 'at_risk_followup_3_closing';
break;
}
return [
'template_name' => $templateName,
'message' => $message,
'channel' => $this->followUpCount == 1 ? 'phone_call' : 'whatsapp_personal',
'priority' => 'urgent',
'follow_up_needed' => $this->followUpCount < 3,
'next_follow_up_days' => $this->getNextFollowUpDays($this->followUpCount)
];
}
/**
* Template untuk segmen PELANGGAN BARU (New Customers)
*/
private function newCustomersTemplate(): array
{
$nama = $this->customer['nama'] ?? 'Bapak/Ibu';
$message = "Halo {$nama}! 😊\n\n";
$message .= "Terima kasih sudah order kemarin 🙏 Gimana produknya, sesuai ekspektasi?\n\n";
$message .= "Oh ya, kita juga punya varian produk lain yang lagi favorit pelanggan kami, mau saya kirimkan katalog lengkapnya?\n\n";
$message .= "Ada juga diskon khusus untuk order kedua nih, mau info lebih lanjut?";
return [
'template_name' => 'new_customer_welcome',
'message' => $message,
'channel' => 'whatsapp_personal',
'priority' => 'high',
'follow_up_needed' => true,
'next_follow_up_days' => 10
];
}
/**
* Template untuk segmen TIDUR/HIBERNASI (Hibernating)
*/
private function hibernatingTemplate(): array
{
$message = "🎉 PROMO KHUSUS!\n\n";
$message .= "Sudah lama nggak order frozen food dari kami? Yuk order lagi, dapatkan diskon 20% khusus hari ini untuk semua produk!\n\n";
$message .= "Stok terbatas, buruan order sebelum kehabisan! 🔥";
return [
'template_name' => 'hibernating_broadcast',
'message' => $message,
'channel' => 'whatsapp_broadcast',
'priority' => 'low',
'follow_up_needed' => false
];
}
/**
* Template default jika segmen tidak dikenali
*/
private function defaultTemplate(): array
{
return [
'template_name' => 'default_generic',
'message' => "Halo! Terima kasih sudah menjadi pelanggan kami. Ada yang bisa kami bantu?",
'channel' => 'whatsapp_broadcast',
'priority' => 'low',
'follow_up_needed' => false
];
}
/**
* Helper: Hitung selisih hari dari tanggal terakhir order
*/
private function calculateDaysSince(string $date): int
{
if ($date === '-' || empty($date)) {
return 0;
}
try {
$lastDate = new DateTime($date);
$today = new DateTime();
$interval = $today->diff($lastDate);
return $interval->days;
} catch (Exception $e) {
return 0;
}
}
/**
* Helper: Tentukan jarak hari untuk follow-up berikutnya (khusus At Risk)
*/
private function getNextFollowUpDays(int $currentCount): int
{
$schedule = [
1 => 3, // Follow-up ke-2 setelah 3 hari
2 => 4, // Follow-up ke-3 setelah 4 hari
3 => 0 // Tidak ada follow-up lagi
];
return $schedule[$currentCount] ?? 0;
}
}
// ============================================
// CONTOH PENGGUNAAN
// ============================================
// Contoh data customer dari database
$customerJuara = [
'nama' => 'Pak Budi',
'nama_toko' => 'Toko Budi Jaya',
'segment' => 'Juara',
'last_order_date' => '2024-12-20'
];
$customerAtRisk = [
'nama' => 'Pak Joko',
'nama_toko' => 'Warung Joko',
'segment' => 'Berisiko Kabur',
'last_order_date' => '2024-11-15'
];
// Generate pesan untuk Juara
$rfm1 = new RFMMessageTemplate($customerJuara);
$result1 = $rfm1->generateMessage();
echo "=== CUSTOMER: {$customerJuara['nama']} ===\n";
echo "Template: {$result1['template_name']}\n";
echo "Channel: {$result1['channel']}\n";
echo "Priority: {$result1['priority']}\n";
echo "Pesan:\n{$result1['message']}\n\n";
// Generate pesan untuk At Risk (follow-up ke-1)
$rfm2 =