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