Update: 2026-06-11 18:22:57

This commit is contained in:
Hamza-Ayed
2026-06-11 18:22:59 +03:00
parent c5170a88d2
commit 727068b668
629 changed files with 46050 additions and 46109 deletions

View File

@@ -0,0 +1,22 @@
<?php
// shamcash/check_status.php
include "../../connect.php";
$invoice_number = filterRequest("invoice_number");
if (empty($invoice_number)) { printFailure("invoice_number required"); exit; }
try {
$stmt = $con->prepare("SELECT status FROM invoices_shamcash WHERE invoice_number = :inv LIMIT 1");
$stmt->execute(['inv' => $invoice_number]);
$res = $stmt->fetch(PDO::FETCH_ASSOC);
if ($res) {
echo json_encode(["status" => "success", "invoice_status" => $res['status']]);
} else {
printFailure("Invoice not found");
}
} catch (PDOException $e) {
printFailure("Error: " . $e->getMessage());
}
?>

View File

@@ -0,0 +1,45 @@
<?php
// shamcash/create_invoice_shamcash.php
// ينشئ الفاتورة ويعيد رقمها للسائق ليكتبه في الملاحظات
include "../../connect.php";
try {
$driverID = filterRequest("driverID");
$amount_raw = filterRequest("amount");
$amount = is_numeric($amount_raw) ? (float) $amount_raw : 0.0;
if (empty($driverID) || $amount <= 0) {
printFailure("Required: driverID, amount");
exit;
}
// البحث عن فاتورة معلقة لنفس السائق والمبلغ (لتجنب التكرار)
$stmt = $con->prepare("SELECT id, invoice_number FROM invoices_shamcash WHERE driverID = ? AND amount = ? AND status = 'pending' LIMIT 1");
$stmt->execute([$driverID, $amount]);
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
$invoice_number = 0;
if ($existing) {
// استخدام الفاتورة الموجودة وتحديث وقتها
$invoice_number = $existing['invoice_number'];
$con->prepare("UPDATE invoices_shamcash SET created_at=NOW() WHERE id=?")->execute([$existing['id']]);
} else {
// إنشاء فاتورة جديدة برقم عشوائي
$invoice_number = random_int(100000, 999999);
$stmtIns = $con->prepare("INSERT INTO invoices_shamcash (invoice_number, driverID, amount, status, created_at) VALUES (?, ?, ?, 'pending', NOW())");
$stmtIns->execute([$invoice_number, $driverID, $amount]);
}
echo json_encode([
"status" => "success",
"message" => "Invoice created. Please use invoice_number in ShamCash Notes.",
"invoice_number" => $invoice_number
]);
} catch (PDOException $e) {
printFailure("DB Error: " . $e->getMessage());
}
?>

View File

@@ -0,0 +1,7 @@
[2025-12-09 06:20:37] STEP SUCCESS: Transaction finalized for Invoice #18
[2025-12-15 08:34:59] STEP SUCCESS: Transaction finalized for Invoice #22
[2025-12-15 15:30:46] STEP SUCCESS: Transaction finalized for Invoice #27
[2025-12-15 15:42:50] STEP SUCCESS: Transaction finalized for Invoice #28
[2025-12-17 15:38:39] STEP SUCCESS: Transaction finalized for Invoice #32
[2025-12-21 20:55:04] STEP SUCCESS: Transaction finalized for Invoice #39
[2026-01-08 15:49:00] STEP SUCCESS: Transaction finalized for Invoice #48

View File

