Chủ Nhật, 1 tháng 11, 2026

Zalopay + Send Email

 Down Load: Tại đây

** Code:

include_once 'zalopay_process.php';

$mail_content = array(

    'Tài khoản'   => $mbrow['congty_vi'],

    'Email'       => $mbrow['user_email'],

    'Mã số thuế'  => $tax_code,

    'Gói dịch vụ' => $item_name,

    'Số tiền'     => number_format($amount_vnd, 0, ',', '.') . ' VNĐ',

    'Mã chuyển khoản' => $transfer_code

);

$mail_ok = false;

if (function_exists('zp_mail_request')) {

    $mail_ok = zp_mail_request($mail_content , $mbrow['user_email'],$mbrow['username'],"superpage");

}

echo zp_json(array(

    "status"     => 1,

    "mail"       => $mail_ok ? 1 : 0,

    "mail_error" => $mail_ok ? '' : (isset($GLOBALS['zp_mail_error']) ? $GLOBALS['zp_mail_error'] : ''),  // xóa dòng này khi chạy thật

    "message"    => "Đăng ký thành công! Chúng tôi đã ghi nhận yêu cầu của bạn" .

    ($mail_ok ? " và gửi email xác nhận." : ". (Email xác nhận chưa gửi được, quản trị viên sẽ liên hệ với bạn.)")

));

exit;

   

# 👉 zalopay_process.php 

<?php

/**

 * zalopay_process.php

 * Logic dùng chung: kích hoạt gói + gửi mail + tiện ích JSON.

 * Tương thích PHP 5.3.

 */


// Khóa bí mật để ký link giả lập (đổi thành chuỗi ngẫu nhiên của bạn)

if (!defined('ZP_MOCK_SECRET')) define('ZP_MOCK_SECRET', 'DOI_CHUOI_BI_MAT_NAY_123456');

// Bật/tắt chế độ giả lập. KHI LÊN PRODUCTION: đặt false

if (!defined('ZP_MOCK_ENABLED')) define('ZP_MOCK_ENABLED', true);

/* ==========

 *  KÍCH HOẠT GÓI

 * ========== */

/**

 * Kích hoạt gói cho user. An toàn khi gọi nhiều lần (idempotent):

 * chỉ cập nhật + gửi mail ở lần đầu tiên (status chưa = 1).

 *

 * @return array ['ok'=>bool, 'already'=>bool, 'package'=>string, 'mail'=>bool, 'msg'=>string]

 */

function zp_activate_package($db, $user_id)

{

    $res = array('ok' => false, 'already' => false, 'package' => '', 'mail' => false, 'msg' => '');

    $user_id = intval($user_id);

    if ($user_id <= 0) { $res['msg'] = 'user_id không hợp lệ'; return $res; }


    $q = $db->sql_query("SELECT * FROM api_verified_payment WHERE shopid = '$user_id' ORDER BY id DESC LIMIT 1");

    $payment_row = $db->sql_fetch_assoc($q);

    if (!$payment_row) { $res['msg'] = 'Không tìm thấy đơn thanh toán'; return $res; }


    $package_type = trim($payment_row['package_type']);

    // Gói gia hạn (V-...) cùng cấp với gói gốc

    $levels = array(

        'BUSINESS' => 3, 'FACTORY' => 4, 'GLOBAL' => 5,

        'V-BUSINESS' => 3, 'V-FACTORY' => 4, 'V-GLOBAL' => 5

    );

    if (!isset($levels[$package_type])) { $res['msg'] = 'Gói không hợp lệ'; return $res; }


    $res['package'] = $package_type;


    // Đã xử lý trước đó -> không làm lại, không gửi mail lại

    if (intval($payment_row['status']) === 1) {

        $res['ok'] = true;

        $res['already'] = true;

        return $res;

    }


    $user_level = $levels[$package_type];

    $payment_id = intval($payment_row['id']);


    // 1. Cập nhật dữ liệu

    $db->sql_query("UPDATE nvb8bbf_users SET user_level = $user_level WHERE user_id = '$user_id'");

    $db->sql_query("UPDATE api_verified_payment SET status = 1 WHERE id = $payment_id");


    // 2. Gửi mail cho khách

    $uq = $db->sql_query("SELECT email, username FROM nvb8bbf_users WHERE user_id = '$user_id' LIMIT 1");

    $user = $db->sql_fetch_assoc($uq);

    if ($user && !empty($user['email'])) {

        $res['mail'] = zp_send_mail($user['email'], $user['username'], $package_type);

    }


    $res['ok'] = true;

    return $res;

}


