{"id":369,"date":"2025-05-19T01:05:25","date_gmt":"2025-05-19T01:05:25","guid":{"rendered":"https:\/\/abatablaster.xyz\/?page_id=369"},"modified":"2026-09-13T12:21:45","modified_gmt":"2026-09-13T12:21:45","slug":"affiliate","status":"publish","type":"page","link":"https:\/\/abatablaster.xyz\/index.php\/affiliate\/","title":{"rendered":"Affiliate"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"ms\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Affiliate \u2013 AbataBlaster<\/title>\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-app-compat.js\"><\/script>\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-auth-compat.js\"><\/script>\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-firestore-compat.js\"><\/script>\n\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/sweetalert2@11\"><\/script>\n\n    <style>\n        body {\n            font-family: 'Poppins', sans-serif;\n            background-color: #f1f8e9;\n            margin: 0;\n            padding: 20px;\n            text-align: center;\n        }\n\n        img.logo {\n            max-width: 120px;\n            border-radius: 10px;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\n            margin-bottom: 20px;\n        }\n\n        .card {\n            max-width: 600px;\n            margin: auto;\n            background: white;\n            padding: 30px;\n            border-radius: 12px;\n            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);\n        }\n\n        table {\n            width: 100%;\n            border-collapse: collapse;\n            margin-top: 20px;\n            font-size: 15px;\n        }\n\n        th,\n        td {\n            border: 1px solid #ccc;\n            padding: 10px;\n            white-space: nowrap;\n        }\n\n        th {\n            background: #c5e1a5;\n        }\n\n        input {\n            width: 100%;\n            padding: 10px;\n            font-size: 15px;\n            border: 1px solid #ccc;\n            border-radius: 6px;\n            margin-bottom: 10px;\n        }\n\n        @media screen and (max-width: 768px) {\n            table {\n                font-size: 12px;\n            }\n        }\n    <\/style>\n<\/head>\n\n<body>\n    <img decoding=\"async\" src=\"https:\/\/abatablaster.xyz\/wp-content\/uploads\/2025\/05\/photo_2024-05-16_15-47-59.jpg\" class=\"logo\"\n        alt=\"Abata Logo\">\n\n    <div class=\"card\">\n        <h2>\ud83d\udc65 Sistem Affiliate Anda<\/h2>\n        <p><strong>Link Referral Anda:<\/strong><\/p>\n        <input type=\"text\" id=\"referralLink\" readonly onclick=\"this.select()\">\n        <div id=\"tooltipCopy\" style=\"color:green; font-size:14px; margin-top:5px; display:none;\">\n            \u2705 Link telah disalin!\n        <\/div>\n\n        <p><strong>Baki Komisen Tersedia:<\/strong><\/p>\n        <h3 id=\"jumlahKomisen\" style=\"color:#2e7d32; margin-bottom: 20px;\">RM0.00<\/h3>\n\n        <!-- \ud83c\udd95 PENERANGAN CARA KOMISEN DIKIRA -->\n        <p style=\"font-size:14px; color:#555; line-height:1.6; margin-top:0; margin-bottom:18px; text-align:left;\">\n            \ud83d\udca1 <strong>Cara komisen dikira:<\/strong><br>\n            \u2022 Anda dapat <strong>signup reward<\/strong> kecil bila prospek daftar akaun melalui link anda.<br>\n            \u2022 Setiap kali <strong>downline topup wallet<\/strong> (min RM20), anda dapat komisen:\n            Tier 1 = <strong>8%<\/strong>, Tier 2 = <strong>3%<\/strong>, Tier 3 = <strong>2%<\/strong> daripada jumlah\n            topup.<br>\n            \u2022 Komisen terkumpul boleh <strong>dipindahkan ke wallet AbataBlaster<\/strong> atau\n            <strong>withdraw ke bank<\/strong>.\n        <\/p>\n\n        <button id=\"btnTransferWallet\"\n            style=\"background:#388e3c; color:white; border:none; border-radius:6px; padding:12px 28px; font-size:16px; font-weight:600; margin:10px 0 20px 0; cursor:pointer;\">Transfer\n            ke Wallet<\/button>\n\n        <button id=\"btnWithdrawKomisen\"\n            style=\"background:#ffa000; color:white; border:none; border-radius:6px; padding:12px 28px; font-size:16px; font-weight:600; margin:10px 0 20px 8px; cursor:pointer;\">\n            Withdraw ke Bank\n        <\/button>\n\n        <div id=\"statusWithdraw\" style=\"margin:10px 0 18px 0;color:#ff9800;font-weight:bold;\"><\/div>\n\n        <h3>\ud83d\udcc4 Senarai Referral Anda<\/h3>\n        <div style=\"overflow-x:auto; max-height:600px; border:1px solid #ccc; border-radius:8px;\">\n            <table id=\"referralTable\" style=\"min-width:900px; width:100%; border-collapse:collapse;\">\n                <thead>\n                    <tr style=\"background:#dcedc8;\">\n                        <th>No<\/th>\n                        <th>Email<\/th>\n                        <th>Komisyen Terkumpul<\/th>\n                        <th>Status<\/th>\n                        <th>Transaksi<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody>\n                    <tr>\n                        <td colspan=\"6\">Loading&#8230;<\/td>\n                    <\/tr>\n                <\/tbody>\n                <tfoot>\n                    <tr style=\"font-weight:bold; background:#f1f8e9;\">\n                        <td colspan=\"5\" style=\"text-align:right;\">Total Komisyen<\/td>\n                        <td id=\"jumlahKomisenKeseluruhan\">\u2013<\/td>\n                    <\/tr>\n                <\/tfoot>\n            <\/table>\n        <\/div>\n\n        <h3 style=\"margin-top: 30px;\">\ud83d\udce5 Senarai Signup Reward (Downline)<\/h3>\n        <div style=\"overflow-x:auto;\">\n            <table id=\"signupRewardTable\" style=\"min-width:700px;\">\n                <thead>\n                    <tr>\n                        <th>No<\/th>\n                        <th>Email<\/th>\n                        <th>Tier<\/th>\n                        <th>Jumlah (RM)<\/th>\n                        <th>Tarikh<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody><\/tbody>\n            <\/table>\n        <\/div>\n\n        <h3 style=\"margin-top: 40px;\">\ud83c\udfc6 Top 10 Affiliate<\/h3>\n        <table id=\"leaderboard\">\n            <thead>\n                <tr>\n                    <th>Username<\/th>\n                    <th>Referral<\/th>\n                    <th>Komisen (RM)<\/th>\n                <\/tr>\n            <\/thead>\n            <tbody>\n                <tr>\n                    <td colspan=\"2\">Loading&#8230;<\/td>\n                <\/tr>\n            <\/tbody>\n        <\/table>\n    <\/div>\n\n    <script>\n        const firebaseConfig = {\n            apiKey: \"AIzaSyBou8nlJ7uPZ4ioOJapzC8Dn3-K7Qs-yco\",\n            authDomain: \"whatsapp-ai-saas.firebaseapp.com\",\n            projectId: \"whatsapp-ai-saas\"\n        };\n        if (!firebase.apps.length) firebase.initializeApp(firebaseConfig);\n        const auth = firebase.auth();\n        const db = firebase.firestore();\n\n        auth.onAuthStateChanged(async (user) => {\n            if (!user) {\n                await Swal.fire({\n                    icon: \"warning\",\n                    title: \"Sesi Tamat\",\n                    text: \"Sila log masuk terlebih dahulu untuk akses halaman ini.\",\n                    confirmButtonText: \"OK\",\n                    confirmButtonColor: \"#43a047\"\n                });\n                window.location.href = \"https:\/\/abatablaster.xyz\/index.php\/login\/\";\n                return;\n            }\n\n            const userDoc = await db.collection(\"users\").doc(user.uid).get();\n            const data = userDoc.data(); \/\/ \u2705 tambah ini\n\n            if (!data?.nama || !data?.noTel || !data?.username) {\n                const nextUrl = encodeURIComponent(window.location.href);\n                await Swal.fire({\n                    icon: \"info\",\n                    title: \"Lengkapkan Maklumat Diri\",\n                    html: `Sila lengkapkan maklumat <b>nama<\/b>, <b>nombor telefon<\/b> dan <b>username<\/b> untuk dapatkan link affiliate anda dan mula jana pendapatan bersama <b>AbataBlaster.xyz<\/b>.`,\n                    confirmButtonText: \"Lengkapkan Sekarang\",\n                    confirmButtonColor: \"#43a047\"\n                });\n\n                window.location.href = `https:\/\/abatablaster.xyz\/index.php\/kemaskini-data\/?next=${nextUrl}`;\n                return;\n            }\n\n            const username = data.username;\n\n            \/\/ \ud83d\udd17 Papar link referral terus ke landing page\n            const link = `${location.origin}\/landing-page.html?ref=${encodeURIComponent(username)}`;\n            document.getElementById(\"referralLink\").value = link;\n\n            const referralInput = document.getElementById(\"referralLink\");\n            const tooltipCopy = document.getElementById(\"tooltipCopy\");\n\n            referralInput.addEventListener(\"click\", () => {\n                referralInput.select();\n                document.execCommand(\"copy\");\n\n                tooltipCopy.style.display = \"block\";\n                setTimeout(() => {\n                    tooltipCopy.style.display = \"none\";\n                }, 1500); \/\/ Papar tooltip selama 1.5 saat\n            });\n\n            \/\/ \ud83d\udcb0 Papar jumlah komisen\n            const komisenSnap = await db.collection(\"affiliate_earnings\").doc(username).get();\n            const jumlahKomisen = komisenSnap.exists ? komisenSnap.data().bakiKomisen || 0 : 0;\n            document.getElementById(\"jumlahKomisen\").innerText = \"RM\" + jumlahKomisen.toFixed(2);\n\n            \/\/ ================== STATUS BANK WITHDRAWAL REALTIME ==================\n            const withdrawQuery = db.collection(\"withdraw_requests\")\n                .where(\"uid\", \"==\", user.uid)\n                .orderBy(\"requestedAt\", \"desc\")\n                .limit(1);\n\n            withdrawQuery.onSnapshot((withdrawSnap) => {\n                const statusContainer = document.getElementById(\"statusWithdraw\");\n\n                if (!statusContainer) {\n                    return;\n                }\n\n                if (withdrawSnap.empty) {\n                    statusContainer.innerHTML = \"\";\n                    return;\n                }\n\n                const withdrawDoc = withdrawSnap.docs[0];\n                const d = withdrawDoc.data() || {};\n                const withdrawId = withdrawDoc.id;\n\n                const requestedDate = new Date(d.requestedAt);\n                const jumlah = Number(d.jumlah || 0);\n\n                const status = String(d.status || \"\")\n                    .trim()\n                    .toLowerCase();\n\n                let statusHtml = `\n                    <div style=\"\n                        background:${status === \"completed\" ? \"#e8f5e9\" : \"#fff8e1\"};\n                        border:1px solid ${status === \"completed\" ? \"#a5d6a7\" : \"#ffe082\"};\n                        border-radius:8px;\n                        padding:12px;\n                        color:#555;\n                        line-height:1.6;\n                    \">\n                        \ud83c\udfe6 <b>Bank Withdrawal<\/b><br>\n                        Jumlah: <b style=\"color:${status === \"completed\" ? \"#2e7d32\" : \"#e65100\"};\">\n                            RM${jumlah.toFixed(2)}\n                        <\/b><br>\n\n                        Status:\n                        <b>\n                            ${status === \"completed\"\n                        ? \"\u2705 Paid to Bank\"\n                        : \"\u23f3 Pending Payment\"}\n                        <\/b><br>\n\n                        <span style=\"font-size:12px;color:#777;\">\n                            Dihantar pada ${requestedDate.toLocaleString(\"ms-MY\")}\n                        <\/span>\n                `;\n\n                \/\/ =========================================\n                \/\/ COMPLETED\n                \/\/ =========================================\n                if (status === \"completed\") {\n                    statusHtml += `\n                        <br><br>\n\n                        <div style=\"\n                            background:#c8e6c9;\n                            color:#1b5e20;\n                            padding:9px 12px;\n                            border-radius:6px;\n                            font-size:13px;\n                            font-weight:600;\n                        \">\n                            \u2705 Pembayaran komisen anda telah selesai diproses.\n                        <\/div>\n                    `;\n                }\n\n                \/\/ =========================================\n                \/\/ PENDING\n                \/\/ =========================================\n                if (status === \"pending\") {\n                    const lastReminderDate = d.lastAdminReminderAtMs\n                        ? new Date(Number(d.lastAdminReminderAtMs))\n                        : requestedDate;\n\n                    const nextReminderTime =\n                        lastReminderDate.getTime() +\n                        (24 * 60 * 60 * 1000);\n\n                    const now = Date.now();\n\n                    const bolehReminder =\n                        now >= nextReminderTime;\n\n                    if (bolehReminder) {\n                        statusHtml += `\n                            <br><br>\n\n                            <button\n                                id=\"btnReminderWithdraw\"\n                                data-withdraw-id=\"${withdrawId}\"\n                                style=\"\n                                    background:#1976d2;\n                                    color:white;\n                                    border:none;\n                                    border-radius:6px;\n                                    padding:9px 14px;\n                                    font-size:13px;\n                                    font-weight:600;\n                                    cursor:pointer;\n                                \">\n                                \ud83d\udd14 Ingatkan Admin\n                            <\/button>\n\n                            <div style=\"font-size:11px;color:#777;margin-top:5px;\">\n                                Reminder hanya boleh dihantar sekali setiap 24 jam.\n                            <\/div>\n                        `;\n\n                    } else {\n                        const jamBaki = Math.max(\n                            1,\n                            Math.ceil(\n                                (nextReminderTime - now) \/\n                                (60 * 60 * 1000)\n                            )\n                        );\n\n                        statusHtml += `\n                            <br><br>\n\n                            <button\n                                disabled\n                                style=\"\n                                    background:#ccc;\n                                    color:#666;\n                                    border:none;\n                                    border-radius:6px;\n                                    padding:9px 14px;\n                                    font-size:13px;\n                                    font-weight:600;\n                                    cursor:not-allowed;\n                                \">\n                                \ud83d\udd14 Reminder Telah Dihantar\n                            <\/button>\n\n                            <div style=\"font-size:11px;color:#777;margin-top:5px;\">\n                                Boleh ingatkan admin semula dalam kira-kira ${jamBaki} jam.\n                            <\/div>\n                        `;\n                    }\n                }\n\n                statusHtml += `<\/div>`;\n\n                statusContainer.innerHTML =\n                    statusHtml;\n\n                const btnReminder =\n                    document.getElementById(\n                        \"btnReminderWithdraw\"\n                    );\n\n                if (btnReminder) {\n                    btnReminder.onclick =\n                        async function () {\n                            await resendWithdrawAdminNotification(\n                                withdrawId,\n                                btnReminder\n                            );\n                        };\n                }\n\n            }, (err) => {\n                console.error(\n                    \"\u274c Realtime withdraw status error:\",\n                    err\n                );\n            });\n\n            \/\/ ================== STATUS BANK WITHDRAWAL REALTIME ==================\n\n            \/\/ \ud83d\udc65 Dapatkan semua user yang dirujuk oleh anda\n            const referralSnap = await db.collection(\"users\")\n                .where(\"referral_by\", \"==\", username)\n                .get();\n\n            \/\/ Dapatkan juga semua komisen dalam subcollection\n            const komisenListSnap = await db.collection(\"affiliate_earnings\")\n                .doc(username)\n                .collection(\"referrals\")\n                .get();\n\n            \/\/ === Papar Table Signup Reward (Downline) ===\n            const signupRewardTbody = document.querySelector(\"#signupRewardTable tbody\");\n\n            \/\/ Debug: print semua dokumen referral yang diambil\n            console.log(\"All referral docs:\", komisenListSnap.docs.map(doc => doc.data()));  \/\/ <-- LETAK SINI\n\n            const signupRewards = komisenListSnap.docs\n                .map(doc => doc.data())\n                .filter(t => t.type === \"signup_reward\");\n\n            console.log(\"SignupRewards found:\", signupRewards);\n\n            \/\/ Dapatkan semua email signup secara serentak\n            const signupRows = await Promise.all(signupRewards.map(async (t, i) => {\n                let email = \"-\";\n                if (t.referred_uid) {\n                    const userDoc = await db.collection(\"users\").doc(t.referred_uid).get();\n                    if (userDoc.exists) email = userDoc.data().email || \"-\";\n                    else console.log(\"User not found for UID:\", t.referred_uid);\n                }\n                const tarikh = t.timestamp && t.timestamp.toDate\n                    ? t.timestamp.toDate().toLocaleDateString(\"ms-MY\")\n                    : (typeof t.timestamp === \"string\"\n                        ? new Date(t.timestamp).toLocaleDateString(\"ms-MY\")\n                        : '-');\n                return `\n    <tr>\n      <td>${i + 1}<\/td>\n      <td>${email}<\/td>\n      <td>Tier ${t.tier || '-'}<\/td>\n      <td>RM${Number(t.komisen).toFixed(2)}<\/td>\n      <td>${tarikh}<\/td>\n    <\/tr>\n  `;\n            }));\n\n            signupRewardTbody.innerHTML = signupRows.length\n                ? signupRows.join(\"\")\n                : `<tr><td colspan=\"5\">Tiada signup reward.<\/td><\/tr>`;\n\n            \/\/ Kumpul semua transaksi dalam array by referred_uid\n            const komisenMap = {}; \/\/ { [referred_uid]: [listOfKomisenObj] }\n            komisenListSnap.forEach(doc => {\n                const d = doc.data();\n                const cleanUid = (d.referred_uid || \"\").trim();\n                if (!komisenMap[cleanUid]) komisenMap[cleanUid] = [];\n                komisenMap[cleanUid].push(d);\n\n            });\n\n            const tbody = document.querySelector(\"#referralTable tbody\");\n            const jumlahTd = document.getElementById(\"jumlahKomisenKeseluruhan\");\n\n            tbody.innerHTML = \"\";\n            let total = 0;\n            let bil = 1;\n\n            referralSnap.forEach(doc => {\n                const data = doc.data();\n                const uid = (doc.id || \"\").trim();\n\n                \/\/ Debug: print UID dan senarai transaksi yang di-link\n                console.log(\n                    \"Referral UID:\",\n                    uid,\n                    \"Transaksi:\",\n                    komisenMap[uid] || \"(tiada komisen)\"\n                );\n\n                const listTransaksi = komisenMap[uid] || [];\n\n                \/\/ [DEBUG] Papar log jika tiada transaksi (letak di sini)\n                if (listTransaksi.length === 0) {\n                    console.log(\"Tiada transaksi untuk referral:\", uid, data.email);\n                }\n\n                \/\/ Jumlahkan semua komisen\n                const totalKomisenReferral = listTransaksi.reduce((sum, t) => sum + (Number(t.komisen) || 0), 0);\n\n                const email = data.email || \"-\";\n                const tamat = data.tarikhTamat ? new Date(data.tarikhTamat) : null;\n                const status = tamat && tamat > new Date() ? \"Aktif\" : \"Tidak Aktif\";\n\n                total += totalKomisenReferral;\n\n                const row = document.createElement(\"tr\");\n                row.innerHTML = `\n        <td>${bil++}<\/td>\n        <td>${email}<\/td>\n        <td>RM${totalKomisenReferral.toFixed(2)}<\/td>\n        <td>${status}<\/td>\n        <td><button class=\"btnTransaksi\" data-uid=\"${uid}\" style=\"padding:6px 14px; border:none; background:#c5e1a5; border-radius:5px; font-weight:500; cursor:pointer;\">Lihat Transaksi<\/button><\/td>\n    `;\n                tbody.appendChild(row);\n            });\n\n            setTimeout(() => {\n                document.querySelectorAll('.btnTransaksi').forEach(btn => {\n                    btn.onclick = async function () {\n                        const referred_uid = btn.getAttribute('data-uid');\n                        const email = btn.parentElement.parentElement.children[1].innerText;\n                        const transaksiSnap = await db.collection(\"affiliate_earnings\")\n                            .doc(username)\n                            .collection(\"referrals\")\n                            .where(\"referred_uid\", \"==\", referred_uid)\n                            .orderBy(\"timestamp\", \"desc\")\n                            .get();\n                        let html = '';\n                        if (transaksiSnap.empty) {\n                            html = \"<i>Tiada transaksi komisen untuk referral ini.<\/i>\";\n                        } else {\n                            html = `\n        <table style='width:100%;font-size:15px;text-align:left'>\n          <tr>\n            <th>Jenis<\/th>\n            <th>Jumlah (RM)<\/th>\n            <th>Tarikh<\/th>\n            <th>Nota\/Pakej<\/th>\n          <\/tr>\n${transaksiSnap.docs.map(doc => {\n                                const t = doc.data();\n\n                                \/\/ \ud83c\udd95 Tentukan teks mesra untuk kolum \"Jenis\"\n                                let jenisText = \"-\";\n                                if (t.type === \"signup_reward\") {\n                                    jenisText = `Sign Up Reward (Tier ${t.tier || \"-\"}${t.tier == 1 ? \"\" : \" - Downline\"})`;\n                                } else if (t.type === \"wallet_topup\") {\n                                    jenisText = `Komisen Topup Wallet (Tier ${t.tier || \"-\"})`;\n                                } else {\n                                    jenisText = t.type || t.pakej || '-';\n                                }\n\n                                const tarikh = t.timestamp && t.timestamp.toDate\n                                    ? t.timestamp.toDate().toLocaleDateString(\"ms-MY\")\n                                    : (typeof t.timestamp === \"string\"\n                                        ? new Date(t.timestamp).toLocaleDateString(\"ms-MY\")\n                                        : '-');\n\n                                return `<tr>\n    <td>${jenisText}<\/td>\n    <td>${Number(t.komisen).toFixed(2)}<\/td>\n    <td>${tarikh}<\/td>\n    <td>${t.pakej || '-'}<\/td>\n  <\/tr>`;\n                            }).join('')}\n        <\/table>`;\n                        }\n                        Swal.fire({\n                            title: `Transaksi Komisen \u2013 ${email}`,\n                            html: `<div style=\"overflow-x:auto;\">${html}<\/div>`,\n                            width: 600,\n                            confirmButtonText: \"Tutup\",\n                            confirmButtonColor: \"#43a047\"\n                        });\n                    };\n                });\n            }, 600);\n\n            jumlahTd.textContent = `RM${total.toFixed(2)}`;\n\n            \/\/ \ud83c\udfc6 Top 10 affiliate\n            const allUsers = await db.collection(\"users\").get();\n            const countMap = {};\n\n            allUsers.forEach(doc => {\n                const refBy = doc.data().referral_by;\n                if (refBy) {\n                    countMap[refBy] = (countMap[refBy] || 0) + 1;\n                }\n            });\n\n            const leaderboardArray = Object.entries(countMap)\n                .sort((a, b) => b[1] - a[1])\n                .slice(0, 10);\n\n            const lbBody = document.getElementById(\"leaderboard\").querySelector(\"tbody\");\n            lbBody.innerHTML = \"\";\n\n            for (const [username, count] of leaderboardArray) {\n                \/\/ Ambil jumlah komisen jika ada\n                const komisenSnap = await db.collection(\"affiliate_earnings\").doc(username).get();\n                const totalKomisen = komisenSnap.exists ? komisenSnap.data().totalKomisen || 0 : 0;\n\n                const row = document.createElement(\"tr\");\n                row.innerHTML = `<td>${username}<\/td><td>${count}<\/td><td>RM${totalKomisen.toFixed(2)}<\/td>`;\n                lbBody.appendChild(row);\n            }\n\n            if (leaderboardArray.length === 0) {\n                lbBody.innerHTML = \"<tr><td colspan='3'>Tiada data.<\/td><\/tr>\";\n            }\n        });\n\n        document.getElementById(\"btnTransferWallet\").onclick = async function () {\n            const user = auth.currentUser;\n\n            if (!user) {\n                return Swal.fire(\n                    \"Sesi Tamat\",\n                    \"Sila log masuk semula.\",\n                    \"warning\"\n                );\n            }\n\n            const btn = document.getElementById(\"btnTransferWallet\");\n\n            try {\n                const userSnap = await db.collection(\"users\").doc(user.uid).get();\n\n                if (!userSnap.exists) {\n                    return Swal.fire(\n                        \"Ralat\",\n                        \"Maklumat pengguna tidak dijumpai.\",\n                        \"error\"\n                    );\n                }\n\n                const username = String(\n                    userSnap.data()?.username || \"\"\n                ).trim();\n\n                const earningsDoc = await db.collection(\"affiliate_earnings\").doc(username).get();\n\n                const bakiKomisen = earningsDoc.exists\n                    ? Number(earningsDoc.data().bakiKomisen || 0)\n                    : 0;\n\n                if (bakiKomisen < 10) {\n                    return Swal.fire(\n                        \"Maaf\",\n                        \"Minimum transfer ke wallet ialah RM10.\",\n                        \"info\"\n                    );\n                }\n\n                const confirm = await Swal.fire({\n                    title: \"Transfer Komisen ke Wallet\",\n                    html: `\n                        Anda akan transfer\n                        <b>RM${bakiKomisen.toFixed(2)}<\/b>\n                        ke wallet AbataBlaster anda.<br><br>\n                        Teruskan?\n                    `,\n                    icon: \"question\",\n                    showCancelButton: true,\n                    confirmButtonText: \"Transfer\",\n                    cancelButtonText: \"Batal\",\n                    confirmButtonColor: \"#43a047\"\n                });\n\n                if (!confirm.isConfirmed) return;\n\n                btn.disabled = true;\n                btn.innerText = \"Memproses...\";\n\n                const token = await user.getIdToken(true);\n\n                const response = await fetch(\n                    \"https:\/\/us-central1-whatsapp-ai-saas.cloudfunctions.net\/transferAffiliateToWallet\",\n                    {\n                        method: \"POST\",\n                        headers: {\n                            \"Content-Type\": \"application\/json\",\n                            \"Authorization\": \"Bearer \" + token\n                        },\n                        body: JSON.stringify({\n                            uid: user.uid,\n                            username,\n                            amount: bakiKomisen\n                        })\n                    }\n                );\n\n                const resultText = await response.text();\n\n                if (!response.ok) {\n                    throw new Error(\n                        resultText || \"Gagal transfer komisen.\"\n                    );\n                }\n\n                await Swal.fire(\n                    \"Berjaya!\",\n                    `RM${bakiKomisen.toFixed(2)} telah dimasukkan ke wallet anda.`,\n                    \"success\"\n                );\n\n                window.location.reload();\n\n            } catch (err) {\n                console.error(\n                    \"\u274c transferAffiliateToWallet error:\",\n                    err\n                );\n\n                btn.disabled = false;\n                btn.innerText = \"Transfer ke Wallet\";\n\n                Swal.fire(\n                    \"Ralat\",\n                    err?.message || \"Gagal transfer komisen ke wallet.\",\n                    \"error\"\n                );\n            }\n        };\n\n        document.getElementById(\"btnWithdrawKomisen\").onclick = async function () {\n            const user = auth.currentUser;\n\n            if (!user) {\n                return Swal.fire(\n                    \"Sesi Tamat\",\n                    \"Sila log masuk semula.\",\n                    \"warning\"\n                );\n            }\n\n            const btn = document.getElementById(\"btnWithdrawKomisen\");\n\n            try {\n                const userSnap = await db.collection(\"users\").doc(user.uid).get();\n\n                if (!userSnap.exists) {\n                    return Swal.fire(\n                        \"Ralat\",\n                        \"Maklumat pengguna tidak dijumpai.\",\n                        \"error\"\n                    );\n                }\n\n                const userData = userSnap.data() || {};\n                const username = String(userData.username || \"\").trim();\n\n                if (!username) {\n                    return Swal.fire(\n                        \"Ralat\",\n                        \"Username affiliate tidak dijumpai.\",\n                        \"error\"\n                    );\n                }\n\n                const earningsDoc = await db.collection(\"affiliate_earnings\").doc(username).get();\n                const bakiKomisen = earningsDoc.exists\n                    ? Number(earningsDoc.data().bakiKomisen || 0)\n                    : 0;\n\n                if (bakiKomisen < 5) {\n                    return Swal.fire(\n                        \"Maaf\",\n                        \"Minimum withdraw ialah RM5.00\",\n                        \"info\"\n                    );\n                }\n\n                const {value: formValues} = await Swal.fire({\n                    title: \"Permohonan Withdraw Komisen\",\n                    html:\n                        `<div style=\"text-align:left;margin-bottom:10px;\">\n                            Baki tersedia:\n                            <b style=\"color:#2e7d32;\">\n                                RM${bakiKomisen.toFixed(2)}\n                            <\/b>\n                        <\/div>` +\n                        `<input id=\"swal-nama\" class=\"swal2-input\" placeholder=\"Nama Penerima\">` +\n                        `<input id=\"swal-bank\" class=\"swal2-input\" placeholder=\"Nama Bank (CIMB, Maybank, dsb)\">` +\n                        `<input id=\"swal-akaun\" class=\"swal2-input\" placeholder=\"No Akaun Bank\">` +\n                        `<input id=\"swal-email\" class=\"swal2-input\" placeholder=\"Email untuk bukti pembayaran\">`,\n                    focusConfirm: false,\n                    showCancelButton: true,\n                    confirmButtonText: \"Hantar Permohonan\",\n                    cancelButtonText: \"Batal\",\n                    preConfirm: () => {\n                        const nama = String(\n                            document.getElementById(\"swal-nama\").value || \"\"\n                        ).trim();\n\n                        const bank = String(\n                            document.getElementById(\"swal-bank\").value || \"\"\n                        ).trim();\n\n                        const akaun = String(\n                            document.getElementById(\"swal-akaun\").value || \"\"\n                        ).trim();\n\n                        const email = String(\n                            document.getElementById(\"swal-email\").value || \"\"\n                        ).trim();\n\n                        if (!nama || !bank || !akaun || !email) {\n                            Swal.showValidationMessage(\n                                \"\u26a0\ufe0f Sila lengkapkan semua maklumat bank.\"\n                            );\n\n                            return false;\n                        }\n\n                        return {\n                            nama,\n                            bank,\n                            akaun,\n                            email\n                        };\n                    }\n                });\n\n                if (!formValues) return;\n\n                const confirmWithdraw = await Swal.fire({\n                    icon: \"warning\",\n                    title: \"Sahkan Withdrawal\",\n                    html: `\n                        Anda akan membuat permohonan withdrawal sebanyak:<br><br>\n\n                        <b style=\"font-size:22px;color:#e65100;\">\n                            RM${bakiKomisen.toFixed(2)}\n                        <\/b><br><br>\n\n                        Selepas permohonan dihantar, jumlah ini akan\n                        <b>dikunci daripada baki komisen<\/b> sementara\n                        menunggu pembayaran admin.\n                    `,\n                    showCancelButton: true,\n                    confirmButtonText: \"\u2705 Ya, Hantar\",\n                    cancelButtonText: \"Batal\",\n                    confirmButtonColor: \"#ffa000\"\n                });\n\n                if (!confirmWithdraw.isConfirmed) return;\n\n                btn.disabled = true;\n                btn.innerText = \"Memproses...\";\n\n                const token = await user.getIdToken(true);\n\n                const response = await fetch(\n                    \"https:\/\/us-central1-whatsapp-ai-saas.cloudfunctions.net\/withdrawAffiliate\",\n                    {\n                        method: \"POST\",\n                        headers: {\n                            \"Content-Type\": \"application\/json\",\n                            \"Authorization\": \"Bearer \" + token\n                        },\n                        body: JSON.stringify({\n                            username,\n                            amount: bakiKomisen,\n                            nama: formValues.nama,\n                            bank: formValues.bank,\n                            akaun: formValues.akaun,\n                            email: formValues.email\n                        })\n                    }\n                );\n\n                const resultText = await response.text();\n\n                if (!response.ok) {\n                    throw new Error(\n                        resultText || \"Gagal membuat permohonan withdrawal.\"\n                    );\n                }\n\n                await Swal.fire(\n                    \"Permohonan Diterima\",\n                    \"Permohonan bank withdrawal telah dihantar. Jika masih belum diproses selepas 24 jam, anda boleh gunakan butang Ingatkan Admin.\",\n                    \"success\"\n                );\n\n                window.location.reload();\n\n            } catch (err) {\n                console.error(\n                    \"\u274c withdrawAffiliate error:\",\n                    err\n                );\n\n                btn.disabled = false;\n                btn.innerText = \"Withdraw ke Bank\";\n\n                Swal.fire(\n                    \"Tidak Dapat Withdraw\",\n                    err?.message || \"Sila cuba lagi.\",\n                    \"error\"\n                );\n            }\n        };\n\n        async function resendWithdrawAdminNotification(withdrawId, buttonEl) {\n            const user = auth.currentUser;\n\n            if (!user) {\n                return Swal.fire(\"Sesi Tamat\", \"Sila log masuk semula.\", \"warning\");\n            }\n\n            const confirm = await Swal.fire({\n                icon: \"question\",\n                title: \"Ingatkan Admin?\",\n                html: `\n                    Sistem akan menghantar reminder kepada admin mengenai\n                    <b>bank withdrawal<\/b> anda.<br><br>\n\n                    <span style=\"font-size:13px;color:#777;\">\n                        Reminder hanya dibenarkan sekali setiap 24 jam.\n                    <\/span>\n                `,\n                showCancelButton: true,\n                confirmButtonText: \"\ud83d\udd14 Ya, Ingatkan Admin\",\n                cancelButtonText: \"Batal\",\n                confirmButtonColor: \"#1976d2\"\n            });\n\n            if (!confirm.isConfirmed) return;\n\n            try {\n                buttonEl.disabled = true;\n                buttonEl.innerText = \"Menghantar...\";\n\n                const token = await user.getIdToken(true);\n\n                const response = await fetch(\n                    \"https:\/\/us-central1-whatsapp-ai-saas.cloudfunctions.net\/resendWithdrawAdminNotification\",\n                    {\n                        method: \"POST\",\n                        headers: {\n                            \"Content-Type\": \"application\/json\",\n                            \"Authorization\": \"Bearer \" + token\n                        },\n                        body: JSON.stringify({\n                            withdrawId: withdrawId\n                        })\n                    }\n                );\n\n                const resultText = await response.text();\n\n                if (!response.ok) {\n                    throw new Error(resultText || \"Gagal menghantar reminder.\");\n                }\n\n                await Swal.fire({\n                    icon: \"success\",\n                    title: \"Admin Telah Diingatkan\",\n                    text: \"Reminder bank withdrawal telah dihantar kepada admin.\",\n                    confirmButtonColor: \"#43a047\"\n                });\n\n                window.location.reload();\n\n            } catch (err) {\n                console.error(\"resendWithdrawAdminNotification error:\", err);\n\n                buttonEl.disabled = false;\n                buttonEl.innerText = \"\ud83d\udd14 Ingatkan Admin\";\n\n                Swal.fire(\n                    \"Tidak Dapat Hantar Reminder\",\n                    err?.message || \"Sila cuba lagi kemudian.\",\n                    \"error\"\n                );\n            }\n        }\n\n    <\/script>\n<\/body>\n\n<\/html>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Affiliate \u2013 AbataBlaster \ud83d\udc65 Sistem Affiliate Anda Link Referral Anda: \u2705 Link telah disalin! Baki Komisen Tersedia: RM0.00 \ud83d\udca1 Cara komisen dikira: \u2022 Anda dapat signup reward kecil bila prospek daftar akaun melalui link anda. \u2022 Setiap kali downline topup wallet (min RM20), anda dapat komisen: Tier 1 = 8%, Tier 2 = 3%, Tier [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-369","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=369"}],"version-history":[{"count":34,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/369\/revisions"}],"predecessor-version":[{"id":1532,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/369\/revisions\/1532"}],"wp:attachment":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}