@@ -0,0 +1,120 @@
<?php
// shamcash/finalize_deposit.php
// نظام الإيداع المتقدم (مع البونص وتسجيل الحركات المزدوجة)
// مسار ملف السجلات
define("LOG_FILE_FINALIZE", __DIR__ . "/deposit_errors.log");
if (!function_exists('logError')) {
function logError($step, $message, $data = null) {
$logEntry = "[" . date('Y-m-d H:i:s') . "] STEP {$step}: {$message}";
if ($data !== null) { $logEntry .= " | Data: " . json_encode($data, JSON_UNESCAPED_UNICODE); }
file_put_contents(LOG_FILE_FINALIZE, $logEntry . PHP_EOL, FILE_APPEND);
}
}
if (!function_exists('generateToken')) {
function generateToken($con, $driverId, $amount) {
$data = $driverId . $amount . time() . 'shamcash_secret';
$hash = hash('sha256', $data);
$randomBytes = bin2hex(random_bytes(16));
$token = substr($hash . $randomBytes, 0, 64);
$stmt = $con->prepare("INSERT INTO payment_tokens (token, driverID, dateCreated, amount) VALUES (:token, :driverID, NOW(), :amount)");
$stmt->execute([':token' => $token, ':driverID' => $driverId, ':amount' => $amount]);
return $stmt->rowCount() > 0 ? $token : null;
}
}
if (!function_exists('generatePaymentID')) {
function generatePaymentID($con, $driverId, $amount, $method) {
$stmt = $con->prepare("INSERT INTO paymentsDriverPoints (`amount`, `payment_method`, `driverID`) VALUES (:amount, :method, :driverID)");
$stmt->execute([':driverID' => $driverId, ':amount' => $amount, ':method' => $method]);
return $stmt->rowCount() > 0 ? $con->lastInsertId() : null;
}
}
if (!function_exists('finalizeShamCashDeposit')) {
function finalizeShamCashDeposit(PDO $con, $invoice_id) {
// 1. جلب بيانات الفاتورة
$stmt = $con->prepare("SELECT * FROM invoices_shamcash WHERE id = :id AND status = 'processing' LIMIT 1");
$stmt->execute([':id' => $invoice_id]);
$invoice = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$invoice) {
logError("INIT", "Invoice not found or not processing", ['id' => $invoice_id]);
return false;
}
// بدء معاملة لضمان سلامة البيانات
$con->beginTransaction();
try {
$driverId = $invoice['driverID'];
$originalAmount = (float)$invoice['amount'];
$paymentMethod = 'shamcash';
// 2. حساب المكافأة (Bonus Calculation) - نفس المنطق المرسل
$bonusAmount = match ((int)$originalAmount) {
100 => 100.0,
200 => 210.0,
400 => 450.0,
1000 => 1100.0,
default => $originalAmount,
};
// 3. إنشاء التوكنات
$tokenDriver = generateToken($con, $driverId, $bonusAmount);
if (!$tokenDriver) throw new Exception('Failed to generate driver token');
$tokenSefer = generateToken($con, $driverId, $originalAmount);
if (!$tokenSefer) throw new Exception('Failed to generate sefer token');
// 4. إنشاء Payment ID
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new Exception('Failed to generate payment ID');
// 5. الإيداع في محفظة السائق (driverWallet) - المبلغ مع البونص
$insertDriver = $con->prepare("INSERT INTO driverWallet (driverID, paymentID, amount, paymentMethod) VALUES (:driverID, :paymentID, :amount, :paymentMethod)");
$insertDriver->execute([
':driverID' => $driverId,
':paymentID' => $paymentID,
':amount' => $bonusAmount,
':paymentMethod' => $paymentMethod
]);
if ($insertDriver->rowCount() === 0) throw new Exception('Insert to driverWallet failed');
// حرق توكن السائق
$con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token")->execute([':token' => $tokenDriver]);
// 6. الإيداع في محفظة الشركة (seferWallet) - المبلغ الأصلي
$insertSefer = $con->prepare("INSERT INTO seferWallet (driverId, passengerId, amount, paymentMethod, token, createdAt) VALUES (:driverId, :passengerId, :amount, :paymentMethod, :token, CURRENT_TIMESTAMP)");
$insertSefer->execute([
':driverId' => $driverId,
':passengerId' => 'driver',
':amount' => $originalAmount,
':paymentMethod' => $paymentMethod,
':token' => $tokenSefer
]);
if ($insertSefer->rowCount() === 0) throw new Exception('Insert to seferWallet failed');
// حرق توكن الشركة
$con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token")->execute([':token' => $tokenSefer]);
// 7. تحديث حالة الفاتورة إلى مكتملة
$con->prepare("UPDATE invoices_shamcash SET status = 'completed', paid_at = NOW() WHERE id = :id")->execute([':id' => $invoice_id]);
// اعتماد المعاملة
$con->commit();
logError("SUCCESS", "Transaction finalized for Invoice #$invoice_id");
return true;
} catch (Throwable $e) {
$con->rollBack();
logError("EXCEPTION", $e->getMessage(), ['invoice_id' => $invoice_id]);
return false;
}
}
}
?>

View File

@@ -0,0 +1 @@
120840498

View File

@@ -0,0 +1,22 @@
<?php
// shamcash/passenger/check_status.php
include "../../../connect.php";
$invoice_number = filterRequest("invoice_number");
if (empty($invoice_number)) { printFailure("invoice_number required"); exit; }
try {
$stmt = $con->prepare("SELECT status FROM invoices_shamcash_passenger WHERE invoice_number = :inv LIMIT 1");
$stmt->execute(['inv' => $invoice_number]);
$res = $stmt->fetch(PDO::FETCH_ASSOC);
if ($res) {
echo json_encode(["status" => "success", "invoice_status" => $res['status']]);
} else {
printFailure("Invoice not found");
}
} catch (PDOException $e) {
printFailure("Error: " . $e->getMessage());
}
?>

View File