/* ==========================================================

 *  EMAIL (dùng PHPMailer + cấu hình SMTP có sẵn của site)

 *  Cần các file của site:

 *    includes/data/mail_config.php  ($mail_mailserver, $mail_username, $mail_password, $mail_email)

 *    classes/class.phpmailer.php

 *    classes/class.smtp.php

 * ========================================================== */


/** Tự dò thư mục gốc của site (nơi có thư mục classes/ và includes/) */

function zp_find_root()

{

    $here = dirname(__FILE__);

    $candidates = array(

        $here . '/',

        $here . '/../',

        $here . '/../../',

        $here . '/../../../'

    );

    if (!empty($_SERVER['DOCUMENT_ROOT'])) {

        $candidates[] = rtrim($_SERVER['DOCUMENT_ROOT'], '/\\') . '/';

    }

    foreach ($candidates as $c) {

        if (file_exists($c . 'classes/class.phpmailer.php') && file_exists($c . 'includes/data/mail_config.php')) {

            return $c;

        }

    }

    return false;

}


/** Một dòng "Nhãn: giá trị" trong mail (bỏ qua nếu rỗng) */

function zp_mail_row($label, $val)

{

    $val = trim((string)$val);

    if ($val === '') return '';

    return '<p style="line-height:1.6;margin:6px 0"><b>' . htmlspecialchars($label) . ':</b> ' . htmlspecialchars($val) . '</p>';

}


/** Khung mail chung (logo + tiêu đề + nội dung + footer) */

function zp_mail_template($title, $content_html)

{

    global $site_live, $ThemeSel;

    $logo = (isset($site_live) ? $site_live : '') . 'themes/' . (isset($ThemeSel) ? $ThemeSel : '') . '/images/logo.png';

    return '

    <div style="max-width:600px;margin:20px auto;background:#fff;border-radius:12px;overflow:hidden;border:1px solid #ccc;font-family:Roboto,Arial,sans-serif">

        <div style="background:#f1f1f1;padding:20px">

            <img src="' . $logo . '" alt="Logo" style="max-height:70px">

        </div>

        <div style="padding:30px;color:#333">

            <h2 style="margin-top:0;color:#ED3237">' . $title . '</h2>

            ' . $content_html . '

            <p style="line-height:1.6">Trân trọng,<br>Đội ngũ ban quản trị vietb2b.com</p>

        </div>

        <div style="background:#ED3237;color:#fff;text-align:center;padding:15px;font-size:14px">

            Mọi thắc mắc và hỗ trợ, vui lòng liên hệ HOTLINE: 0903018626

        </div>

    </div>';

}


/** Ghi lỗi gửi mail vào biến toàn cục + file zalopay_mail_error.log (cùng thư mục) */

function zp_mail_fail($msg)

{

    global $zp_mail_error;

    $zp_mail_error = $msg;

    $GLOBALS['zp_mail_error'] = $msg;

    @file_put_contents(dirname(__FILE__) . '/zalopay_mail_error.log', date('Y-m-d H:i:s') . ' - ' . $msg . "\n", FILE_APPEND);

    return false;

}


/**

 * Gửi mail qua SMTP của site.

 * $to / $cc: mảng array(array(email, tên), ...). $to rỗng => gửi cho admin ($mail_email)

 * @return bool

 */

