feat: implement email logging and test price mode functionality with QR code generation for order confirmations
This commit is contained in:
20
.vscode/ftp-kr.sync.cache.json
vendored
20
.vscode/ftp-kr.sync.cache.json
vendored
@@ -60,8 +60,8 @@
|
||||
"controls": {
|
||||
"class.Apanel.php": {
|
||||
"type": "-",
|
||||
"size": 9256,
|
||||
"lmtime": 1772747455304,
|
||||
"size": 9377,
|
||||
"lmtime": 1772806035809,
|
||||
"modified": false
|
||||
},
|
||||
"class.Cron.php": {
|
||||
@@ -122,8 +122,8 @@
|
||||
},
|
||||
"class.Tickets.php": {
|
||||
"type": "-",
|
||||
"size": 7784,
|
||||
"lmtime": 1772747439621,
|
||||
"size": 7959,
|
||||
"lmtime": 1772788752331,
|
||||
"modified": false
|
||||
},
|
||||
"class.Users.php": {
|
||||
@@ -920,6 +920,12 @@
|
||||
}
|
||||
},
|
||||
"admin-panel": {
|
||||
"calendar.php": {
|
||||
"type": "-",
|
||||
"size": 7561,
|
||||
"lmtime": 1772788844785,
|
||||
"modified": false
|
||||
},
|
||||
"login.php": {
|
||||
"type": "-",
|
||||
"size": 376,
|
||||
@@ -961,12 +967,6 @@
|
||||
"size": 4615,
|
||||
"lmtime": 1771856674000,
|
||||
"modified": false
|
||||
},
|
||||
"calendar.php": {
|
||||
"type": "-",
|
||||
"size": 5189,
|
||||
"lmtime": 1772747510115,
|
||||
"modified": false
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
|
||||
@@ -1,6 +1,78 @@
|
||||
<?php
|
||||
class S
|
||||
{
|
||||
private static function get_route_param( $var )
|
||||
{
|
||||
$var = trim((string) $var);
|
||||
if ( $var === '' || empty($_SERVER['REQUEST_URI']) )
|
||||
return null;
|
||||
|
||||
$uriPath = explode('?', (string) $_SERVER['REQUEST_URI'], 2)[0];
|
||||
$segments = explode('/', trim($uriPath, '/'));
|
||||
|
||||
foreach ( $segments as $segment )
|
||||
{
|
||||
if ( strpos($segment, '=') === false )
|
||||
continue;
|
||||
|
||||
list($key, $value) = explode('=', $segment, 2);
|
||||
if ( trim((string) $key) === $var )
|
||||
return urldecode((string) $value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function get_rewrite_tail_param( $var )
|
||||
{
|
||||
$var = trim((string) $var);
|
||||
$queryString = (string) ( $_SERVER['QUERY_STRING'] ?? '' );
|
||||
|
||||
if ( $var === '' || $queryString === '' )
|
||||
return null;
|
||||
|
||||
$parts = explode('/', $queryString);
|
||||
foreach ( $parts as $part )
|
||||
{
|
||||
if ( strpos($part, '=') === false )
|
||||
continue;
|
||||
|
||||
list($key, $value) = explode('=', $part, 2);
|
||||
if ( trim((string) $key) === $var )
|
||||
return urldecode((string) $value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function log_mail_event( $level, $message, $context = [] )
|
||||
{
|
||||
global $settings;
|
||||
|
||||
if ( empty($settings['mail_debug_log_enabled']) )
|
||||
return;
|
||||
|
||||
$rootPath = dirname(__DIR__);
|
||||
$logFile = $rootPath . DIRECTORY_SEPARATOR . 'mail_debug.log';
|
||||
|
||||
$time = date('Y-m-d H:i:s');
|
||||
$line = '[' . $time . '] [' . strtoupper((string) $level) . '] ' . (string) $message;
|
||||
|
||||
if ( is_array( $context ) && !empty( $context ) )
|
||||
{
|
||||
$line .= ' | ' . json_encode( $context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
|
||||
}
|
||||
|
||||
$line .= PHP_EOL;
|
||||
$written = @file_put_contents( $logFile, $line, FILE_APPEND );
|
||||
|
||||
if ( $written === false )
|
||||
{
|
||||
if ( !empty($settings['mail_debug_error_log_enabled']) )
|
||||
error_log( 'Mail log write error: ' . $logFile . ' | ' . $line );
|
||||
}
|
||||
}
|
||||
|
||||
public static function array_unique_multi( $array, $key )
|
||||
{
|
||||
$temp_array = [];
|
||||
@@ -172,8 +244,31 @@ class S
|
||||
}
|
||||
if ( isset( $_GET[ $var ] ) )
|
||||
{
|
||||
return $_GET[ $var ];
|
||||
$value = $_GET[ $var ];
|
||||
|
||||
if ( is_string($value) && strpos($value, '/') !== false )
|
||||
{
|
||||
$segments = explode('/', $value);
|
||||
$head = trim((string) ($segments[0] ?? ''));
|
||||
if ( $head !== '' )
|
||||
return urldecode($head);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$routeValue = self::get_route_param( $var );
|
||||
if ( $routeValue !== null )
|
||||
{
|
||||
return $routeValue;
|
||||
}
|
||||
|
||||
$rewriteTailValue = self::get_rewrite_tail_param( $var );
|
||||
if ( $rewriteTailValue !== null )
|
||||
{
|
||||
return $rewriteTailValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -198,10 +293,94 @@ class S
|
||||
return filter_var( $email, FILTER_VALIDATE_EMAIL );
|
||||
}
|
||||
|
||||
private static function normalize_attachments( $file )
|
||||
{
|
||||
$attachments = [];
|
||||
|
||||
if ( is_array( $file ) )
|
||||
{
|
||||
foreach ( $file as $file_tmp )
|
||||
{
|
||||
if ( !empty( $file_tmp ) && file_exists( $file_tmp ) )
|
||||
$attachments[] = $file_tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !empty( $file ) && file_exists( $file ) )
|
||||
$attachments[] = $file;
|
||||
}
|
||||
|
||||
return $attachments;
|
||||
}
|
||||
|
||||
private static function send_email_native( $email, $subject, $text, $attachments, $settings )
|
||||
{
|
||||
$from = trim((string) ($settings['email_from'] ?? 'bilety@brzezovka.pl'));
|
||||
$replyTo = trim((string) ($settings['email_reply_to'] ?? $from));
|
||||
$bccEmail = trim((string) ($settings['email_bcc'] ?? ''));
|
||||
|
||||
$headers = [];
|
||||
$headers[] = 'From: ' . $from;
|
||||
$headers[] = 'Reply-To: ' . $replyTo;
|
||||
if ( $bccEmail !== '' && self::email_check( $bccEmail ) )
|
||||
$headers[] = 'Bcc: ' . $bccEmail;
|
||||
$headers[] = 'MIME-Version: 1.0';
|
||||
|
||||
$encodedSubject = '=?UTF-8?B?' . base64_encode((string) $subject) . '?=';
|
||||
|
||||
if ( empty($attachments) )
|
||||
{
|
||||
$headers[] = 'Content-Type: text/html; charset=UTF-8';
|
||||
$ok = @mail($email, $encodedSubject, (string) $text, implode("\r\n", $headers));
|
||||
return (bool) $ok;
|
||||
}
|
||||
|
||||
$boundary = 'boundary_' . md5(uniqid((string) mt_rand(), true));
|
||||
$headers[] = 'Content-Type: multipart/mixed; boundary="' . $boundary . '"';
|
||||
|
||||
$body = '';
|
||||
$body .= '--' . $boundary . "\r\n";
|
||||
$body .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
$body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
|
||||
$body .= (string) $text . "\r\n";
|
||||
|
||||
foreach ( $attachments as $attachment )
|
||||
{
|
||||
$content = @file_get_contents($attachment);
|
||||
if ( $content === false )
|
||||
continue;
|
||||
|
||||
$filename = basename($attachment);
|
||||
$body .= '--' . $boundary . "\r\n";
|
||||
$body .= 'Content-Type: application/octet-stream; name="' . $filename . '"' . "\r\n";
|
||||
$body .= "Content-Transfer-Encoding: base64\r\n";
|
||||
$body .= 'Content-Disposition: attachment; filename="' . $filename . '"' . "\r\n\r\n";
|
||||
$body .= chunk_split(base64_encode($content)) . "\r\n";
|
||||
}
|
||||
|
||||
$body .= '--' . $boundary . "--\r\n";
|
||||
|
||||
$ok = @mail($email, $encodedSubject, $body, implode("\r\n", $headers));
|
||||
return (bool) $ok;
|
||||
}
|
||||
|
||||
public static function send_email( $email, $subject, $text, $file = '' )
|
||||
{
|
||||
global $settings;
|
||||
|
||||
$email = trim((string) $email);
|
||||
if ( !self::email_check( $email ) )
|
||||
{
|
||||
self::log_mail_event( 'error', 'Mail send aborted - invalid recipient', [
|
||||
'to' => $email,
|
||||
'subject' => $subject
|
||||
] );
|
||||
return false;
|
||||
}
|
||||
|
||||
$attachments = self::normalize_attachments( $file );
|
||||
|
||||
$mail = new PHPMailer;
|
||||
$mail -> IsSMTP();
|
||||
$mail -> SMTPAuth = true;
|
||||
@@ -220,27 +399,65 @@ class S
|
||||
$mail -> From = 'bilety@brzezovka.pl';
|
||||
$mail -> FromName = 'KOMPLEKS TURYSTYCZNY BRZEZÓVKA';
|
||||
$mail -> addAddress( $email, $email );
|
||||
$mail -> addBCC( 'bilety@brzezovka.pl' );
|
||||
$mail -> addReplyTo( 'bilety@brzezovka.pl', 'KOMPLEKS TURYSTYCZNY BRZEZÓVKA' );
|
||||
$mail -> isHTML( true );
|
||||
|
||||
$bccEmail = trim((string) ($settings['email_bcc'] ?? ''));
|
||||
if ( $bccEmail !== '' && self::email_check( $bccEmail ) )
|
||||
{
|
||||
$mail -> addBCC( $bccEmail );
|
||||
}
|
||||
|
||||
$mail -> Subject = $subject;
|
||||
$mail -> Body = $text;
|
||||
foreach ( $attachments as $attachment )
|
||||
$mail -> AddAttachment( $attachment );
|
||||
|
||||
if ( is_array( $file ) )
|
||||
{
|
||||
foreach ( $file as $file_tmp )
|
||||
self::log_mail_event( 'info', 'Mail send attempt', [
|
||||
'to' => $email,
|
||||
'subject' => $subject,
|
||||
'attachments' => $attachments
|
||||
] );
|
||||
|
||||
$isSent = $mail -> send();
|
||||
|
||||
if (!$isSent) {
|
||||
self::log_mail_event( 'error', 'Mail send failed', [
|
||||
'to' => $email,
|
||||
'subject' => $subject,
|
||||
'error' => $mail->ErrorInfo
|
||||
] );
|
||||
if ( !empty($settings['mail_debug_error_log_enabled']) )
|
||||
error_log('Mail send error to ' . $email . ': ' . $mail->ErrorInfo);
|
||||
|
||||
self::log_mail_event( 'info', 'Mail send fallback attempt (native mail)', [
|
||||
'to' => $email,
|
||||
'subject' => $subject
|
||||
] );
|
||||
|
||||
$fallbackSent = self::send_email_native( $email, $subject, $text, $attachments, $settings );
|
||||
if ( $fallbackSent )
|
||||
{
|
||||
if ( !empty( $file_tmp ) && file_exists( $file_tmp ) )
|
||||
$mail -> AddAttachment( $file_tmp );
|
||||
self::log_mail_event( 'info', 'Mail send fallback success (native mail)', [
|
||||
'to' => $email,
|
||||
'subject' => $subject
|
||||
] );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !empty( $file ) && file_exists( $file ) )
|
||||
$mail -> AddAttachment( $file );
|
||||
|
||||
$lastError = error_get_last();
|
||||
self::log_mail_event( 'error', 'Mail send fallback failed (native mail)', [
|
||||
'to' => $email,
|
||||
'subject' => $subject,
|
||||
'error' => is_array($lastError) ? ($lastError['message'] ?? '') : ''
|
||||
] );
|
||||
} else {
|
||||
self::log_mail_event( 'info', 'Mail send success', [
|
||||
'to' => $email,
|
||||
'subject' => $subject
|
||||
] );
|
||||
}
|
||||
|
||||
return $mail -> send();
|
||||
return $isSent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,144 @@ namespace controls;
|
||||
|
||||
class Tickets
|
||||
{
|
||||
private static function sendPaidOrderSummaryEmail(array $order)
|
||||
{
|
||||
$hash = trim((string) ($order['hash'] ?? ''));
|
||||
$email = trim((string) ($order['email'] ?? ''));
|
||||
|
||||
if ($hash === '' || $email === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dir = 'orders/' . $hash[0] . '/' . $hash[1] . '/';
|
||||
$qrFilePath = $dir . $hash . '.png';
|
||||
|
||||
if (!file_exists($qrFilePath)) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
\QRcode::png($hash, $qrFilePath, QR_ECLEVEL_H, 4);
|
||||
}
|
||||
|
||||
$orderId = (int) ($order['id'] ?? 0);
|
||||
$orderPrice = $order['order_price'] ?? '0';
|
||||
$invoiceUrl = trim((string) ($order['invoice_url'] ?? ''));
|
||||
$orderLink = 'https://bilety.brzezovka.pl/tickets/order_confirm/order=' . $hash;
|
||||
|
||||
$subject = 'brzezovka.pl - potwierdzenie platnosci zamowienia #' . $orderId;
|
||||
$message = '<div style="width:100%; max-width: 600px; margin: 0 auto;">';
|
||||
$message .= '<h2>Platnosc zostala potwierdzona</h2>';
|
||||
$message .= '<p>Numer zamowienia: <strong>' . $orderId . '</strong></p>';
|
||||
$message .= '<p>Kwota: <strong>' . $orderPrice . ' zl</strong></p>';
|
||||
$message .= '<p>Szczegoly zamowienia: <a href="' . $orderLink . '">' . $orderLink . '</a></p>';
|
||||
if ($invoiceUrl !== '') {
|
||||
$message .= '<p>Dokument sprzedazy: <a href="' . $invoiceUrl . '">' . $invoiceUrl . '</a></p>';
|
||||
}
|
||||
$message .= '<p>W zalaczniku dodany jest kod QR biletu (PNG).</p>';
|
||||
$message .= '</div>';
|
||||
|
||||
return \S::send_email($email, $subject, $message, $qrFilePath);
|
||||
}
|
||||
|
||||
private static function isValidTestPriceSecret($secret)
|
||||
{
|
||||
global $settings;
|
||||
|
||||
$expectedSecret = trim((string) ($settings['test_price_mode_secret'] ?? ''));
|
||||
$providedSecret = trim((string) $secret);
|
||||
|
||||
if ($expectedSecret === '' || $providedSecret === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hash_equals($expectedSecret, $providedSecret);
|
||||
}
|
||||
|
||||
private static function applyTestPriceToBasket()
|
||||
{
|
||||
$basket = \S::get_session('basket');
|
||||
|
||||
if (!is_array($basket) || empty($basket)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($basket as $ticketId => &$variants) {
|
||||
if (!is_array($variants)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($variants as &$variant) {
|
||||
if (!is_array($variant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$variant['ticket_price'] = 1.0;
|
||||
}
|
||||
unset($variant);
|
||||
}
|
||||
unset($variants);
|
||||
|
||||
\S::set_session('basket', $basket);
|
||||
}
|
||||
|
||||
static public function test_price_mode_on()
|
||||
{
|
||||
$secret = \S::get('secret');
|
||||
|
||||
if (!self::isValidTestPriceSecret($secret)) {
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
\S::set_session('lower_price_ticket', true);
|
||||
self::applyTestPriceToBasket();
|
||||
\S::alert('Test mode: all ticket prices are set to 1 zl.');
|
||||
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function test_price_mode_off()
|
||||
{
|
||||
$secret = \S::get('secret');
|
||||
|
||||
if (!self::isValidTestPriceSecret($secret)) {
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
\S::del_session('lower_price_ticket');
|
||||
\S::del_session('basket');
|
||||
\S::alert('Test mode disabled. Basket has been cleared.');
|
||||
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function resend_order_email()
|
||||
{
|
||||
$secret = \S::get('secret');
|
||||
$hash = trim((string) \S::get('order'));
|
||||
|
||||
if (!self::isValidTestPriceSecret($secret) || $hash === '') {
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
$order = \factory\Tickets::get_order_details_by_hash($hash);
|
||||
if (!$order) {
|
||||
\S::alert('Order not found.');
|
||||
header('Location: /tickets/main_view/');
|
||||
exit;
|
||||
}
|
||||
|
||||
$isSent = self::sendPaidOrderSummaryEmail($order);
|
||||
\S::alert($isSent ? 'Order e-mail has been resent.' : 'Could not resend e-mail. Check SMTP logs.');
|
||||
|
||||
header('Location: /tickets/order_confirm/order=' . $hash);
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function main_view()
|
||||
{
|
||||
global $settings;
|
||||
@@ -667,13 +805,16 @@ class Tickets
|
||||
if ($order['payment_status'])
|
||||
{
|
||||
$order_successful = true;
|
||||
$mailSent = self::sendPaidOrderSummaryEmail($order);
|
||||
if ($mailSent) {
|
||||
$mdb->update('orders', ['informed_user' => 1], ['id' => $order['id']]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$order_fail = true;
|
||||
$mdb->update('orders', ['informed_user' => 1], ['id' => $order['id']]);
|
||||
}
|
||||
|
||||
$mdb->update('orders', ['informed_user' => 1], ['id' => $order['id']]);
|
||||
}
|
||||
|
||||
return \Tpl::view( 'tickets/order-confirm', [
|
||||
|
||||
@@ -8,6 +8,8 @@ $settings['email_host'] = 'h53.seohost.pl';
|
||||
$settings['email_port'] = 25;
|
||||
$settings['email_login'] = 'bilety@brzezovka.pl';
|
||||
$settings['email_password'] = 'biletyonline';
|
||||
$settings['mail_debug_log_enabled'] = false;
|
||||
$settings['mail_debug_error_log_enabled'] = false;
|
||||
|
||||
// Park rozrywki i dinozaurow
|
||||
$settings['tickets']['plac-zabaw-ulgowy']['name'] = 'Park rozrywki i dinozaurów - ulgowy';
|
||||
@@ -117,3 +119,4 @@ $settings['p24']['sandbox_crc_key'] = 'a48ba2394a52373a';
|
||||
$settings['p24']['sandbox'] = false;
|
||||
|
||||
$settings['admin-password'] = 'Admin2022!';
|
||||
$settings['test_price_mode_secret'] = 'jvVtWNrvWr7c4HhepYDu';
|
||||
|
||||
@@ -36,9 +36,6 @@ if ($_SESSION['ip'] !== $_SERVER['REMOTE_ADDR']) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( isset($_GET['debug']) && $_GET['debug'] == 'lower_price_ticket' )
|
||||
$_SESSION['lower_price_ticket'] = true;
|
||||
|
||||
\R::setup('mysql:host=' . $database['host'] . ';dbname=' . $database['name'], $database['user'], $database['password']);
|
||||
\R::ext('xdispense', function ($type) {
|
||||
return R::getRedBean() -> dispense($type);
|
||||
@@ -55,4 +52,4 @@ $mdb = new medoo([
|
||||
require_once 'load_prices.php';
|
||||
|
||||
$user = \S::get_session('user');
|
||||
echo \view\Site::show();
|
||||
echo \view\Site::show();
|
||||
|
||||
@@ -2607,14 +2607,13 @@ class PHPMailer
|
||||
if (!is_readable($path)) {
|
||||
throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
|
||||
}
|
||||
$magic_quotes = get_magic_quotes_runtime();
|
||||
$magic_quotes = function_exists('get_magic_quotes_runtime') ? get_magic_quotes_runtime() : false;
|
||||
if ($magic_quotes) {
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
set_magic_quotes_runtime(false);
|
||||
if (function_exists('set_magic_quotes_runtime')) {
|
||||
set_magic_quotes_runtime(false);
|
||||
}
|
||||
} else {
|
||||
//Doesn't exist in PHP 5.4, but we don't need to check because
|
||||
//get_magic_quotes_runtime always returns false in 5.4+
|
||||
//so it will never get here
|
||||
ini_set('magic_quotes_runtime', false);
|
||||
}
|
||||
}
|
||||
@@ -2622,7 +2621,9 @@ class PHPMailer
|
||||
$file_buffer = $this->encodeString($file_buffer, $encoding);
|
||||
if ($magic_quotes) {
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
set_magic_quotes_runtime($magic_quotes);
|
||||
if (function_exists('set_magic_quotes_runtime')) {
|
||||
set_magic_quotes_runtime($magic_quotes);
|
||||
}
|
||||
} else {
|
||||
ini_set('magic_quotes_runtime', $magic_quotes);
|
||||
}
|
||||
@@ -3921,4 +3922,4 @@ class phpmailerException extends Exception
|
||||
$errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
|
||||
return $errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,13 @@ foreach ($settings['tickets'] as $tid => &$_ticket) {
|
||||
$_ticket['dynamic_prices'] = $_ticket['dynamic_prices'] ?? ['day0' => 0, 'day1_2' => 0, 'day3_7' => 0];
|
||||
}
|
||||
}
|
||||
|
||||
if (\S::get_session('lower_price_ticket')) {
|
||||
foreach ($settings['tickets'] as &$_ticket) {
|
||||
$_ticket['price'] = 1.0;
|
||||
$_ticket['price_weekend'] = 1.0;
|
||||
$_ticket['dynamic_prices'] = ['day0' => 0.0, 'day1_2' => 0.0, 'day3_7' => 0.0];
|
||||
}
|
||||
}
|
||||
|
||||
unset($_ticket, $_dbStmt, $_dbPrices, $_r);
|
||||
|
||||
8
mail_debug.log
Normal file
8
mail_debug.log
Normal file
@@ -0,0 +1,8 @@
|
||||
[2026-03-10 13:05:25] [INFO] Mail send attempt | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","attachments":["orders/e/e/eeee5f8008effb60a5d54f83c4f66564.png"]}
|
||||
[2026-03-10 13:05:59] [INFO] Mail send attempt | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","attachments":["orders/e/e/eeee5f8008effb60a5d54f83c4f66564.png"]}
|
||||
[2026-03-10 13:06:43] [INFO] Mail send attempt | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","attachments":["orders/e/e/eeee5f8008effb60a5d54f83c4f66564.png"]}
|
||||
[2026-03-10 13:06:43] [ERROR] Mail send failed | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","error":"SMTP Error: The following recipients failed: biuro@project-pro.pl: Account bilety@brzezovka.pl currently blocked for sending to too many\r\ninvalid recipients\r\nbilety@brzezovka.pl: "}
|
||||
[2026-03-10 13:09:43] [INFO] Mail send attempt | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","attachments":["orders/e/e/eeee5f8008effb60a5d54f83c4f66564.png"]}
|
||||
[2026-03-10 13:09:43] [ERROR] Mail send failed | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242","error":"SMTP Error: The following recipients failed: biuro@project-pro.pl: Account bilety@brzezovka.pl currently blocked for sending to too many\r\ninvalid recipients\r\n"}
|
||||
[2026-03-10 13:09:43] [INFO] Mail send fallback attempt (native mail) | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242"}
|
||||
[2026-03-10 13:09:43] [INFO] Mail send fallback success (native mail) | {"to":"biuro@project-pro.pl","subject":"brzezovka.pl - potwierdzenie platnosci zamowienia #1242"}
|
||||
Reference in New Issue
Block a user