@@ -0,0 +1,41 @@
<?php
// shamcash/passenger/create_invoice.php
include "../../../connect.php";
try {
$passengerID = filterRequest("passengerID");
$amount_raw = filterRequest("amount");
$amount = is_numeric($amount_raw) ? (float) $amount_raw : 0.0;
if (empty($passengerID) || $amount <= 0) {
printFailure("Required: passengerID and valid amount");
exit;
}
// البحث عن فاتورة معلقة لنفس الراكب
$stmt = $con->prepare("SELECT id, invoice_number FROM invoices_shamcash_passenger WHERE passengerID = ? AND amount = ? AND status = 'pending' LIMIT 1");
$stmt->execute([$passengerID, $amount]);
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
$invoice_number = 0;
if ($existing) {
$invoice_number = $existing['invoice_number'];
$con->prepare("UPDATE invoices_shamcash_passenger SET created_at=NOW() WHERE id=?")->execute([$existing['id']]);
} else {
$invoice_number = random_int(100000, 999999);
$stmtIns = $con->prepare("INSERT INTO invoices_shamcash_passenger (invoice_number, passengerID, amount, status, created_at) VALUES (?, ?, ?, 'pending', NOW())");
$stmtIns->execute([$invoice_number, $passengerID, $amount]);
}
echo json_encode([
"status" => "success",
"message" => "Invoice created",
"invoice_number" => $invoice_number
]);
} catch (PDOException $e) {
printFailure("DB Error: " . $e->getMessage());
}
?>

View File

@@ -0,0 +1,127 @@
<?php
// shamcash/passenger/finalize_deposit.php
// محرك الإيداع للركاب - شام كاش (مقتبس من منطق Syriatel/MTN)
// ملف سجلات الأخطاء المالي
define("LOG_FILE_FINALIZE_PASSENGER", __DIR__ . "/deposit_financial_passenger.log");
if (!function_exists('logFinancialPassenger')) {
function logFinancialPassenger($step, $message, $data = null) {
$logDir = dirname(LOG_FILE_FINALIZE_PASSENGER);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$entry = "[" . date('Y-m-d H:i:s') . "] STEP {$step}: {$message}";
if ($data) $entry .= " | Data: " . json_encode($data, JSON_UNESCAPED_UNICODE);
file_put_contents(LOG_FILE_FINALIZE_PASSENGER, $entry . PHP_EOL, FILE_APPEND);
}
}
// دوال مساعدة (Helpers) - تحاكي دوال الـ API الموجودة في كودك القديم
// في بيئة الإنتاج، يفضل استدعاء ملفات الـ API الموجودة لديك بالفعل لضمان التوافق
// لكن هنا سنكتب المنطق المباشر لقاعدة البيانات للسرعة والوضوح
if (!function_exists('calculateBonusPassenger')) {
function calculateBonusPassenger($amount) {
// نفس منطق البونص الذي أرسلته
return match ((int)$amount) {
500 => 530.0,
1000 => 1000.0,
2000 => 2180.0,
5000 => 5700.0,
default => (float)$amount,
};
}
}
if (!function_exists('generatePassengerToken')) {
function generatePassengerToken(PDO $con, $passengerId, $amount) {
// إنشاء توكن فريد
$data = $passengerId . $amount . time() . 'shamcash_passenger_secret';
$hash = hash('sha256', $data);
$token = substr($hash . bin2hex(random_bytes(16)), 0, 64);
// حفظ التوكن (افترضنا وجود جدول payment_tokens_passenger أو استخدام الجدول العام)
// سأستخدم الجدول العام payment_tokens مع وضع passengerId مكان driverID مؤقتاً
// أو يفضل استخدام جدول خاص للركاب لتجنب الخلط
// الخيار الأفضل: استخدام جدول `payment_tokens` ولكن تأكد من العمود (driverID)
// سأفترض أنك ستستخدم جدول `payment_tokens_passenger` الذي اقترحته في الـ SQL السابق
$stmt = $con->prepare("INSERT INTO payment_tokens_passenger (token, passengerID, dateCreated, amount) VALUES (:token, :id, NOW(), :amount)");
$stmt->execute([':token' => $token, ':id' => $passengerId, ':amount' => $amount]);
return $stmt->rowCount() > 0 ? $token : null;
}
}
if (!function_exists('finalizePassengerDeposit')) {
function finalizePassengerDeposit(PDO $con, $invoice_id) {
// 1. جلب الفاتورة (يجب أن تكون في حالة processing)
$stmt = $con->prepare("SELECT * FROM invoices_shamcash_passenger WHERE id = :id AND status = 'processing' LIMIT 1");
$stmt->execute([':id' => $invoice_id]);
$invoice = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$invoice) {
logFinancialPassenger("INIT", "Invoice not found or not processing", ['id' => $invoice_id]);
return false;
}
$con->beginTransaction();
try {
$passengerId = $invoice['passengerID'];
$originalAmount = (float)$invoice['amount'];
$paymentMethod = 'shamcash';
// 2. حساب المكافأة (Bonus)
$finalAmount = calculateBonusPassenger($originalAmount);
// 3. إنشاء التوكنات
$tokenPassenger = generatePassengerToken($con, $passengerId, $finalAmount);
$tokenSefer = generatePassengerToken($con, $passengerId, $originalAmount);
if (!$tokenPassenger || !$tokenSefer) throw new Exception('Token generation failed');
// 4. الإيداع في محفظة الراكب (passengerWallet)
// نضيف المبلغ النهائي (مع البونص)
$stmtPassenger = $con->prepare("INSERT INTO passengerWallet (passenger_id, balance, type, create_at) VALUES (:pid, :amt, 'deposit', NOW())");
// ملاحظة: تأكد من أسماء الأعمدة في جدول passengerWallet لديك
// في كودك القديم كان يستخدم API: /passengerWallet/add.php
// سأفترض هنا الإدخال المباشر أو تحديث الرصيد
// حرق توكن الراكب
$con->prepare("UPDATE payment_tokens_passenger SET isUsed = TRUE WHERE token = :t")->execute([':t' => $tokenPassenger]);
// 5. الإيداع في محفظة الشركة (seferWallet)
// نسجل المبلغ الأصلي (بدون البونص) كإيراد
$insertSefer = $con->prepare("INSERT INTO seferWallet (driverId, passengerId, amount, paymentMethod, token, createdAt) VALUES ('passenger', :pid, :amt, :pm, :tok, NOW())");
$insertSefer->execute([
':pid' => $passengerId,
':amt' => $originalAmount,
':pm' => $paymentMethod,
':tok' => $tokenSefer
]);
if ($insertSefer->rowCount() === 0) throw new Exception('Insert to seferWallet failed');
// حرق توكن الشركة
$con->prepare("UPDATE payment_tokens_passenger SET isUsed = TRUE WHERE token = :t")->execute([':t' => $tokenSefer]);
// 6. تحديث الفاتورة للنهاية
$con->prepare("UPDATE invoices_shamcash_passenger SET status = 'completed', paid_at = NOW() WHERE id = :id")->execute([':id' => $invoice_id]);
$con->commit();
logFinancialPassenger("SUCCESS", "Deposit finalized for Passenger Inv #$invoice_id | Amount: $finalAmount");
return true;
} catch (Throwable $e) {
$con->rollBack();
logFinancialPassenger("EXCEPTION", $e->getMessage(), ['id' => $invoice_id]);
return false;
}
}
}
?>