function zp_mail_send($subject, $body, $to = array(), $cc = array()){


    global $zp_mail_error, $zp_mail_debug;

    $zp_mail_error = '';

    $GLOBALS['zp_mail_error'] = '';


    $root = zp_find_root();

    if ($root === false) {

        return zp_mail_fail('Không tìm thấy classes/class.phpmailer.php hoặc includes/data/mail_config.php (thử trong ' . dirname(__FILE__) . ' và các thư mục cha)');

    }


    // include (không _once) để các biến cấu hình luôn có trong hàm này

    include $root . 'includes/data/mail_config.php';


    // Chỉ nạp PHPMailer nếu site chưa nạp (tránh "Cannot redeclare class PHPMailer")

    if (!class_exists('PHPMailer')) {

        require_once $root . 'classes/class.smtp.php';

        require_once $root . 'classes/class.phpmailer.php';

    }

    if (!class_exists('PHPMailer')) return zp_mail_fail('Không có class PHPMailer');

    if (empty($mail_mailserver) || empty($mail_username)) {

        return zp_mail_fail('mail_config.php thiếu $mail_mailserver / $mail_username');

    }


    $mail = new PHPMailer();

    $mail->CharSet    = 'UTF-8';

    $mail->IsSMTP();

    $mail->Host       = $mail_mailserver;

    $mail->SMTPAuth   = true;

    $mail->Username   = $mail_username;

    $mail->Password   = $mail_password;

    $mail->SMTPSecure = 'ssl';

    $mail->Port       = 465;

    $mail->Timeout    = 20;

    if (!empty($zp_mail_debug)) $mail->SMTPDebug = 2;   // chỉ bật trong file test

    $mail->SetFrom($mail_username, 'VietB2B.com');


    if (empty($to) && !empty($mail_email)) $to = array(array($mail_email, 'Admin VietB2B'));

    $has_to = false;

    foreach ($to as $t) {

        if (!empty($t[0]) && filter_var($t[0], FILTER_VALIDATE_EMAIL)) {

            $mail->AddAddress($t[0], isset($t[1]) ? $t[1] : '');

            $has_to = true;

        }

    }

    if (!$has_to) return zp_mail_fail('Không có địa chỉ người nhận hợp lệ (kiểm tra $mail_email trong mail_config.php)');


    foreach ($cc as $c) {

        if (!empty($c[0]) && filter_var($c[0], FILTER_VALIDATE_EMAIL)) {

            $mail->AddCC($c[0], isset($c[1]) ? $c[1] : '');

        }

    }


    $mail->IsHTML(true);

    $mail->Subject = $subject;

    $mail->Body    = $body;

    $mail->AltBody = strip_tags($body);


    if ($mail->Send()) return true;

    return zp_mail_fail('SMTP lỗi: ' . $mail->ErrorInfo);

}


##┌────────────────────────────────────────────────┐     

function zp_mail_types()

{

    return array(

        'verified' => array(

            'title'         => 'Đăng ký dịch vụ xác thực doanh nghiệp',

            'subject_admin' => 'Xác thực doanh nghiệp Verified',

            'subject_cust'  => 'VIETB2B - Đã nhận yêu cầu xác thực doanh nghiệp',

            'intro'         => 'VIETB2B đã nhận được yêu cầu đăng ký dịch vụ xác thực doanh nghiệp của bạn với thông tin sau:'

        ),

        'superpage' => array(

            'title'         => 'Đăng ký dịch vụ Superpage',

            'subject_admin' => 'Đăng ký dịch vụ Superpage',

            'subject_cust'  => 'VIETB2B - Đã nhận yêu cầu đăng ký Superpage',

            'intro'         => 'VIETB2B đã nhận được yêu cầu đăng ký dịch vụ Superpage của bạn với thông tin sau:'

        ),

        'verified_upgrade' => array(

            'title'         => 'Nâng cấp gói dịch vụ Verified',

            'subject_admin' => 'Nâng cấp gói dịch vụ Verified',

            'subject_cust'  => 'VIETB2B - Đã nhận yêu cầu nâng cấp gói dịch vụ Verified',

            'intro'         => 'VIETB2B đã nhận được yêu cầu nâng cấp gói dịch vụ Verified của bạn với thông tin sau:'

        ),

        'verified_renew' => array(

            'title'         => 'Gia hạn gói dịch vụ Verified',

            'subject_admin' => 'Gia hạn gói dịch vụ Verified',

            'subject_cust'  => 'VIETB2B - Đã nhận yêu cầu gia hạn gói dịch vụ Verified',

            'intro'         => 'VIETB2B đã nhận được yêu cầu gia hạn gói dịch vụ Verified của bạn với thông tin sau:'

        ),

        'superpage_renew' => array(

            'title'         => 'Gia hạn gói Superpage',

            'subject_admin' => 'Gia hạn gói Superpage',

            'subject_cust'  => 'VIETB2B - Đã nhận yêu cầu gia hạn gói Superpage',

            'intro'         => 'VIETB2B đã nhận được yêu cầu gia hạn gói Superpage của bạn với thông tin sau:'

        )

    );

}


function zp_mail_request($rows, $cust_email = '', $cust_name = '', $type = 'verified')