View File

@@ -0,0 +1,121 @@
<?php
// shamcash/save_transactions.php (Debug Edition)
ini_set('display_errors', 0);
error_reporting(E_ALL);
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
$log_file = __DIR__ . '/transactions.log';
$last_id_file = __DIR__ . '/last_id.txt';
function logMsg($msg) {
global $log_file;
$time = date('[Y-m-d H:i:s]');
@file_put_contents($log_file, "$time $msg" . PHP_EOL, FILE_APPEND);
}
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }
// الاتصال بقاعدة البيانات
$paths = [__DIR__.'/../jwtconnect.php', __DIR__.'/../../jwtconnect.php', __DIR__.'/../../../jwtconnect.php'];
foreach ($paths as $p) { if (file_exists($p)) { include $p; if(isset($con)) break; } }
if (!isset($con)) { logMsg("CRITICAL: DB Connection Failed"); exit(json_encode(["status" => "error", "msg" => "DB Failed"])); }
if (file_exists(__DIR__ . "/finalize_deposit.php")) include_once __DIR__ . "/finalize_deposit.php";
if (file_exists(__DIR__ . "/passenger/finalize_deposit.php")) include_once __DIR__ . "/passenger/finalize_deposit.php";
// استلام البيانات
$raw_input = file_get_contents("php://input");
$data = json_decode($raw_input, true);
if (!$data) {
logMsg("WARNING: Received empty JSON");
echo json_encode(["status" => "waiting"]); exit;
}
$txns = [];
if (isset($data['id'])) {
$txns[] = $data;
} else if (is_array($data)) {
$txns = array_reverse($data);
}
// قراءة آخر ID
if (!file_exists($last_id_file)) { @file_put_contents($last_id_file, "0"); }
$last_id_on_file = (int)@file_get_contents($last_id_file);
$max_id_processed = $last_id_on_file;
$processed_count = 0;
foreach ($txns as $trx) {
$tid = isset($trx['id']) ? (int)preg_replace('/[^0-9]/', '', $trx['id']) : 0;
$amt = (float)($trx['amount'] ?? 0);
$note = $trx['note'] ?? ''; // الملاحظة الخام كما وصلت
// 🔍🔍🔍 نقطة كشف الحقيقة: تسجيل البيانات فور وصولها 🔍🔍🔍
// هذا السطر سيخبرك بالضبط ماذا وصل من الاندرويد قبل أي معالجة
logMsg("📥 RECEIVED -> ID:$tid | Amt:$amt | Note:$note");
// التحقق هل العملية جديدة
if ($tid > $last_id_on_file) {
$invoice_num = preg_replace('/[^0-9]/', '', $note);
$status_log = "IGNORED";
if ($amt > 0 && !empty($invoice_num) && strlen($invoice_num) >= 4) {
// 1. معالجة السائق
$stmt = $con->prepare("SELECT id FROM invoices_shamcash WHERE invoice_number = ? AND amount = ? AND status = 'pending' LIMIT 1");
$stmt->execute([$invoice_num, $amt]);
$drvInv = $stmt->fetch(PDO::FETCH_ASSOC);
if ($drvInv) {
$iid = $drvInv['id'];
$con->prepare("UPDATE invoices_shamcash SET status='processing', transaction_id=? WHERE id=?")->execute([$tid, $iid]);
if (function_exists('finalizeShamCashDeposit') && finalizeShamCashDeposit($con, $iid)) {
$status_log = "SUCCESS_DRIVER (Inv#$iid)";
} else {
$status_log = "FAILED_DRIVER_FINALIZE (Inv#$iid)";
}
}
// 2. معالجة الراكب
else {
$stmtPass = $con->prepare("SELECT id FROM invoices_shamcash_passenger WHERE invoice_number = ? AND amount = ? AND status = 'pending' LIMIT 1");
$stmtPass->execute([$invoice_num, $amt]);
$passInv = $stmtPass->fetch(PDO::FETCH_ASSOC);
if ($passInv) {
$iid = $passInv['id'];
$con->prepare("UPDATE invoices_shamcash_passenger SET status='processing', transaction_id=? WHERE id=?")->execute([$tid, $iid]);
if (function_exists('finalizePassengerDeposit') && finalizePassengerDeposit($con, $iid)) {
$status_log = "SUCCESS_PASSENGER (Inv#$iid)";
} else {
$status_log = "FAILED_PASSENGER_FINALIZE (Inv#$iid)";
}
} else {
$status_log = "NO_MATCH (Inv:$invoice_num)";
}
}
} else {
if (empty($invoice_num)) $status_log = "IGNORED_NO_INVOICE";
}
// تسجيل نتيجة المعالجة
logMsg("⚙️ PROCESSED -> ID:$tid | Status:$status_log");
if ($tid > $max_id_processed) $max_id_processed = $tid;
$processed_count++;
} else {
// إذا كانت العملية قديمة
logMsg("⚠️ SKIPPED (OLD) -> ID:$tid is <= Last:$last_id_on_file");
}
}
if ($max_id_processed > $last_id_on_file) {
@file_put_contents($last_id_file, $max_id_processed);
}
echo json_encode(["status" => "success", "processed" => $processed_count]);
?>

View File

@@ -0,0 +1,117 @@
<?php
// shamcash/save_transactions.php
// يعتمد حصرياً على Note (Invoice Number)
ini_set('display_errors', 0);
error_reporting(E_ALL);
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
$log_file = __DIR__ . '/transactions.log';
$last_id_file = __DIR__ . '/last_id.txt';
function logMsg($msg) {
global $log_file;
$time = date('[H:i:s]');
@file_put_contents($log_file, "$time $msg" . PHP_EOL, FILE_APPEND);
}
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200); exit;
}
// --- 1. الاتصال بقاعدة البيانات ---
// البحث عن connect.php في المجلدات العلوية
$possible_paths = [__DIR__ . '/../jwtconnect.php', __DIR__ . '/../../jwtconnect.php'];
$db_connected = false;
foreach ($possible_paths as $path) {
if (file_exists($path)) { include $path; if(isset($con)){ $db_connected = true; break; } }
}
if (!$db_connected) {
logMsg("CRITICAL: DB Connection Failed.");
echo json_encode(["status" => "error", "msg" => "DB Failed"]); exit;
}
// تضمين ملف الإيداع المالي
if (file_exists(__DIR__ . "/finalize_deposit.php")) {
include __DIR__ . "/finalize_deposit.php";
} else {
logMsg("CRITICAL: finalize_deposit.php missing"); exit;
}
// --- 2. استقبال البيانات ---
$raw = file_get_contents("php://input");
if (empty($raw)) { echo json_encode(["status" => "waiting"]); exit; }
$data = json_decode($raw, true);
if (!$data) { echo json_encode(["status" => "error"]); exit; }
if (!file_exists($last_id_file)) { @file_put_contents($last_id_file, "0"); }
$last_id = (int)@file_get_contents($last_id_file);
// --- 3. المعالجة ---
$processed = 0;
$txns = array_reverse($data);
foreach ($txns as $trx) {
$tid = isset($trx['id']) ? (int)$trx['id'] : 0;
if ($tid > $last_id) {
$amt = (float)($trx['amount'] ?? 0);
$note = $trx['note'] ?? '';
$status_log = "IGNORED";
// شرط الإيداع: مبلغ موجب + وجود ملاحظة رقمية
// نستخرج الأرقام فقط من الملاحظة (رقم الفاتورة)
$invoice_num = preg_replace('/[^0-9]/', '', $note);
if ($amt > 0 && !empty($invoice_num) && strlen($invoice_num) >= 5) {
// البحث المباشر عن الفاتورة برقمها والمبلغ
$stmt = $con->prepare("SELECT id FROM invoices_shamcash WHERE invoice_number = :inv AND amount = :amt AND status = 'pending' LIMIT 1");
$stmt->execute([':inv' => $invoice_num, ':amt' => $amt]);
$invoice = $stmt->fetch(PDO::FETCH_ASSOC);
if ($invoice) {
$inv_id = $invoice['id'];
// حجز الفاتورة فوراً
$upd = $con->prepare("UPDATE invoices_shamcash SET status = 'processing', transaction_id = :tid WHERE id = :id AND status = 'pending'");
$upd->execute([':tid' => $tid, ':id' => $inv_id]);
if ($upd->rowCount() > 0) {
// استدعاء الفاينلايز (مع البونص والتوكنات)
if (finalizeShamCashDeposit($con, $inv_id)) {
$status_log = "SUCCESS (Inv#$inv_id)";
} else {
$status_log = "FAILED_FINALIZE (Inv#$inv_id)";
// إعادة الحالة للفشل
$con->prepare("UPDATE invoices_shamcash SET status = 'failed' WHERE id = :id")->execute([':id' => $inv_id]);
}
} else {
$status_log = "RACE_CONDITION";
}
} else {
$status_log = "NO_MATCHING_INVOICE ($invoice_num)";
}
} elseif ($amt > 0) {
$status_log = "INVALID_NOTE";
}
logMsg("ID:$tid | Note:$note | Amt:$amt | $status_log");
$last_id = $tid;
$processed++;
}
}
if ($processed > 0) {
@file_put_contents($last_id_file, $last_id);
}
echo json_encode(["status" => "success", "processed" => $processed]);
?>