{

    $types = zp_mail_types();

    $cfg   = isset($types[$type]) ? $types[$type] : $types['verified'];


    $html = '';

    foreach ($rows as $label => $val) $html .= zp_mail_row($label, $val);


    $cust_email = trim((string)$cust_email);

    $cust_ok    = ($cust_email !== '' && filter_var($cust_email, FILTER_VALIDATE_EMAIL));


    // 1. Gửi admin (KHÔNG CC khách, vì khách đã nhận mail riêng ở bước 2 -> tránh khách nhận 2 mail)

    $body_admin = zp_mail_template($cfg['title'], $html);

    $ok_admin   = zp_mail_send($cfg['subject_admin'], $body_admin, array(), array());

    $err_admin  = isset($GLOBALS['zp_mail_error']) ? $GLOBALS['zp_mail_error'] : '';


    // 2. Gửi RIÊNG một mail cho khách (chắc chắn hơn CC)

    $ok_cust = false;

    if ($cust_ok) {

        $intro  = '<p>Xin chào <b>' . htmlspecialchars($cust_name) . '</b>,</p>';

        $intro .= '<p>' . $cfg['intro'] . '</p>';

        $body_c = zp_mail_template($cfg['title'], $intro . $html);

        $ok_cust = zp_mail_send($cfg['subject_cust'], $body_c, array(array($cust_email, $cust_name)));

    } else {

        zp_mail_fail('Không gửi được cho khách: email rỗng hoặc không hợp lệ ("' . $cust_email . '")');

    }

    $err_cust = isset($GLOBALS['zp_mail_error']) ? $GLOBALS['zp_mail_error'] : '';


    // Gộp thông báo lỗi để hiện ở mail_error

    $errs = array();

    if (!$ok_admin) $errs[] = 'Admin: ' . $err_admin;

    if (!$ok_cust)  $errs[] = 'Khách: ' . $err_cust;

    $GLOBALS['zp_mail_error'] = implode(' | ', $errs);

    return ($ok_admin && $ok_cust);

}

##└────────────────────────────────────────────────┘


/** Mail "Yêu cầu xác thực Super Page": gửi admin, CC khách. $rows = array('Nhãn' => 'giá trị') */

function zp_mail_request__BanGoc($rows, $cust_email = '', $cust_name = ''){


    $html = '';

    foreach ($rows as $label => $val) $html .= zp_mail_row($label, $val);

    $body = zp_mail_template('Đăng ký dịch vụ xác thực doanh nghiệp', $html);

    $cc   = $cust_email ? array(array($cust_email, $cust_name)) : array();

    return zp_mail_send('Xác thực doanh nghiệp Verified', $body, array(), $cc);

}

/** Mail báo đăng ký gói Superpage thành công: gửi cho khách */

function zp_send_mail($to, $username, $package)

{

    $html  = '<p>Xin chào <b>' . htmlspecialchars($username) . '</b>,</p>';

    $html .= '<p>Bạn đã đăng ký thành công gói <b>Superpage (' . htmlspecialchars($package) . ')</b> trên VIETB2B.</p>';

    $html .= '<p>Tài khoản của bạn đã được nâng cấp và có thể sử dụng ngay các quyền lợi của gói.</p>';

    $body  = zp_mail_template('Đăng ký gói Superpage thành công!', $html);

    return zp_mail_send('VIETB2B - Đăng ký gói Superpage thành công', $body, array(array($to, $username)));

}

/* =============

 *  LINK GIẢ LẬP (chống người khác tự gõ URL để nâng cấp gói)

 * ============= */

function zp_mock_sign($user_id, $apptransid, $status, $ts){

    return hash_hmac('sha256', $user_id . '|' . $apptransid . '|' . $status . '|' . $ts, ZP_MOCK_SECRET);

}

function zp_mock_verify($user_id, $apptransid, $status, $ts, $sig)

{

    if (!ZP_MOCK_ENABLED) return false;

    if (abs(time() - intval($ts)) > 600) return false; // link hết hạn sau 10 phút

    return zp_safe_equals(zp_mock_sign($user_id, $apptransid, $status, $ts), (string)$sig);

}

/** So sánh chuỗi an toàn (thay hash_equals vì PHP 5.3 chưa có) */

function zp_safe_equals($a, $b)

{

    if (strlen($a) !== strlen($b)) return false;

    $diff = 0;

    for ($i = 0, $n = strlen($a); $i < $n; $i++) {

        $diff |= ord($a[$i]) ^ ord($b[$i]);

    }

    return $diff === 0;

}

/* ==========================================================

 *  JSON giữ nguyên tiếng Việt (PHP 5.3 chưa có JSON_UNESCAPED_UNICODE)

 *  Cần bật extension mbstring.

 * ========================================================== */

function zp_json($data)

{

    $json = json_encode($data);

    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', 'zp_json_unescape_cb', $json);

}

function zp_json_unescape_cb($m)

{

    $code = hexdec($m[1]);

    // Giữ nguyên ký tự ASCII, surrogate (emoji) và dấu phân tách dòng để JSON không bị hỏng

    if ($code < 0x80 || ($code >= 0xD800 && $code <= 0xDFFF) || $code == 0x2028 || $code == 0x2029) {

        return $m[0];

    }

    return mb_convert_encoding(pack('H*', $m[1]), 'UTF-8', 'UCS-2BE');

}

Không có nhận xét nào:

Đăng nhận xét