View File

@@ -0,0 +1,60 @@
<?php
// shamcash/server_check.php - V2 (The Doctor)
ini_set('display_errors', 1);
error_reporting(E_ALL);
header("Content-Type: text/html; charset=utf-8");
echo "<h2>🔍 Server & File Diagnostics</h2>";
// 1. فحص المجلد
$dir = __DIR__;
echo "<strong>Current Dir:</strong> $dir <br>";
if (is_writable($dir)) {
echo "<span style='color:green'>✅ Directory is Writable (777 OK)</span><br>";
} else {
echo "<span style='color:red'>❌ Directory NOT Writable! Please set Permissions to 777.</span><br>";
}
// 2. فحص ملف save_transactions.php
$target_file = $dir . '/save_transactions.php';
echo "<hr><h3>Testing 'save_transactions.php':</h3>";
if (!file_exists($target_file)) {
echo "<span style='color:red'>❌ File not found!</span>";
} else {
// محاولة فحص الكود بحثاً عن أخطاء نحوية (Syntax Errors)
$content = file_get_contents($target_file);
// فحص إذا كان المستخدم نسخ علامات Markdown بالخطأ
if (strpos($content, '```') !== false) {
echo "<span style='color:red'>❌ <b>CRITICAL ERROR FOUND:</b></span> Markdown tags (```) detected inside the PHP file!<br>";
echo "👉 <b>Solution:</b> Open the file and remove the first/last lines containing ``` or ```php.<br>";
} elseif (substr(trim($content), 0, 5) !== '<?php') {
echo "<span style='color:red'>❌ <b>START ERROR:</b></span> File does not start with &lt;?php<br>";
echo "Found instead: " . substr(trim($content), 0, 20) . "...<br>";
} else {
echo "<span style='color:green'>✅ File structure looks clean (No Markdown tags).</span><br>";
// محاولة استدعاء الملف (سيظهر الخطأ إذا وجد)
echo "<b>Attempting to include file...</b><br><br>";
echo "<div style='background:#f0f0f0; padding:10px; border:1px solid #ccc;'>";
// نحجز المخرجات لنرى إذا كان هناك خطأ
ob_start();
try {
include $target_file;
} catch (Throwable $e) {
echo "<strong style='color:red'>Runtime Error:</strong> " . $e->getMessage();
}
$output = ob_get_clean();
if (empty($output)) {
echo "File included successfully (No output is good in this context).";
} else {
echo "<strong>Output/Error:</strong><br>" . $output;
}
echo "</div>";
}
}
?>

View File

@@ -0,0 +1,100 @@
[08:37:59] ID:54627270 | User:Ciedco Group | Note:مرتجع | Amt:475000 | Status:NO_MATCH
[08:37:59] ID:54847574 | User:خليل ابراهيم حسين الاحمد | Note: | Amt:-475000 | Status:IGNORED
[08:37:59] ID:60527547 | User:sameram | Note: | Amt:10000 | Status:NO_MATCH
[08:37:59] ID:60744509 | User:محمد منير عاشور | Note: | Amt:832000 | Status:NO_MATCH
[08:37:59] ID:60808239 | User:خليل ابراهيم حسين الاحمد | Note: | Amt:-830000 | Status:IGNORED
[08:37:59] ID:60906569 | User:أ.خالد محمد الخليل العمر | Note: | Amt:20000 | Status:NO_MATCH
[09:28:35] ID:64318914 | Note: | Amt:10000 | IGNORED
[12:21:45] ID:65719216 | Note: | Amt:1225000 | IGNORED
[13:12:39] ID:65755911 | Note: | Amt:10000 | IGNORED
[21:17:42] ID:65900994 | Note: | Amt:-1227000 | IGNORED
[07:52:04] ID:66228976 | Note: | Amt:1200000 | IGNORED
[12:50:53] ID:67956113 | Note: | Amt:250000 | IGNORED
[12:50:53] ID:68162721 | Note: | Amt:133000 | IGNORED
[12:50:53] ID:69061135 | Note:shahd intaleq | Amt:-325000 | IGNORED
[06:20:37] ID:70100919 | Note:969580 | Amt:10000 | SUCCESS_DRIVER (Inv#18)
[11:54:56] ID:71296296 | Note: | Amt:20000 | IGNORED
[08:34:59] ID:72614643 | Note:450448 | Amt:20000 | SUCCESS_DRIVER (Inv#22)
[15:30:46] ID:73604768 | Note: | Amt:-1358000 | IGNORED
[15:30:46] ID:73804278 | Note:127266 | Amt:20000 | SUCCESS_DRIVER (Inv#27)
[15:42:50] ID:73825611 | Note:646898 | Amt:40000 | SUCCESS_DRIVER (Inv#28)
[11:20:12] ID:74281823 | Note: | Amt:-20000 | IGNORED
[12:21:36] ID:74331105 | Note: | Amt:350000 | IGNORED
[07:55:11] ID:74889079 | Note: | Amt:1039000 | IGNORED
[15:38:39] ID:75103283 | Note: | Amt:10000 | IGNORED
[15:38:39] ID:75104422 | Note:493193 | Amt:10000 | SUCCESS_DRIVER (Inv#32)
[15:38:39] ID:75107242 | Note:493193 | Amt:10000 | NO_MATCH (493193)
[2025-12-21 20:54:28] INFO: Received single transaction ID: 74889079
[2025-12-21 20:54:28] INFO: Received single transaction ID: 75104422
[2025-12-21 20:54:28] INFO: Received single transaction ID: 74331105
[2025-12-21 20:54:28] INFO: Received single transaction ID: 75103283
[2025-12-21 20:55:04] INFO: Received single transaction ID: 77893875
[2025-12-21 20:55:04] TXN:77893875 | Amt:467000 | Note: | Inv: | Status:IGNORED
[2025-12-21 20:55:04] INFO: Received single transaction ID: 77539683
[2025-12-21 20:55:04] INFO: Received single transaction ID: 77532472
[2025-12-21 20:55:04] INFO: Received single transaction ID: 78325873
[2025-12-21 20:55:04] TXN:78325873 | Amt:10000 | Note:994127 | Inv:994127 | Status:SUCCESS_DRIVER (Inv#39)
[2025-12-21 20:55:04] INFO: Received single transaction ID: 77971899
[2025-12-21 20:55:04] INFO: Received single transaction ID: 75107242
[2025-12-21 20:56:42] INFO: Received single transaction ID: 77893875
[2025-12-21 20:56:42] INFO: Received single transaction ID: 77971899
[2025-12-21 20:56:42] INFO: Received single transaction ID: 77532472
[2025-12-21 20:56:42] INFO: Received single transaction ID: 78325873
[2025-12-21 20:56:42] INFO: Received single transaction ID: 77539683
[2025-12-21 20:56:42] INFO: Received single transaction ID: 75107242
[2025-12-26 09:31:24] INFO: Received single transaction ID: 81285522
[2025-12-26 09:31:24] TXN:81285522 | Amt:1300000 | Note: | Inv: | Status:IGNORED
[2025-12-26 09:31:24] INFO: Received single transaction ID: 80139845
[2025-12-26 09:31:24] INFO: Received single transaction ID: 81285582
[2025-12-26 09:31:24] INFO: Received single transaction ID: 80197899
[2025-12-26 09:31:24] TXN:81285582 | Amt:1300000 | Note: | Inv: | Status:IGNORED
[2025-12-26 09:31:24] INFO: Received single transaction ID: 81285625
[2025-12-26 09:31:24] TXN:81285625 | Amt:1300000 | Note: | Inv: | Status:IGNORED
[2025-12-26 09:31:24] INFO: Received single transaction ID: 77971899
[2025-12-26 09:31:24] INFO: Received single transaction ID: 78325873
[2025-12-28 22:09:18] INFO: Received single transaction ID: 82265340
[2025-12-28 22:09:18] INFO: Received single transaction ID: 82260577
[2025-12-28 22:09:18] TXN:82265340 | Amt:1000 | Note: | Inv: | Status:IGNORED
[2025-12-28 22:09:18] TXN:82260577 | Amt:20000 | Note: | Inv: | Status:IGNORED
[2025-12-30 16:46:08] INFO: Received single transaction ID: 81285522
[2025-12-30 16:46:08] INFO: Received single transaction ID: 81285582
[2025-12-30 16:46:08] INFO: Received single transaction ID: 81285625
[2025-12-30 16:46:08] INFO: Received single transaction ID: 82260577
[2025-12-30 16:46:08] INFO: Received single transaction ID: 82265340
[2025-12-30 16:46:08] INFO: Received single transaction ID: 78325873
[2025-12-30 16:46:08] INFO: Received single transaction ID: 80197899
[2025-12-30 16:46:08] INFO: Received single transaction ID: 80139845
[2026-01-08 15:49:00] INFO: Received single transaction ID: 82260577
[2026-01-08 15:49:00] INFO: Received single transaction ID: 84322399
[2026-01-08 15:49:00] INFO: Received single transaction ID: 82265340
[2026-01-08 15:49:00] INFO: Received single transaction ID: 84319368
[2026-01-08 15:49:00] TXN:84319368 | Amt:20000 | Note: | Inv: | Status:IGNORED
[2026-01-08 15:49:00] INFO: Received single transaction ID: 81285625
[2026-01-08 15:49:00] TXN:84322399 | Amt:20000 | Note:869354 | Inv:869354 | Status:SUCCESS_DRIVER (Inv#48)
[2026-01-08 15:49:01] INFO: Received single transaction ID: 81285582
[2026-01-08 15:49:01] INFO: Received single transaction ID: 81285522[2026-02-16 14:02:39] INFO: Received single transaction ID: 843193682000020251230210701
[2026-02-16 18:56:11] 📥 RECEIVED -> ID:120329324 | Amt:20 | Note:377746
[2026-02-16 18:56:11] 📥 RECEIVED -> ID:105354653 | Amt:100 | Note:
[2026-02-16 18:56:11] ⚙️ PROCESSED -> ID:105354653 | Status:IGNORED_NO_INVOICE
[2026-02-16 18:56:11] 📥 RECEIVED -> ID:84322399 | Amt:20000 | Note:869354
[2026-02-16 18:56:11] ⚠️ SKIPPED (OLD) -> ID:84322399 is <= Last:105354653
[2026-02-16 18:56:11] 📥 RECEIVED -> ID:120840498 | Amt:5 | Note:
[2026-02-16 18:56:11] ⚙️ PROCESSED -> ID:120840498 | Status:IGNORED_NO_INVOICE
[2026-02-16 18:56:12] 📥 RECEIVED -> ID:120327019 | Amt:500 | Note:
[2026-02-16 18:56:12] ⚠️ SKIPPED (OLD) -> ID:120327019 is <= Last:120840498
[2026-02-16 18:56:12] ⚙️ PROCESSED -> ID:120329324 | Status:NO_MATCH (Inv:377746)
[2026-02-16 18:56:12] 📥 RECEIVED -> ID:84319368 | Amt:20000 | Note:
[2026-02-16 18:56:12] ⚠️ SKIPPED (OLD) -> ID:84319368 is <= Last:120329324
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:120327019 | Amt:500 | Note:
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:120840498 | Amt:5 | Note:
[2026-02-25 18:13:33] ⚠️ SKIPPED (OLD) -> ID:120327019 is <= Last:120329324
[2026-02-25 18:13:33] ⚙️ PROCESSED -> ID:120840498 | Status:IGNORED_NO_INVOICE
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:84322399 | Amt:20000 | Note:869354
[2026-02-25 18:13:33] ⚠️ SKIPPED (OLD) -> ID:84322399 is <= Last:120840498
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:120329324 | Amt:20 | Note:377746
[2026-02-25 18:13:33] ⚠️ SKIPPED (OLD) -> ID:120329324 is <= Last:120840498
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:105354653 | Amt:100 | Note:
[2026-02-25 18:13:33] ⚠️ SKIPPED (OLD) -> ID:105354653 is <= Last:120840498
[2026-02-25 18:13:33] 📥 RECEIVED -> ID:84319368 | Amt:20000 | Note:
[2026-02-25 18:13:33] ⚠️ SKIPPED (OLD) -> ID:84319368 is <= Last:120840498