Update: 2026-06-11 19:26:42

This commit is contained in:
Hamza-Ayed
2026-06-11 19:26:42 +03:00
parent 727068b668
commit b87477bec4
371 changed files with 67 additions and 14257 deletions

Binary file not shown.

View File

@@ -1,148 +0,0 @@
<?php
// هذا الملف هو نقطة النهاية بعد الدفع، ويقوم بكل عمليات التحقق وإضافة الرصيد
// This file is the final endpoint after payment, handling all verification and balance updates.
include "../../../jwtconnect.php";
// -------------------------------------------------
// دوال مساعدة لإنشاء التوكنات ومعرفات الدفع
// Helper functions for creating tokens and payment IDs
// -------------------------------------------------
/**
* إنشاء توكن فريد لعملية المحفظة وتخزينه في قاعدة البيانات
* Creates a unique token for a wallet transaction and stores it in the database.
*/
define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride"); // تأكد من صحة هذا الرابط
define("LOG_FILE", "../logs/payment_verification.log");
function logError($step, $message, $data = null) {
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$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, $logEntry . PHP_EOL, FILE_APPEND);
}
function generateToken($con, $driverId, $amount): ?string
{
global $secretKey; // يفترض أن هذا المتغير متاح من ملف الاتصال
$data = $driverId . $amount . time() . ($secretKey ?? 'default_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;
}
/**
* تسجيل دفعة في جدول النقاط وإعادة المعرف الخاص بها
* Logs a payment in the points table and returns its ID.
*/
function generatePaymentID($con, $driverId, $amount, $method): ?string
{
$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;
}
// -------------------------------------------------
// المنطق الرئيسي للمعالجة
// Main processing logic
// -------------------------------------------------
// 1. استقبال الرقم المرجعي من الرابط
// 1. Receive the order reference from the URL.
$orderRef = $_GET['orderRef'] ?? null;
if (empty($orderRef)) {
echo "<h1>خطأ: الرقم المرجعي للطلب مفقود.</h1>";
exit;
}
// 2. الانتظار والتأكد من وصول الـ Webhook
// 2. Wait and verify that the webhook has updated the status.
$payment = null;
$max_attempts = 5; // محاولة لمدة 10 ثوانٍ - Poll for 10 seconds
for ($attempts = 0; $attempts < $max_attempts; $attempts++) {
// تأكد من أن اسم الجدول صحيح
// Make sure the table name is correct.
$stmt = $con->prepare("SELECT * FROM `paymentsLogSyriaDriver` WHERE order_ref = :order_ref AND status = 1 LIMIT 1");
$stmt->execute([':order_ref' => $orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if ($payment) {
break; // تم العثور على الدفعة الناجحة - Successful payment found
}
sleep(2); // الانتظار لمدة ثانيتين قبل المحاولة التالية - Wait 2 seconds before retrying
}
// 3. التحقق من نتيجة البحث
// 3. Check the polling result.
if (!$payment) {
echo "<h1>خطأ في تأكيد الدفع</h1><p>لم نتمكن من تأكيد دفعتك. قد تستغرق العملية بضع لحظات. يرجى التحقق من رصيدك في التطبيق لاحقاً أو التواصل مع الدعم الفني.</p>";
exit;
}
// 4. تمت عملية الدفع بنجاح، لنقم بإضافة الرصيد
// 4. Payment successful, proceed to add balance.
try {
$driverId = $payment['user_id'];
// eCash لا تحتاج للقسمة على 100
// eCash amount does not need division by 100.
$originalAmount = floatval($payment['amount']);
$paymentMethod = $payment['payment_method'] ?? 'ecash';
// حساب المكافأة
// Calculate the bonus.
$bonusAmount = match ((int)$originalAmount) {
80 => 80.0,
200 => 215.0,
400 => 450.0,
1000 => 1140.0,
default => $originalAmount,
};
// --- تنفيذ منطق تحديث المحافظ ---
// --- Execute wallet update logic ---
$tokenDriver = generateToken($con, $driverId, $bonusAmount);
if (!$tokenDriver) throw new Exception('Failed to generate token for driver wallet.');
$tokenSefer = generateToken($con, $driverId, $originalAmount);
if (!$tokenSefer) throw new Exception('Failed to generate token for sefer wallet.');
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new Exception('Failed to generate payment ID.');
// إضافة الرصيد إلى driverWallet
// Add balance to 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('Failed to insert into driverWallet.');
$markTokenDriver = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token");
$markTokenDriver->execute([':token' => $tokenDriver]);
// إضافة الرصيد إلى seferWallet
// Add balance to 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]);
$markTokenSefer = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token");
$markTokenSefer->execute([':token' => $tokenSefer]);
// 5. عرض صفحة النجاح النهائية
// 5. Display final success page.
echo "<h1>تمت العملية بنجاح</h1><p>تمت إضافة الرصيد إلى محفظتك. يمكنك الآن العودة إلى التطبيق.</p>";
} catch (Throwable $e) {
// في حال حدوث خطأ، يتم تسجيله وعرض رسالة للمستخدم
// In case of an error, log it and display a message to the user.
error_log("VERIFY_ERROR: " . $e->getMessage() . " | OrderRef: " . $orderRef);
echo "<h1>حدث خطأ</h1><p>لقد تم استلام دفعتك بنجاح، ولكن حدث خطأ أثناء تحديث رصيدك. يرجى التواصل مع الدعم الفني وتزويدهم بالرقم المرجعي: " . htmlspecialchars($orderRef) . "</p>";
}
?>

View File

@@ -1,91 +0,0 @@
<?php
// استخدام ملف اتصال خاص بالـ Webhook لا يحتوي على أي تحقق من الهوية
include "../../../jwtconnect.php";
/*
|--------------------------------------------------------------------------
| ملف Webhook النهائي الخاص بـ eCash (مع تسجيل إضافي للتصحيح)
|--------------------------------------------------------------------------
*/
// --- الإعدادات ---
$ecash_merchant_id = getenv('ECASH_MERCHANT_ID');
$ecash_merchant_secret = getenv('ECASH_MERCHANT_SECRET');
// --- إعداد ملف اللوج (Log File) ---
$log_dir = __DIR__ . '/../logs';
$log_file = $log_dir . '/ecash_production.log';
if (!is_dir($log_dir)) {
mkdir($log_dir, 0755, true);
}
// --- قراءة البيانات القادمة من eCash ---
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// --- تسجيل الـ Callback كاملاً لأغراض المراقبة ---
file_put_contents($log_file, "--- NEW WEBHOOK ---\n" . date('Y-m-d H:i:s') . " - RAW BODY: " . $raw_body . PHP_EOL, FILE_APPEND);
if (!$data || !isset($data['Token'])) {
http_response_code(400);
exit;
}
// --- استخراج البيانات ---
$isSuccess = $data['IsSuccess'] ?? false;
$transactionNo = $data['TransactionNo'] ?? '';
$amount = $data['Amount'] ?? '';
$orderRef = $data['OrderRef'] ?? '';
$receivedToken = $data['Token'];
// --- **تصحيح الأخطاء: بناء وتسجيل سلسلة التحقق** ---
$verification_string = $ecash_merchant_id . $ecash_merchant_secret . $transactionNo . $amount . $orderRef;
$expectedToken = strtoupper(md5($verification_string));
// تسجيل السلسلة المستخدمة في التوقيع والقيم الفردية
$debug_log = "VERIFICATION STRING: " . $verification_string . PHP_EOL;
$debug_log .= " - Merchant ID Used: " . $ecash_merchant_id . PHP_EOL;
$debug_log .= " - TransactionNo Used: " . $transactionNo . PHP_EOL;
$debug_log .= " - Amount Used: " . $amount . PHP_EOL;
$debug_log .= " - OrderRef Used: " . $orderRef . PHP_EOL;
$debug_log .= "CALCULATED TOKEN: " . $expectedToken . PHP_EOL;
$debug_log .= "RECEIVED TOKEN: " . $receivedToken . PHP_EOL;
file_put_contents($log_file, $debug_log, FILE_APPEND);
// --- التحقق من صحة الـ Token ---
if (!hash_equals($expectedToken, $receivedToken)) {
http_response_code(401);
file_put_contents($log_file, "TOKEN MISMATCH! Process stopped." . PHP_EOL, FILE_APPEND);
exit;
}
// --- تحديث حالة الدفعة في قاعدة البيانات ---
file_put_contents($log_file, "TOKEN MATCH! Proceeding to update database." . PHP_EOL, FILE_APPEND);
$payment_status = $isSuccess ? 1 : 0;
try {
$stmt = $con->prepare(
"UPDATE `paymentsLogSyriaDriver` SET status = :status, updated_at = NOW() WHERE order_ref = :order_ref AND status = 2"
);
$stmt->execute([
':status' => $payment_status,
':order_ref' => $orderRef
]);
if ($stmt->rowCount() > 0) {
http_response_code(200);
file_put_contents($log_file, "SUCCESS: Database updated." . PHP_EOL, FILE_APPEND);
} else {
http_response_code(200);
file_put_contents($log_file, "INFO: Order not found or already processed." . PHP_EOL, FILE_APPEND);
}
} catch (PDOException $e) {
http_response_code(500);
file_put_contents($log_file, "FATAL: Database update failed: " . $e->getMessage() . PHP_EOL, FILE_APPEND);
}
?>

View File

@@ -1,79 +0,0 @@
<?php
// هذا الملف يجب أن يستخدم ملف الاتصال الذي يتحقق من الهوية
include "../../../connect.php";
// يجب استدعاء دالة التحقق هنا لضمان أن الطلب قادم من تطبيقك فقط
/*
|--------------------------------------------------------------------------
| ملف إتمام الدفع النهائي
|--------------------------------------------------------------------------
|
| هذا الملف مسؤول عن:
| 1. استقبال طلب من تطبيق فلاتر بعد عودة المستخدم.
| 2. التحقق من وجود دفعة ناجحة حديثة للمستخدم في قاعدة البيانات.
| 3. حساب المكافآت.
| 4. استدعاء واجهات API داخلية لإضافة الرصيد إلى المحافظ.
|
*/
// --- استقبال البيانات من تطبيق فلاتر ---
$userId = filterRequest("userId"); // أو driverId
$paymentMethod = filterRequest("paymentMethod") ?? 'ecash';
if (empty($userId)) {
printFailure("معرّف المستخدم غير صالح.");
exit;
}
try {
// خطوة 1: البحث عن آخر دفعة ناجحة للمستخدم (تم تحديثها بواسطة الـ Webhook)
$stmt = $con->prepare(
"SELECT * FROM `paymentsLogSyria`
WHERE user_id = :user_id
AND status = 1
AND updated_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
ORDER BY updated_at DESC
LIMIT 1"
);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_STR);
$stmt->execute();
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
printFailure("لم يتم العثور على دفعة ناجحة حديثة.");
exit;
}
// خطوة 2: الحصول على المبلغ (لا يحتاج للقسمة على 100)
$amount = $payment['amount'];
// خطوة 3: حساب المكافأة
$finalAmount = calculateBonus($amount); // استخدم دالة حساب المكافآت الخاصة بك
$passengerId = $userId; // نفترض أن معرّف المستخدم هو نفسه معرّف الراكب
// --- هنا تضع نفس منطق إضافة الرصيد الذي كان في ملف payment_verify.php القديم ---
// (مثال)
// $token = generatePaymentToken($passengerId, $finalAmount);
// addToPassengerWallet($passengerId, $finalAmount, $token);
// ... إلخ
// --- النجاح النهائي ---
printSuccess("تمت معالجة الدفع وتحديث الرصيد بنجاح.");
} catch (PDOException $e) {
error_log("Finalize Payment Error: " . $e->getMessage());
printFailure("حدث خطأ في قاعدة البيانات أثناء إتمام العملية.");
}
// --- يمكنك وضع دوال المساعدة هنا (calculateBonus, etc.) ---
function calculateBonus($amount) {
$result = $amount;
if ($amount == 200) $result = 215;
else if ($amount == 400) $result = 450;
else if ($amount == 100) $result = 100.0;
else if ($amount == 1000) $result = 1140;
return $result;
}
?>

View File

@@ -1,88 +0,0 @@
<?php
include "../../../connect.php"; // تأكد من أن هذا الملف يحتوي على الاتصال بقاعدة البيانات ودوال المساعدة
/*
|--------------------------------------------------------------------------
| ملف بدء الدفع مع eCash
|--------------------------------------------------------------------------
|
| هذا الملف مسؤول عن:
| 1. استقبال طلب الدفع من تطبيق فلاتر (المبلغ ومعرّف المستخدم/السائق).
| 2. إنشاء رابط دفع فريد وخاص ببوابة eCash.
| 3. حساب رمز التحقق (Verification Code) المطلوب من eCash.
| 4. تسجيل محاولة الدفع في قاعدة البيانات بحالة "قيد الانتظار".
| 5. إعادة رابط الدفع إلى التطبيق ليتم عرضه في WebView.
|
*/
// --- الإعدادات الرئيسية - يجب تخزينها كمتغيرات بيئة (Environment Variables) ---
$ecash_merchant_id = getenv('ECASH_MERCHANT_ID'); // معرّف التاجر الخاص بك من eCash
$ecash_merchant_secret = getenv('ECASH_MERCHANT_SECRET'); // المفتاح السري الخاص بك من eCash
$ecash_terminal_key = getenv('ECASH_TERMINAL_KEY'); // مفتاح المحطة الطرفية (Terminal Key) من eCash
$ecash_checkout_url = 'https://checkout.ecash-pay.com/'; //
$ecash_checkout_url_stage = 'https://checkout.ecash-pay.co/';//رابط بوابة الدفع
$base_app_url = getenv('APP_BASE_URL'); // الرابط الأساسي لواجهة API الخاصة بك
// --- استقبال البيانات من تطبيق فلاتر ---
$amount = filterRequest("amount");
$driverId = filterRequest("driverId"); // معرّف السائق أو المستخدم
// --- التحقق من صحة البيانات المدخلة ---
if (empty($amount) || empty($driverId) || !is_numeric($amount) || $amount <= 0) {
printFailure("المبلغ أو معرّف المستخدم غير صالح.");
exit;
}
// --- إعداد متغيرات الدفع ---
$currency = "SYP"; // العملة حسب متطلبات eCash
$lang = "AR"; // لغة واجهة الدفع (AR أو EN)
//$orderRef = uniqid($driverId . "_"); // إنشاء رقم مرجعي فريد للطلب لربطه بالمستخدم
$orderRef = "tripz_" . $driverId . "_" . time();
// --- إنشاء رمز التحقق (Verification Code) ---
// هو عبارة عن MD5 لمجموعة من الحقول ويجب أن يكون بأحرف كبيرة
$verification_string = $ecash_merchant_id . $ecash_merchant_secret . $amount . $orderRef;
$verificationCode = strtoupper(md5($verification_string));
// --- تحديد روابط إعادة التوجيه والاستدعاء (Redirect & Callback) ---
// الرابط الذي يتم توجيه المستخدم إليه بعد إتمام الدفع
$redirectUrl = urlencode($base_app_url . "/driver/ecash_verify.php?orderRef=" . $orderRef);
// الرابط الذي تستدعيه eCash لإبلاغ سيرفرك بنتيجة العملية (Webhook)
$callbackUrl = urlencode($base_app_url . "/driver/ecash_webhook.php");
// --- بناء رابط الدفع النهائي الخاص بـ eCash ---
$paymentUrl = "{$ecash_checkout_url}Checkout/CardCheckout" .
"?tk=" . urlencode($ecash_terminal_key) .
"&mid=" . urlencode($ecash_merchant_id) .
"&vc=" . urlencode($verificationCode) .
"&c=" . urlencode($currency) .
"&a=" . urlencode($amount) .
"&lang=" . urlencode($lang) .
"&or=" . urlencode($orderRef) .
"&ru=" . $redirectUrl .
"&cu=" . $callbackUrl;
// --- تسجيل العملية المبدئية في قاعدة البيانات ---
// هذا يساعد على تتبع الطلب وربطه بالـ callback القادم من eCash
// نفترض أن حقل status يقبل القيم: 0=فشل، 1=نجاح، 2=قيد الانتظار
try {
$stmt = $con->prepare(
"INSERT INTO `paymentsLogSyriaDriver`( `user_id`, `amount`, `status`, `order_ref`, `payment_method`, `created_at`)
VALUES (:user_id, :amount, 2, :order_ref,'ecash-driver', NOW())"
);
$stmt->execute([
':user_id' => $driverId,
':amount' => $amount,
':order_ref' => $orderRef
]);
} catch (PDOException $e) {
error_log("eCash - فشل تسجيل الدفعة المبدئية: " . $e->getMessage());
printFailure("حدث خطأ أثناء بدء عملية الدفع. يرجى المحاولة مرة أخرى.");
exit;
}
// --- إعادة رابط الدفع إلى تطبيق فلاتر ---
// التطبيق سيستقبل هذا الرابط ويفتحه في WebView
// نرسل الرابط داخل حقل 'message' كما يتوقع كود فلاتر
printSuccess($paymentUrl);
?>

View File

@@ -1,42 +0,0 @@
<?php
// Load environment variables from .env file
// **FIX:** Corrected the path to go up three levels to find the 'vendor' directory
require_once realpath(__DIR__ . '/../../../vendor/autoload.php');
// **FIX:** Corrected the path to go up two levels to find 'load_env.php'
require_once realpath(__DIR__ . '/../../load_env.php');
$env_file = '/home/tripz-egypt-wl/env/.env';
loadEnvironment($env_file);
// --- CORS Headers ---
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit;
}
$dbname = getenv('dbname');
// --- Database Connection ONLY ---
try {
$dsn = "mysql:host=localhost;dbname=$dbname;charset=utf8mb4";
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
];
$user = getenv('USER');
$pass = getenv('PASS');
$con = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log("Webhook DB Connection Error: " . $e->getMessage());
http_response_code(500);
echo json_encode(['error' => 'Internal Server Error']);
exit;
}
?>

View File

@@ -1,44 +0,0 @@
<?php
// --- ecash_config.php ---
// Central configuration file for ecash, loading from a .env file.
// This assumes you have a function or a library (like Dotenv) to load the .env file.
// --- IMPORTANT ---
// Define the path to your .env file. Adjust if necessary.
//$env_file_path = '/home/tripz-egypt-wl/env/.env'; // Or use realpath(__DIR__ . '/../.env');
//loadEnvironment($env_file_path);
require "../../connect.php";
// --- Load ecash Credentials from Environment Variables ---
define('ECASH_MERCHANT_ID', getenv('ECASH_MERCHANT_ID'));
define('ECASH_MERCHANT_SECRET', getenv('ECASH_MERCHANT_SECRET'));
define('ECASH_TERMINAL_KEY', getenv('ECASH_TERMINAL_KEY'));
// --- Set Mode (Staging/Live) from Environment Variable ---
// Add ECASH_STAGING_MODE=true to your .env for testing
$is_staging = getenv('ECASH_STAGING_MODE') === 'false';
define('ECASH_STAGING_MODE', $is_staging);
// --- URLs (Automatically switch based on mode) ---
$checkout_base_url = ECASH_STAGING_MODE ? 'https://checkout.ecash-pay.co' : 'https://checkout.ecash-pay.com';
define('ECASH_CHECKOUT_URL', $checkout_base_url);
// --- Your Application URLs (Load from .env or define here) ---
// It's best practice to also put these in your .env file.
define('APP_BASE_URL', getenv('APP_BASE_URL')); // e.g., https://yourdomain.com/api
define('APP_REDIRECT_URL_SUCCESS', APP_BASE_URL . '/success.php');
define('APP_CALLBACK_URL', APP_BASE_URL . '/webhook_ecash.php'); // Use a specific webhook for ecash
// --- Other Settings ---
define('ECASH_CURRENCY', 'SYP');
define('ECASH_LANG', 'EN'); // 'EN' for English, 'AR' for Arabic
// --- Basic Validation ---
if (!ECASH_MERCHANT_ID || !ECASH_MERCHANT_SECRET || !ECASH_TERMINAL_KEY) {
http_response_code(500);
error_log("ecash config: Missing one or more required ecash environment variables.");
echo json_encode(['status' => 'error', 'message' => 'Payment gateway not configured correctly.']);
exit;
}
?>

View File

@@ -1,264 +0,0 @@
--- NEW WEBHOOK ---
2025-07-21 17:33:55 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108408","TransactionNo":"2515118257","Amount":"10000.00","Token":"386BBEDFFA3FBCEFCCF7F546FB4BC622"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2251511825710000.00tripz_109270481246447459618_1753108408
- Merchant ID Used: UOMACV
- TransactionNo Used: 2515118257
- Amount Used: 10000.00
- OrderRef Used: tripz_109270481246447459618_1753108408
CALCULATED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
RECEIVED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:34:00 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108408","TransactionNo":"2515118257","Amount":"10000.00","Token":"386BBEDFFA3FBCEFCCF7F546FB4BC622"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2251511825710000.00tripz_109270481246447459618_1753108408
- Merchant ID Used: UOMACV
- TransactionNo Used: 2515118257
- Amount Used: 10000.00
- OrderRef Used: tripz_109270481246447459618_1753108408
CALCULATED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
RECEIVED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:34:05 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108408","TransactionNo":"2515118257","Amount":"10000.00","Token":"386BBEDFFA3FBCEFCCF7F546FB4BC622"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2251511825710000.00tripz_109270481246447459618_1753108408
- Merchant ID Used: UOMACV
- TransactionNo Used: 2515118257
- Amount Used: 10000.00
- OrderRef Used: tripz_109270481246447459618_1753108408
CALCULATED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
RECEIVED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:34:11 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108408","TransactionNo":"2515118257","Amount":"10000.00","Token":"386BBEDFFA3FBCEFCCF7F546FB4BC622"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2251511825710000.00tripz_109270481246447459618_1753108408
- Merchant ID Used: UOMACV
- TransactionNo Used: 2515118257
- Amount Used: 10000.00
- OrderRef Used: tripz_109270481246447459618_1753108408
CALCULATED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
RECEIVED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:34:16 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108408","TransactionNo":"2515118257","Amount":"10000.00","Token":"386BBEDFFA3FBCEFCCF7F546FB4BC622"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2251511825710000.00tripz_109270481246447459618_1753108408
- Merchant ID Used: UOMACV
- TransactionNo Used: 2515118257
- Amount Used: 10000.00
- OrderRef Used: tripz_109270481246447459618_1753108408
CALCULATED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
RECEIVED TOKEN: 386BBEDFFA3FBCEFCCF7F546FB4BC622
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:38:33 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108680","TransactionNo":"3434918048","Amount":"2000.00","Token":"5E397F3BCFC8DBC277E67BBE909A4C25"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE234349180482000.00tripz_109270481246447459618_1753108680
- Merchant ID Used: UOMACV
- TransactionNo Used: 3434918048
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753108680
CALCULATED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
RECEIVED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:38:38 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108680","TransactionNo":"3434918048","Amount":"2000.00","Token":"5E397F3BCFC8DBC277E67BBE909A4C25"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE234349180482000.00tripz_109270481246447459618_1753108680
- Merchant ID Used: UOMACV
- TransactionNo Used: 3434918048
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753108680
CALCULATED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
RECEIVED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:38:44 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108680","TransactionNo":"3434918048","Amount":"2000.00","Token":"5E397F3BCFC8DBC277E67BBE909A4C25"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE234349180482000.00tripz_109270481246447459618_1753108680
- Merchant ID Used: UOMACV
- TransactionNo Used: 3434918048
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753108680
CALCULATED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
RECEIVED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:38:49 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108680","TransactionNo":"3434918048","Amount":"2000.00","Token":"5E397F3BCFC8DBC277E67BBE909A4C25"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE234349180482000.00tripz_109270481246447459618_1753108680
- Merchant ID Used: UOMACV
- TransactionNo Used: 3434918048
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753108680
CALCULATED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
RECEIVED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:38:54 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753108680","TransactionNo":"3434918048","Amount":"2000.00","Token":"5E397F3BCFC8DBC277E67BBE909A4C25"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE234349180482000.00tripz_109270481246447459618_1753108680
- Merchant ID Used: UOMACV
- TransactionNo Used: 3434918048
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753108680
CALCULATED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
RECEIVED TOKEN: 5E397F3BCFC8DBC277E67BBE909A4C25
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payment_id' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:43:55 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109008","TransactionNo":"2925347460","Amount":"2000.00","Token":"16EC668D7C9A4105D464BC925D0F35B3"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE229253474602000.00tripz_109270481246447459618_1753109008
- Merchant ID Used: UOMACV
- TransactionNo Used: 2925347460
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109008
CALCULATED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
RECEIVED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:44:00 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109008","TransactionNo":"2925347460","Amount":"2000.00","Token":"16EC668D7C9A4105D464BC925D0F35B3"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE229253474602000.00tripz_109270481246447459618_1753109008
- Merchant ID Used: UOMACV
- TransactionNo Used: 2925347460
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109008
CALCULATED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
RECEIVED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:44:06 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109008","TransactionNo":"2925347460","Amount":"2000.00","Token":"16EC668D7C9A4105D464BC925D0F35B3"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE229253474602000.00tripz_109270481246447459618_1753109008
- Merchant ID Used: UOMACV
- TransactionNo Used: 2925347460
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109008
CALCULATED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
RECEIVED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:44:11 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109008","TransactionNo":"2925347460","Amount":"2000.00","Token":"16EC668D7C9A4105D464BC925D0F35B3"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE229253474602000.00tripz_109270481246447459618_1753109008
- Merchant ID Used: UOMACV
- TransactionNo Used: 2925347460
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109008
CALCULATED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
RECEIVED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:44:16 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109008","TransactionNo":"2925347460","Amount":"2000.00","Token":"16EC668D7C9A4105D464BC925D0F35B3"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE229253474602000.00tripz_109270481246447459618_1753109008
- Merchant ID Used: UOMACV
- TransactionNo Used: 2925347460
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109008
CALCULATED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
RECEIVED TOKEN: 16EC668D7C9A4105D464BC925D0F35B3
TOKEN MATCH! Proceeding to update database.
FATAL: Database update failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list'
--- NEW WEBHOOK ---
2025-07-21 17:51:29 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753109456","TransactionNo":"2487921821","Amount":"2000.00","Token":"1EA870532F15308A41780C06AC852C33"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE224879218212000.00tripz_109270481246447459618_1753109456
- Merchant ID Used: UOMACV
- TransactionNo Used: 2487921821
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753109456
CALCULATED TOKEN: 1EA870532F15308A41780C06AC852C33
RECEIVED TOKEN: 1EA870532F15308A41780C06AC852C33
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-21 18:54:15 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753113200","TransactionNo":"1725092256","Amount":"2000.00","Token":"983B8B9FDA5947CEE1D16D6ECC29FAF9"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE217250922562000.00tripz_109270481246447459618_1753113200
- Merchant ID Used: UOMACV
- TransactionNo Used: 1725092256
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753113200
CALCULATED TOKEN: 983B8B9FDA5947CEE1D16D6ECC29FAF9
RECEIVED TOKEN: 983B8B9FDA5947CEE1D16D6ECC29FAF9
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-21 19:06:34 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753113966","TransactionNo":"1477094275","Amount":"2000.00","Token":"01AF3E8E7C921FF72ADB09300971F2D2"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE214770942752000.00tripz_109270481246447459618_1753113966
- Merchant ID Used: UOMACV
- TransactionNo Used: 1477094275
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753113966
CALCULATED TOKEN: 01AF3E8E7C921FF72ADB09300971F2D2
RECEIVED TOKEN: 01AF3E8E7C921FF72ADB09300971F2D2
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-21 19:15:57 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753114529","TransactionNo":"746605967","Amount":"2000.00","Token":"7102931A8851540F14F4E259751EA776"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE27466059672000.00tripz_109270481246447459618_1753114529
- Merchant ID Used: UOMACV
- TransactionNo Used: 746605967
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753114529
CALCULATED TOKEN: 7102931A8851540F14F4E259751EA776
RECEIVED TOKEN: 7102931A8851540F14F4E259751EA776
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-21 19:20:54 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753114829","TransactionNo":"10119078","Amount":"2000.00","Token":"11DEB7F0AA5121F048E94CF385D5FC3D"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2101190782000.00tripz_109270481246447459618_1753114829
- Merchant ID Used: UOMACV
- TransactionNo Used: 10119078
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753114829
CALCULATED TOKEN: 11DEB7F0AA5121F048E94CF385D5FC3D
RECEIVED TOKEN: 11DEB7F0AA5121F048E94CF385D5FC3D
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-21 19:23:26 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_109270481246447459618_1753114985","TransactionNo":"532601241","Amount":"2000.00","Token":"18DCD7E952332EB655B036B0C76EEDC7"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE25326012412000.00tripz_109270481246447459618_1753114985
- Merchant ID Used: UOMACV
- TransactionNo Used: 532601241
- Amount Used: 2000.00
- OrderRef Used: tripz_109270481246447459618_1753114985
CALCULATED TOKEN: 18DCD7E952332EB655B036B0C76EEDC7
RECEIVED TOKEN: 18DCD7E952332EB655B036B0C76EEDC7
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-22 00:11:03 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_14a51b422c9972299e109c7db5f65a2c_1753132198","TransactionNo":"947634072","Amount":"200000.00","Token":"E6811EE374F921257C45DC84CCCF48DC"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE2947634072200000.00tripz_14a51b422c9972299e109c7db5f65a2c_1753132198
- Merchant ID Used: UOMACV
- TransactionNo Used: 947634072
- Amount Used: 200000.00
- OrderRef Used: tripz_14a51b422c9972299e109c7db5f65a2c_1753132198
CALCULATED TOKEN: E6811EE374F921257C45DC84CCCF48DC
RECEIVED TOKEN: E6811EE374F921257C45DC84CCCF48DC
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-22 00:17:06 - RAW BODY: {"IsSuccess":false,"Message":"OTP is not valid!","OrderRef":"tripz_14a51b422c9972299e109c7db5f65a2c_1753132598","TransactionNo":"1773754242","Amount":"200000.00","Token":"2654D3390FF25082FF5A8A1BA59D6CDA"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE21773754242200000.00tripz_14a51b422c9972299e109c7db5f65a2c_1753132598
- Merchant ID Used: UOMACV
- TransactionNo Used: 1773754242
- Amount Used: 200000.00
- OrderRef Used: tripz_14a51b422c9972299e109c7db5f65a2c_1753132598
CALCULATED TOKEN: 2654D3390FF25082FF5A8A1BA59D6CDA
RECEIVED TOKEN: 2654D3390FF25082FF5A8A1BA59D6CDA
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.
--- NEW WEBHOOK ---
2025-07-22 00:19:54 - RAW BODY: {"IsSuccess":true,"Message":null,"OrderRef":"tripz_14a51b422c9972299e109c7db5f65a2c_1753132768","TransactionNo":"1048082327","Amount":"100000.00","Token":"DCF7C2AEE0A81DB6C5F40C086E396928"}
VERIFICATION STRING: UOMACVPA8BQ8U99BRDDONSLAKW2IDSLBTCQFR776E8L55C0DLBYFB6NJJOWJ7FOLWEYQE21048082327100000.00tripz_14a51b422c9972299e109c7db5f65a2c_1753132768
- Merchant ID Used: UOMACV
- TransactionNo Used: 1048082327
- Amount Used: 100000.00
- OrderRef Used: tripz_14a51b422c9972299e109c7db5f65a2c_1753132768
CALCULATED TOKEN: DCF7C2AEE0A81DB6C5F40C086E396928
RECEIVED TOKEN: DCF7C2AEE0A81DB6C5F40C086E396928
TOKEN MATCH! Proceeding to update database.
SUCCESS: Database updated.

View File

@@ -1,9 +0,0 @@
[2025-07-21 17:38:50] STEP VERIFY: لم يتم تأكيد الدفع بعد عدة محاولات | Data: {"orderRef":"tripz_109270481246447459618_1753108680"}
[2025-07-21 17:38:56] STEP VERIFY: لم يتم تأكيد الدفع بعد عدة محاولات | Data: {"orderRef":"tripz_109270481246447459618_1753108680"}
[2025-07-21 17:44:13] STEP VERIFY: لم يتم تأكيد الدفع بعد عدة محاولات | Data: {"orderRef":"tripz_109270481246447459618_1753109008"}
[2025-07-21 17:51:41] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_109270481246447459618_1753109456","userId":"109270481246447459618"}
[2025-07-21 19:06:39] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_109270481246447459618_1753113966","userId":"109270481246447459618"}
[2025-07-21 19:20:58] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_109270481246447459618_1753114829","userId":"109270481246447459618"}
[2025-07-21 19:23:30] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_109270481246447459618_1753114985","userId":"109270481246447459618"}
[2025-07-22 00:11:08] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_14a51b422c9972299e109c7db5f65a2c_1753132198","userId":"14a51b422c9972299e109c7db5f65a2c"}
[2025-07-22 00:20:01] STEP VERIFY: اكتملت العملية بنجاح | Data: {"orderRef":"tripz_14a51b422c9972299e109c7db5f65a2c_1753132768","userId":"14a51b422c9972299e109c7db5f65a2c"}

View File

@@ -1,181 +0,0 @@
<?php
// هذا الملف هو نقطة النهاية بعد الدفع، ويقوم بكل عمليات التحقق وإضافة الرصيد
include "../../../jwtconnect.php";
define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride");
define("LOG_FILE", "../logs/payment_verification.log");
function logError($step, $message, $data = null) {
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$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, $logEntry . PHP_EOL, FILE_APPEND);
}
function showHTMLPage($type, $title, $message) {
$color = $type === 'success' ? '#28a745' : '#dc3545';
$icon = $type === 'success' ? '✔' : '✖';
?>
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<title><?= htmlspecialchars($title) ?></title>
<style>
body {
background-color: #f4f6f9;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
text-align: center;
padding-top: 100px;
color: #333;
}
.container {
background: #fff;
padding: 40px 30px;
margin: auto;
max-width: 450px;
border-radius: 15px;
box-shadow: 0 8px 20px rgba(0,0,0,0.1);
animation: fadeIn 1s ease-out;
}
.icon {
font-size: 64px;
color: <?= $color ?>;
margin-bottom: 15px;
}
h1 {
font-size: 28px;
color: <?= $color ?>;
}
p {
font-size: 18px;
margin-top: 10px;
color: #555;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div class="container">
<div class="icon"><?= $icon ?></div>
<h1><?= htmlspecialchars($title) ?></h1>
<p><?= htmlspecialchars($message) ?></p>
</div>
</body>
</html>
<?php
exit;
}
$orderRef = $_GET['orderRef'] ?? null;
if (empty($orderRef)) {
showHTMLPage("error", "خطأ في الرابط", "الرقم المرجعي للطلب غير موجود.");
}
$payment = null;
$max_attempts = 5;
for ($attempts = 0; $attempts < $max_attempts; $attempts++) {
$stmt = $con->prepare("SELECT * FROM `paymentsLogSyria` WHERE order_ref = :order_ref AND status = 1 LIMIT 1");
$stmt->execute([':order_ref' => $orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if ($payment) break;
sleep(2);
}
if (!$payment) {
logError("VERIFY", "لم يتم تأكيد الدفع بعد عدة محاولات", ["orderRef" => $orderRef]);
showHTMLPage("error", "لم يتم تأكيد الدفع", "لم نتمكن من تأكيد دفعتك بعد. قد تستغرق العملية بضع لحظات. يرجى التحقق من رصيدك في التطبيق لاحقاً أو التواصل مع الدعم الفني.");
}
try {
$userId = $payment['user_id'];
$amount = $payment['amount'];
$paymentMethod = $payment['payment_method'] ?? 'ecash';
$finalAmount = calculateBonus($amount);
$token = generatePaymentToken($userId, $finalAmount);
if (!$token) throw new Exception("فشل إنشاء توكن محفظة الراكب");
$walletResult = addToPassengerWallet($userId, $finalAmount, $token);
if (!$walletResult || ($walletResult['status'] ?? 'fail') != "success") {
throw new Exception("فشل إضافة الرصيد لمحفظة الراكب");
}
$seferToken = generatePaymentToken($userId, $amount);
if (!$seferToken) throw new Exception("فشل إنشاء توكن محفظة سفر");
$seferWalletResult = addToSeferWallet($userId, $amount, $paymentMethod, $seferToken);
if (!$seferWalletResult || ($seferWalletResult['status'] ?? 'fail') != "success") {
throw new Exception("فشل إضافة الرصيد لمحفظة سفر");
}
logError("VERIFY", "اكتملت العملية بنجاح", ["orderRef" => $orderRef, "userId" => $userId]);
showHTMLPage("success", "تم الدفع بنجاح", "تمت إضافة الرصيد إلى محفظتك. شكرًا لاستخدامك Intaleq.");
} catch (Exception $e) {
logError("VERIFY_ERROR", $e->getMessage(), ["orderRef" => $orderRef]);
showHTMLPage("error", "حدث خطأ", "لقد تم استلام دفعتك بنجاح، ولكن حدث خطأ أثناء تحديث رصيدك. يرجى التواصل مع الدعم الفني وتزويدهم بالرقم المرجعي: " . htmlspecialchars($orderRef));
}
// --- دوال مساعدة ---
function calculateBonus($amount) {
if ($amount == 200000) return 205000;
if ($amount == 400000) return 425000;
if ($amount == 1000000) return 1040000;
return $amount;
}
function generatePaymentToken($passengerId, $amount) {
$url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = ['passengerId' => $passengerId, 'amount' => $amount];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
$data = json_decode($response, true);
return $data['message'] ?? null;
}
function addToPassengerWallet($passengerId, $amount, $token) {
$url = BASE_URL . "/passengerWallet/add.php";
$postData = ['passenger_id' => $passengerId, 'balance' => $amount, 'token' => $token];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
return json_decode($response, true);
}
function addToSeferWallet($passengerId, $amount, $paymentMethod, $token) {
$url = BASE_URL . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $token,
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
return json_decode($response, true);
}
?>

View File

@@ -1,91 +0,0 @@
<?php
// استخدام ملف اتصال خاص بالـ Webhook لا يحتوي على أي تحقق من الهوية
include "../../../jwtconnect.php";
/*
|--------------------------------------------------------------------------
| ملف Webhook النهائي الخاص بـ eCash (مع تسجيل إضافي للتصحيح)
|--------------------------------------------------------------------------
*/
// --- الإعدادات ---
$ecash_merchant_id = getenv('ECASH_MERCHANT_ID');
$ecash_merchant_secret = getenv('ECASH_MERCHANT_SECRET');
// --- إعداد ملف اللوج (Log File) ---
$log_dir = __DIR__ . '/../logs';
$log_file = $log_dir . '/ecash_production.log';
if (!is_dir($log_dir)) {
mkdir($log_dir, 0755, true);
}
// --- قراءة البيانات القادمة من eCash ---
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// --- تسجيل الـ Callback كاملاً لأغراض المراقبة ---
file_put_contents($log_file, "--- NEW WEBHOOK ---\n" . date('Y-m-d H:i:s') . " - RAW BODY: " . $raw_body . PHP_EOL, FILE_APPEND);
if (!$data || !isset($data['Token'])) {
http_response_code(400);
exit;
}
// --- استخراج البيانات ---
$isSuccess = $data['IsSuccess'] ?? false;
$transactionNo = $data['TransactionNo'] ?? '';
$amount = $data['Amount'] ?? '';
$orderRef = $data['OrderRef'] ?? '';
$receivedToken = $data['Token'];
// --- **تصحيح الأخطاء: بناء وتسجيل سلسلة التحقق** ---
$verification_string = $ecash_merchant_id . $ecash_merchant_secret . $transactionNo . $amount . $orderRef;
$expectedToken = strtoupper(md5($verification_string));
// تسجيل السلسلة المستخدمة في التوقيع والقيم الفردية
$debug_log = "VERIFICATION STRING: " . $verification_string . PHP_EOL;
$debug_log .= " - Merchant ID Used: " . $ecash_merchant_id . PHP_EOL;
$debug_log .= " - TransactionNo Used: " . $transactionNo . PHP_EOL;
$debug_log .= " - Amount Used: " . $amount . PHP_EOL;
$debug_log .= " - OrderRef Used: " . $orderRef . PHP_EOL;
$debug_log .= "CALCULATED TOKEN: " . $expectedToken . PHP_EOL;
$debug_log .= "RECEIVED TOKEN: " . $receivedToken . PHP_EOL;
file_put_contents($log_file, $debug_log, FILE_APPEND);
// --- التحقق من صحة الـ Token ---
if (!hash_equals($expectedToken, $receivedToken)) {
http_response_code(401);
file_put_contents($log_file, "TOKEN MISMATCH! Process stopped." . PHP_EOL, FILE_APPEND);
exit;
}
// --- تحديث حالة الدفعة في قاعدة البيانات ---
file_put_contents($log_file, "TOKEN MATCH! Proceeding to update database." . PHP_EOL, FILE_APPEND);
$payment_status = $isSuccess ? 1 : 0;
try {
$stmt = $con->prepare(
"UPDATE `paymentsLogSyria` SET status = :status, updated_at = NOW() WHERE order_ref = :order_ref AND status = 2"
);
$stmt->execute([
':status' => $payment_status,
':order_ref' => $orderRef
]);
if ($stmt->rowCount() > 0) {
http_response_code(200);
file_put_contents($log_file, "SUCCESS: Database updated." . PHP_EOL, FILE_APPEND);
} else {
http_response_code(200);
file_put_contents($log_file, "INFO: Order not found or already processed." . PHP_EOL, FILE_APPEND);
}
} catch (PDOException $e) {
http_response_code(500);
file_put_contents($log_file, "FATAL: Database update failed: " . $e->getMessage() . PHP_EOL, FILE_APPEND);
}
?>

View File

@@ -1,79 +0,0 @@
<?php
// هذا الملف يجب أن يستخدم ملف الاتصال الذي يتحقق من الهوية
include "../../../connect.php";
// يجب استدعاء دالة التحقق هنا لضمان أن الطلب قادم من تطبيقك فقط
/*
|--------------------------------------------------------------------------
| ملف إتمام الدفع النهائي
|--------------------------------------------------------------------------
|
| هذا الملف مسؤول عن:
| 1. استقبال طلب من تطبيق فلاتر بعد عودة المستخدم.
| 2. التحقق من وجود دفعة ناجحة حديثة للمستخدم في قاعدة البيانات.
| 3. حساب المكافآت.
| 4. استدعاء واجهات API داخلية لإضافة الرصيد إلى المحافظ.
|
*/
// --- استقبال البيانات من تطبيق فلاتر ---
$userId = filterRequest("userId"); // أو driverId
$paymentMethod = filterRequest("paymentMethod") ?? 'ecash';
if (empty($userId)) {
printFailure("معرّف المستخدم غير صالح.");
exit;
}
try {
// خطوة 1: البحث عن آخر دفعة ناجحة للمستخدم (تم تحديثها بواسطة الـ Webhook)
$stmt = $con->prepare(
"SELECT * FROM `paymentsLogSyria`
WHERE user_id = :user_id
AND status = 1
AND updated_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
ORDER BY updated_at DESC
LIMIT 1"
);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_STR);
$stmt->execute();
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
printFailure("لم يتم العثور على دفعة ناجحة حديثة.");
exit;
}
// خطوة 2: الحصول على المبلغ (لا يحتاج للقسمة على 100)
$amount = $payment['amount'];
// خطوة 3: حساب المكافأة
$finalAmount = calculateBonus($amount); // استخدم دالة حساب المكافآت الخاصة بك
$passengerId = $userId; // نفترض أن معرّف المستخدم هو نفسه معرّف الراكب
// --- هنا تضع نفس منطق إضافة الرصيد الذي كان في ملف payment_verify.php القديم ---
// (مثال)
// $token = generatePaymentToken($passengerId, $finalAmount);
// addToPassengerWallet($passengerId, $finalAmount, $token);
// ... إلخ
// --- النجاح النهائي ---
printSuccess("تمت معالجة الدفع وتحديث الرصيد بنجاح.");
} catch (PDOException $e) {
error_log("Finalize Payment Error: " . $e->getMessage());
printFailure("حدث خطأ في قاعدة البيانات أثناء إتمام العملية.");
}
// --- يمكنك وضع دوال المساعدة هنا (calculateBonus, etc.) ---
function calculateBonus($amount) {
$result = $amount;
if ($amount == 500) return 530;
if ($amount == 1000) return 1070;
if ($amount == 2000) return 2180;
if ($amount == 5000) return 5700;
return $result;
}
?>

View File

@@ -1,88 +0,0 @@
<?php
include "../../../connect.php"; // تأكد من أن هذا الملف يحتوي على الاتصال بقاعدة البيانات ودوال المساعدة
/*
|--------------------------------------------------------------------------
| ملف بدء الدفع مع eCash
|--------------------------------------------------------------------------
|
| هذا الملف مسؤول عن:
| 1. استقبال طلب الدفع من تطبيق فلاتر (المبلغ ومعرّف المستخدم/السائق).
| 2. إنشاء رابط دفع فريد وخاص ببوابة eCash.
| 3. حساب رمز التحقق (Verification Code) المطلوب من eCash.
| 4. تسجيل محاولة الدفع في قاعدة البيانات بحالة "قيد الانتظار".
| 5. إعادة رابط الدفع إلى التطبيق ليتم عرضه في WebView.
|
*/
// --- الإعدادات الرئيسية - يجب تخزينها كمتغيرات بيئة (Environment Variables) ---
$ecash_merchant_id = getenv('ECASH_MERCHANT_ID'); // معرّف التاجر الخاص بك من eCash
$ecash_merchant_secret = getenv('ECASH_MERCHANT_SECRET'); // المفتاح السري الخاص بك من eCash
$ecash_terminal_key = getenv('ECASH_TERMINAL_KEY'); // مفتاح المحطة الطرفية (Terminal Key) من eCash
$ecash_checkout_url = 'https://checkout.ecash-pay.com/'; //
$ecash_checkout_url_stage = 'https://checkout.ecash-pay.co/';//رابط بوابة الدفع
$base_app_url = getenv('APP_BASE_URL'); // الرابط الأساسي لواجهة API الخاصة بك
// --- استقبال البيانات من تطبيق فلاتر ---
$amount = filterRequest("amount");
$passengerId = filterRequest("passengerId"); // معرّف السائق أو المستخدم
// --- التحقق من صحة البيانات المدخلة ---
if (empty($amount) || empty($passengerId) || !is_numeric($amount) || $amount <= 0) {
printFailure("المبلغ أو معرّف المستخدم غير صالح.");
exit;
}
// --- إعداد متغيرات الدفع ---
$currency = "SYP"; // العملة حسب متطلبات eCash
$lang = "AR"; // لغة واجهة الدفع (AR أو EN)
//$orderRef = uniqid($passengerId . "_"); // إنشاء رقم مرجعي فريد للطلب لربطه بالمستخدم
$orderRef = "tripz_" . $passengerId . "_" . time();
// --- إنشاء رمز التحقق (Verification Code) ---
// هو عبارة عن MD5 لمجموعة من الحقول ويجب أن يكون بأحرف كبيرة
$verification_string = $ecash_merchant_id . $ecash_merchant_secret . $amount . $orderRef;
$verificationCode = strtoupper(md5($verification_string));
// --- تحديد روابط إعادة التوجيه والاستدعاء (Redirect & Callback) ---
// الرابط الذي يتم توجيه المستخدم إليه بعد إتمام الدفع
$redirectUrl = urlencode($base_app_url . "/passenger/ecash_verify.php?orderRef=" . $orderRef);
// الرابط الذي تستدعيه eCash لإبلاغ سيرفرك بنتيجة العملية (Webhook)
$callbackUrl = urlencode($base_app_url . "/passenger/ecash_webhook.php");
// --- بناء رابط الدفع النهائي الخاص بـ eCash ---
$paymentUrl = "{$ecash_checkout_url}Checkout/CardCheckout" .
"?tk=" . urlencode($ecash_terminal_key) .
"&mid=" . urlencode($ecash_merchant_id) .
"&vc=" . urlencode($verificationCode) .
"&c=" . urlencode($currency) .
"&a=" . urlencode($amount) .
"&lang=" . urlencode($lang) .
"&or=" . urlencode($orderRef) .
"&ru=" . $redirectUrl .
"&cu=" . $callbackUrl;
//error_log("eCash - فشل تسجيل الدفعة المبدئية: " . $paymentUrl);
// --- تسجيل العملية المبدئية في قاعدة البيانات ---
// هذا يساعد على تتبع الطلب وربطه بالـ callback القادم من eCash
// نفترض أن حقل status يقبل القيم: 0=فشل، 1=نجاح، 2=قيد الانتظار
try {
$stmt = $con->prepare(
"INSERT INTO `paymentsLogSyria`( `user_id`, `amount`, `status`, `order_ref`, `payment_method`, `created_at`)
VALUES (:user_id, :amount, 2, :order_ref,'ecash-passenger', NOW())"
);
$stmt->execute([
':user_id' => $passengerId,
':amount' => $amount,
':order_ref' => $orderRef
]);
} catch (PDOException $e) {
error_log("eCash - فشل تسجيل الدفعة المبدئية: " . $e->getMessage());
printFailure("حدث خطأ أثناء بدء عملية الدفع. يرجى المحاولة مرة أخرى.");
exit;
}
// --- إعادة رابط الدفع إلى تطبيق فلاتر ---
// التطبيق سيستقبل هذا الرابط ويفتحه في WebView
// نرسل الرابط داخل حقل 'message' كما يتوقع كود فلاتر
printSuccess($paymentUrl);
?>

View File

@@ -1,42 +0,0 @@
<?php
// Load environment variables from .env file
// **FIX:** Corrected the path to go up three levels to find the 'vendor' directory
require_once realpath(__DIR__ . '/../../../vendor/autoload.php');
// **FIX:** Corrected the path to go up two levels to find 'load_env.php'
require_once realpath(__DIR__ . '/../../load_env.php');
$env_file = '/home/tripz-egypt-wl/env/.env';
loadEnvironment($env_file);
// --- CORS Headers ---
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit;
}
$dbname = getenv('dbname');
// --- Database Connection ONLY ---
try {
$dsn = "mysql:host=localhost;dbname=$dbname;charset=utf8mb4";
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
];
$user = getenv('USER');
$pass = getenv('PASS');
$con = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log("Webhook DB Connection Error: " . $e->getMessage());
http_response_code(500);
echo json_encode(['error' => 'Internal Server Error']);
exit;
}
?>

View File

@@ -1,73 +0,0 @@
<?php
// --- payWithEcash.php (Updated) ---
// This script now saves transaction details before generating the payment link.
require "../../connect.php"; // Your existing connection/auth script
require_once "ecash_config.php"; // The ecash config file
// --- Get Input Data ---
$amount = filterRequest("amount", "numeric");
$passengerId = filterRequest("passengerId"); // Get passengerId from the request
if (!$amount || $amount <= 0) {
printFailure("Invalid or missing amount.");
exit;
}
if (!$passengerId) {
printFailure("Passenger ID is required.");
exit;
}
// The user ID from your JWT authentication in connect.php
$userId = $decodedToken->user_id ?? null;
if (!$userId) {
printFailure("Authentication failed.");
exit;
}
// 1. --- Create a unique order reference ---
$orderRef = 'INTALEQ_' . $userId . '_' . time();
// 2. --- Save the initial transaction to your database ---
// This step is CRITICAL for the webhook to work correctly.
// Create a table named 'ecash_transactions' with columns like:
// id, order_ref, user_id, passenger_id, amount, status, created_at, updated_at
try {
$stmt = $con->prepare(
"INSERT INTO ecash_transactions (order_ref, user_id, passenger_id, amount, status) VALUES (?, ?, ?, ?, 'pending')"
);
$stmt->execute([$orderRef, $userId, $passengerId, $amount]);
} catch (PDOException $e) {
// Log the database error
error_log("ecash_initiate DB Error: " . $e->getMessage());
printFailure("Failed to initiate payment transaction.");
exit;
}
// 3. --- Generate the Verification Code (VC) ---
$stringToHash = ECASH_MERCHANT_ID . ECASH_MERCHANT_SECRET . $amount . $orderRef;
$verificationCode = strtoupper(md5($stringToHash));
// 4. --- Construct URLs ---
$redirectUrl = urlencode(APP_REDIRECT_URL_SUCCESS);
$callbackUrl = urlencode(APP_CALLBACK_URL);
// 5. --- Build the Final Checkout URL ---
$checkoutUrl = sprintf(
"%s/Checkout/CardCheckout?tk=%s&mid=%s&vc=%s&c=%s&a=%s&lang=%s&or=%s&ru=%s&cu=%s",
ECASH_CHECKOUT_URL,
ECASH_TERMINAL_KEY,
ECASH_MERCHANT_ID,
$verificationCode,
ECASH_CURRENCY,
$amount,
ECASH_LANG,
$orderRef,
$redirectUrl,
$callbackUrl
);
// 6. --- Return the URL to Flutter ---
printSuccess($checkoutUrl);
?>

View File

@@ -1,310 +0,0 @@
<?php
// --- webhook_ecash.php ---
// This script securely handles the callback from ecash and updates user wallets.
// Include necessary files
require_once "../../connect.php"; // Adjust path as needed
require_once "ecash_config.php"; // Adjust path as needed
define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride");
define("LOG_FILE", "../logs/ecash_webhook.log");
// --- Start Webhook Processing ---
// 1. Log the raw incoming data from ecash
$raw_post_data = file_get_contents('php://input');
logError("0", "Webhook received", ["payload" => $raw_post_data]);
$data = json_decode($raw_post_data, true);
if (!$data) {
logError("0.1", "Invalid JSON payload.");
http_response_code(400);
exit;
}
// 2. Extract data and verify the token from ecash
$isSuccess = $data['isSuccess'] ?? null;
$orderRef = $data['orderRef'] ?? null;
$transactionNo = $data['transactionNo'] ?? null;
$amount = $data['amount'] ?? null;
$receivedToken = $data['token'] ?? '';
$string_to_hash = ECASH_MERCHANT_ID . ECASH_MERCHANT_SECRET . $transactionNo . $amount . $orderRef;
$expected_token = md5($string_to_hash);
if (strcasecmp($expected_token, $receivedToken) !== 0) {
logError("1", "Token Mismatch", [
"expected" => $expected_token,
"received" => $receivedToken,
"string" => $string_to_hash
]);
http_response_code(401); // Unauthorized
exit;
}
logError("1", "Token Verified Successfully.");
// 3. Check if payment was successful
if ($isSuccess !== true) {
logError("2", "Payment was not successful according to ecash.", $data);
// Optionally, update your database to mark the order as 'failed'
updateTransactionStatus($orderRef, 'failed', $transactionNo);
http_response_code(200); // Respond OK to ecash, but do nothing else
exit;
}
logError("2", "Payment reported as SUCCESS by ecash.");
// 4. Find the original transaction in your database using the Order Reference
try {
$stmt = $con->prepare("SELECT * FROM ecash_transactions WHERE order_ref = ? LIMIT 1");
$stmt->execute([$orderRef]);
$transaction = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$transaction) {
logError("3", "OrderRef not found in our database.", ["orderRef" => $orderRef]);
http_response_code(404); // Not Found
exit;
}
// Security Check: Ensure this transaction hasn't already been processed
if ($transaction['status'] !== 'pending') {
logError("3.1", "Transaction already processed.", ["orderRef" => $orderRef, "status" => $transaction['status']]);
http_response_code(200); // Acknowledge receipt, but prevent double-spending
exit;
}
$passengerId = $transaction['passenger_id'];
$paidAmount = $transaction['amount']; // Use the amount from your DB as the source of truth
logError("3", "Transaction found in DB.", ["passengerId" => $passengerId, "amount" => $paidAmount]);
// 5. --- Start Wallet Update Logic (from your paymet_verfy.php) ---
// Calculate bonus
$finalAmount = calculateBonus($paidAmount);
logError("4", "Bonus calculated.", ["original" => $paidAmount, "final" => $finalAmount]);
// Add to Passenger Wallet
$passengerToken = generatePaymentToken($passengerId, $finalAmount);
if ($passengerToken) {
addToPassengerWallet($passengerId, $finalAmount, $passengerToken);
}
// Add to Sefer Wallet
$paymentMethod = 'ecash'; // Or another identifier
addToSeferWallet($passengerId, $paidAmount, $paymentMethod);
// 6. Mark the transaction as 'success' in your database to prevent reprocessing
updateTransactionStatus($orderRef, 'success', $transactionNo);
logError("7", "Process completed successfully.");
} catch (PDOException $e) {
logError("DB_ERROR", "Database error: " . $e->getMessage());
http_response_code(500);
exit;
} catch (Exception $e) {
logError("GENERAL_ERROR", "General error: " . $e->getMessage());
http_response_code(500);
exit;
}
// 7. Respond to ecash server
http_response_code(200);
echo "Webhook processed.";
// --- ALL HELPER FUNCTIONS FROM paymet_verfy.php ---
function updateTransactionStatus($orderRef, $status, $transactionNo) {
global $con;
try {
$stmt = $con->prepare(
"UPDATE ecash_transactions SET status = ?, ecash_transaction_no = ?, updated_at = NOW() WHERE order_ref = ?"
);
$stmt->execute([$status, $transactionNo, $orderRef]);
} catch (PDOException $e) {
logError("DB_UPDATE_ERROR", "Failed to update transaction status", ["error" => $e->getMessage()]);
}
}
function generatePaymentToken($passengerId, $amount) {
$url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = [
'passengerId' => $passengerId,
'amount' => $amount
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("4.1", "cURL error in token generation", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("4.2", "HTTP error in token generation", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data || !isset($data['message'])) {
logError("4.3", "Invalid response format in token generation", [
"response" => $response
]);
return null;
}
return $data['message']; // ✅ Return token
}
// 🎯 Function to add balance to passenger's wallet with error logging
function addToPassengerWallet($passengerId, $amount, $token) {
$url = BASE_URL . "/passengerWallet/add.php";
$postData = [
'passenger_id' => $passengerId,
'balance' => $amount,
'token' => $token
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("5.1", "cURL error in passenger wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("5.2", "HTTP error in passenger wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("5.3", "Invalid response format in passenger wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to add balance to Sefer wallet with error logging
function addToSeferWallet($passengerId, $amount, $paymentMethod) {
// Generate a new token specifically for the Sefer wallet
$seferToken = generatePaymentToken($passengerId, $amount);
if (!$seferToken) {
logError("6.0.1", "Failed to generate Sefer token");
return null;
}
logError("6.0.2", "Generated new Sefer token", [
"token_length" => ($seferToken)
]);
$url = BASE_URL . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $seferToken, // Use the new Sefer-specific token
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("6.1", "cURL error in Sefer wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("6.2", "HTTP error in Sefer wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("6.3", "Invalid response format in Sefer wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to calculate bonus
function calculateBonus($amount) {
logError("3.1", "Bonus calculation input", ["amount" => $amount]);
$result = 0;
if ($amount == 100) $result = 100;
else if ($amount == 200) $result = 215;
else if ($amount == 400) $result = 450;
else if ($amount == 1000) $result = 1140;
logError("3.2", "Bonus calculation result", [
"input" => $amount,
"output" => $result
]);
return $result;
}
?>

View File

@@ -1,45 +0,0 @@
<?php
include "../../connect.php";
$kazan = filterRequest("kazan");
$adminId = filterRequest("adminId");
$latePrice = filterRequest("latePrice");
$heavyPrice = filterRequest("heavyPrice");
$naturePrice = filterRequest("naturePrice");
$comfortPrice = filterRequest("comfortPrice");
$speedPrice = filterRequest("speedPrice");
$deliveryPrice = filterRequest("deliveryPrice");
$freePrice = filterRequest("freePrice");
$country = filterRequest("country");
$fuelPrice = filterRequest("fuelPrice");
// Prepare an SQL statement with placeholders for the values
$sql = "INSERT INTO `kazan`( `country`,`kazan`, `comfortPrice`, `speedPrice`, `deliveryPrice`, `freePrice`, `latePrice`, `heavyPrice`, `adminId`, `naturePrice`, `fuelPrice`) VALUES (:country,:kazan, :comfortPrice, :speedPrice, :deliveryPrice, :freePrice, :latePrice, :heavyPrice, :adminId, :naturePrice,:fuelPrice)";
$stmt = $con->prepare($sql);
// Bind the parameters to the SQL query
$stmt->bindParam(':kazan', $kazan);
$stmt->bindParam(':comfortPrice', $comfortPrice);
$stmt->bindParam(':speedPrice', $speedPrice);
$stmt->bindParam(':deliveryPrice', $deliveryPrice);
$stmt->bindParam(':freePrice', $freePrice);
$stmt->bindParam(':latePrice', $latePrice);
$stmt->bindParam(':heavyPrice', $heavyPrice);
$stmt->bindParam(':adminId', $adminId);
$stmt->bindParam(':naturePrice', $naturePrice);
$stmt->bindParam(':country', $country);
$stmt->bindParam(':fuelPrice', $fuelPrice);
// Execute the statement
if ($stmt->execute()) {
// Print a success message
printSuccess("Kazan saved successfully");
} else {
// Print a failure message
printFailure("Failed to save Kazan");
}
// Close the statement
$stmt->close();
?>

View File

@@ -1,27 +0,0 @@
<?php
include "../../connect.php";
$country = filterRequest("country");
$sql = " SELECT *
FROM
`kazan`
WHERE `country`='$country'";
$stmt = $con->prepare($sql);
$stmt->execute();
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($row){
// Fetch the record
// $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
printSuccess( $row);
}
else{
// Print a failure message
printFailure($message = "No Kazan record found");
}
?>

View File

@@ -1,72 +0,0 @@
<?php
include "../../connect.php";
$id = filterRequest("id");
// Create an empty array to store the column-value pairs
$columnValues = array();
// Check if each column is set in the request and add it to the array
if (isset($_POST["kazan"])) {
$kazan = filterRequest("kazan");
$columnValues[] = "`kazan` = '$kazan'";
}
if (isset($_POST["comfortPrice"])) {
$comfortPrice = filterRequest("comfortPrice");
$columnValues[] = "`comfortPrice` = '$comfortPrice'";
}
if (isset($_POST["speedPrice"])) {
$speedPrice = filterRequest("speedPrice");
$columnValues[] = "`speedPrice` = '$speedPrice'";
}
if (isset($_POST["deliveryPrice"])) {
$deliveryPrice = filterRequest("deliveryPrice");
$columnValues[] = "`deliveryPrice` = '$deliveryPrice'";
}
if (isset($_POST["freePrice"])) {
$freePrice = filterRequest("freePrice");
$columnValues[] = "`freePrice` = '$freePrice'";
}
if (isset($_POST["latePrice"])) {
$latePrice = filterRequest("latePrice");
$columnValues[] = "`latePrice` = '$latePrice'";
}
if (isset($_POST["heavyPrice"])) {
$heavyPrice = filterRequest("heavyPrice");
$columnValues[] = "`heavyPrice` = '$heavyPrice'";
}
if (isset($_POST["adminId"])) {
$adminId = filterRequest("adminId");
$columnValues[] = "`adminId` = '$adminId'";
}
if (isset($_POST["createdAt"])) {
$createdAt = filterRequest("createdAt");
$columnValues[] = "`createdAt` = '$createdAt'";
}
if (isset($_POST["naturePrice"])) {
$naturePrice = filterRequest("naturePrice");
$columnValues[] = "`naturePrice` = '$naturePrice'";
}
// Construct the SET clause of the update query using the column-value pairs
$setClause = implode(", ", $columnValues);
$sql = "UPDATE `kazan` SET $setClause WHERE `id` = '$id'";
$stmt = $con->prepare($sql);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// Print a success message
printSuccess($message = "Kazan data updated successfully");
} else {
// Print a failure message
printFailure($message = "Failed to update kazan data");
}

View File

@@ -1,385 +0,0 @@
[2025-03-20 21:01:11] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:01:11] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:01:11] STEP 1: Payment found | Data: {"payment_id":"13","status":"1","amount":"2800.00"}
[2025-03-20 21:01:11] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:01:11] STEP 3: Calculating bonus | Data: {"amount":"2800.00"}
[2025-03-20 21:01:11] STEP 3.1: Bonus calculation input | Data: {"amount":"2800.00"}
[2025-03-20 21:01:11] STEP 3.2: Bonus calculation result | Data: {"input":"2800.00","output":0}
[2025-03-20 21:01:11] STEP 3: Bonus calculation failed | Data: {"original_amount":"2800.00","calculated_amount":0}
[2025-03-20 21:07:36] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:07:36] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:07:36] STEP 1: Payment found | Data: {"payment_id":"14","status":"1","amount":28}
[2025-03-20 21:07:36] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:07:36] STEP 3: Calculating bonus | Data: {"amount":"2800.00"}
[2025-03-20 21:07:36] STEP 3.1: Bonus calculation input | Data: {"amount":"2800.00"}
[2025-03-20 21:07:36] STEP 3.2: Bonus calculation result | Data: {"input":"2800.00","output":0}
[2025-03-20 21:07:36] STEP 3: Bonus calculation failed | Data: {"original_amount":"2800.00","calculated_amount":0}
[2025-03-20 21:10:41] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:10:41] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:10:41] STEP 1: Payment found | Data: {"payment_id":"15","status":"1","amount":80}
[2025-03-20 21:10:41] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:10:41] STEP 3: Calculating bonus | Data: {"amount":80}
[2025-03-20 21:10:41] STEP 3.1: Bonus calculation input | Data: {"amount":80}
[2025-03-20 21:10:41] STEP 3.2: Bonus calculation result | Data: {"input":80,"output":0}
[2025-03-20 21:10:41] STEP 3: Bonus calculation failed | Data: {"original_amount":80,"calculated_amount":0}
[2025-03-20 21:11:51] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:11:51] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:11:51] STEP 1: Payment found | Data: {"payment_id":"16","status":"1","amount":100}
[2025-03-20 21:11:51] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:11:51] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:11:51] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:11:51] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:11:51] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:11:51] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:11:51] STEP 4.2: HTTP error in token generation | Data: {"http_code":404,"response":"<!DOCTYPE HTML PUBLIC \"-\/\/IETF\/\/DTD HTML 2.0\/\/EN\">\n<html><head>\n<title>404 Not Found<\/title>\n<\/head><body>\n<h1>Not Found<\/h1>\n<p>The requested URL was not found on this server.<\/p>\n<p>Additionally, a 404 Not Found\nerror was encountered while trying to use an ErrorDocument to handle the request.<\/p>\n<\/body><\/html>\n"}
[2025-03-20 21:11:51] STEP 4: Token generation failed
[2025-03-20 21:15:42] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:15:42] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:15:42] STEP 1: Payment found | Data: {"payment_id":"17","status":"1","amount":100}
[2025-03-20 21:15:42] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:15:42] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:15:42] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:15:42] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:15:42] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:15:42] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:15:42] STEP 4.2: HTTP error in token generation | Data: {"http_code":401,"response":"{\"error\":\"Authorization token required\"}"}
[2025-03-20 21:15:42] STEP 4: Token generation failed
[2025-03-20 21:27:10] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:27:10] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:27:10] STEP 1: Payment found | Data: {"payment_id":"18","status":"1","amount":100}
[2025-03-20 21:27:10] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:27:10] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:27:10] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:27:10] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:27:10] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:27:10] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:27:10] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 21:27:10] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:27:10] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 21:27:10] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":100,"paymentMethod":"unknown"}
[2025-03-20 21:27:10] STEP 6.1: cURL error in Sefer wallet update | Data: {"error":"Could not resolve host: wallet.sefer.live","url":"https:\/\/wallet.sefer.live\/seferpw.shop\/sefer\/ride\/seferWallet\/add.php"}
[2025-03-20 21:27:10] STEP 6: Failed to add balance to Sefer wallet
[2025-03-20 21:31:51] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:31:51] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:31:51] STEP 1: Payment found | Data: {"payment_id":"19","status":"1","amount":100}
[2025-03-20 21:31:51] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:31:51] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:31:51] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:31:51] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:31:51] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:31:51] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:31:51] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 21:31:51] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:31:51] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 21:31:51] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":100,"paymentMethod":"unknown"}
[2025-03-20 21:31:51] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 21:35:58] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:35:58] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:35:58] STEP 1: Payment found | Data: {"payment_id":"20","status":"1","amount":100}
[2025-03-20 21:35:58] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:35:58] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:35:58] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:35:58] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:35:58] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:35:58] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:35:58] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 21:35:58] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:35:58] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 21:35:58] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":100,"paymentMethod":"unknown"}
[2025-03-20 21:35:58] STEP 4: tokenSefer generated successfully | Data: {"token_length":64}
[2025-03-20 21:35:58] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 21:52:30] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 21:52:30] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 21:52:30] STEP 1: Payment found | Data: {"payment_id":"21","status":"1","amount":100}
[2025-03-20 21:52:30] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 21:52:30] STEP 3: Calculating bonus | Data: {"amount":100}
[2025-03-20 21:52:30] STEP 3.1: Bonus calculation input | Data: {"amount":100}
[2025-03-20 21:52:30] STEP 3.2: Bonus calculation result | Data: {"input":100,"output":100}
[2025-03-20 21:52:30] STEP 3: Bonus calculated | Data: {"original_amount":100,"final_amount":100}
[2025-03-20 21:52:30] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:52:30] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 21:52:30] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":100}
[2025-03-20 21:52:30] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 21:52:30] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":100,"paymentMethod":"unknown"}
[2025-03-20 21:52:30] STEP 4: tokenSefer generated successfully | Data: {"token_length":64}
[2025-03-20 21:52:30] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 22:09:36] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:09:36] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:09:36] STEP 1: Payment found | Data: {"payment_id":"22","status":"1","amount":200}
[2025-03-20 22:09:36] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:09:36] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:09:36] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:09:36] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:09:36] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:09:36] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:09:36] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:09:36] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:09:36] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:09:36] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":null}
[2025-03-20 22:09:36] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":64}
[2025-03-20 22:09:36] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 22:19:03] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:19:03] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:19:03] STEP 1: Payment found | Data: {"payment_id":"23","status":"1","amount":200}
[2025-03-20 22:19:03] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:19:03] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:19:03] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:19:03] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:19:03] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:19:03] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:19:03] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:19:03] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:19:03] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:19:03] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":null}
[2025-03-20 22:19:03] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"e8131e30ba2ccef8c2f15cd03fa15d6151ca6e3fbc60778b9ad6fb5e105f383d"}
[2025-03-20 22:19:03] STEP 6.2: HTTP error in Sefer wallet update | Data: {"http_code":401,"response":"{\"error\":\"Authorization token required\"}"}
[2025-03-20 22:19:03] STEP 6: Failed to add balance to Sefer wallet
[2025-03-20 22:24:40] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:24:40] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:24:40] STEP 1: Payment found | Data: {"payment_id":"24","status":"1","amount":200}
[2025-03-20 22:24:40] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:24:40] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:24:40] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:24:40] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:24:40] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:24:40] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:24:40] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:24:40] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:24:40] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:24:40] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:24:40] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"9d924a59964a75c672502e0a961e79bcdb23d62f6fadfe2aa6b5cac145022015"}
[2025-03-20 22:24:40] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 22:38:27] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:38:27] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:38:27] STEP 1: Payment found | Data: {"payment_id":"25","status":"1","amount":200}
[2025-03-20 22:38:27] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:38:27] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:38:27] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:38:27] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:38:27] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:38:27] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:38:27] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:38:27] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:38:27] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:38:27] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:38:27] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"d0b8b5d6e25d74038ff96d9bb61533213536049fc99484df751cbff86f354058"}
[2025-03-20 22:38:27] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 22:45:51] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:45:51] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:45:51] STEP 1: Payment found | Data: {"payment_id":"26","status":"1","amount":200}
[2025-03-20 22:45:51] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:45:51] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:45:51] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:45:51] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:45:51] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:45:51] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:45:51] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:45:51] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:45:51] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:45:51] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:45:51] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"698f6808c38e9075e74513a21a2b8255c9b04c1473be5fb9bc559488e3a29c1f"}
[2025-03-20 22:45:51] STEP 6: Failed to add balance to Sefer wallet | Data: {"status":"failure","message":"Invalid or already used token"}
[2025-03-20 22:48:56] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:48:56] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:48:56] STEP 1: Payment found | Data: {"payment_id":"27","status":"1","amount":200}
[2025-03-20 22:48:56] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:48:56] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:48:56] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:48:56] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:48:56] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:48:56] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:48:56] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:48:56] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:48:56] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:48:56] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:48:56] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"86128c316f4f275e543fc07b7a171c39a1c92b81fcadd1548f6c150a1651d1f4"}
[2025-03-20 22:48:56] STEP 6.2: HTTP error in Sefer wallet update | Data: {"http_code":500,"response":""}
[2025-03-20 22:48:56] STEP 6: Failed to add balance to Sefer wallet
[2025-03-20 22:51:43] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:51:43] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:51:43] STEP 1: Payment found | Data: {"payment_id":"28","status":"1","amount":200}
[2025-03-20 22:51:43] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:51:43] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:51:43] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:51:43] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:51:43] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:51:43] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:51:43] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:51:43] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:51:43] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:51:43] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:51:43] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"9a7626a1c58f54e0181a059a9ce4758af2c75998941cc6c00947377b4fc5bacf"}
[2025-03-20 22:51:43] STEP 6.2: HTTP error in Sefer wallet update | Data: {"http_code":500,"response":""}
[2025-03-20 22:51:43] STEP 6: Failed to add balance to Sefer wallet
[2025-03-20 22:54:12] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 22:54:12] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 22:54:12] STEP 1: Payment found | Data: {"payment_id":"29","status":"1","amount":200}
[2025-03-20 22:54:12] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 22:54:12] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 22:54:12] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 22:54:12] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 22:54:12] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 22:54:12] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:54:12] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 22:54:12] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 22:54:12] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 22:54:12] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 22:54:12] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"7f955f629d5da0ec127b6c0b32de0fa44aeaad9c9ec8231418905c8031c94316"}
[2025-03-20 22:54:12] STEP 6: Balance added to Sefer wallet | Data: {"status":"success","message":"Wallet data saved successfully"}
[2025-03-20 22:54:12] STEP 7: Process completed successfully | Data: {"payment_id":"29","amount":215,"passengerId":"113172279072358305645"}
[2025-03-20 23:00:11] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 23:00:11] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 23:00:11] STEP 1: Payment found | Data: {"payment_id":"30","status":"1","amount":200}
[2025-03-20 23:00:11] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 23:00:11] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 23:00:11] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:00:11] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:00:11] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 23:00:11] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:00:11] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:00:11] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:00:11] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 23:00:11] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 23:00:11] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:00:11] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"5c6d19041cfab3851040212ccf045f21be41c84c5d736dfc58b2da7eb3c8854a"}
[2025-03-20 23:00:11] STEP 6: Balance added to Sefer wallet | Data: {"status":"success","message":"Wallet data saved successfully"}
[2025-03-20 23:00:11] STEP 7: Process completed successfully | Data: {"payment_id":"30","amount":215,"passengerId":"113172279072358305645"}
[2025-03-20 23:07:14] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 23:07:14] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 23:07:14] STEP 1: Payment found | Data: {"payment_id":"31","status":"1","amount":200}
[2025-03-20 23:07:14] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 23:07:14] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 23:07:14] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:07:14] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:07:14] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 23:07:14] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:07:14] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:07:14] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:07:14] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 23:07:14] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 23:07:14] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:07:14] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"b912396d32c1b398d65e4459ac945079025840776db6feb34a9cc4f06b60191a"}
[2025-03-20 23:07:14] STEP 6: Balance added to Sefer wallet | Data: {"status":"success","message":"Wallet data saved successfully"}
[2025-03-20 23:07:14] STEP 7: Process completed successfully | Data: {"payment_id":"31","amount":215,"passengerId":"113172279072358305645"}
[2025-03-20 23:13:05] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:13:05] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:13:05] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"3b68024312f568ea264d279280d9a6164a4a272531b21678d6a5e556816a7592"}
[2025-03-20 23:28:20] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 23:28:20] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 23:28:20] STEP 1: Payment found | Data: {"payment_id":"36","status":"1","amount":200}
[2025-03-20 23:28:20] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 23:28:20] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 23:28:20] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:28:20] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:28:20] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 23:28:20] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:28:20] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:28:20] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:28:20] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 23:28:20] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 23:28:20] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:28:20] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"b0f64da4cfca1bf153c523a03cd692b8f1a44c09674683df5406dcd6c874f00d"}
[2025-03-20 23:28:20] STEP 6: Balance added to Sefer wallet | Data: {"status":"success","message":"Wallet data saved successfully"}
[2025-03-20 23:28:20] STEP 7: Process completed successfully | Data: {"payment_id":"36","amount":215,"passengerId":"113172279072358305645"}
[2025-03-20 23:31:52] STEP 0: Request received | Data: {"user_id":"+201010101010","passengerId":"113172279072358305645"}
[2025-03-20 23:31:52] STEP 1: Querying latest payment | Data: {"user_id":"+201010101010"}
[2025-03-20 23:31:52] STEP 1: Payment found | Data: {"payment_id":"37","status":"1","amount":200}
[2025-03-20 23:31:52] STEP 2: Payment status verified | Data: {"status":"1"}
[2025-03-20 23:31:52] STEP 3: Calculating bonus | Data: {"amount":200}
[2025-03-20 23:31:52] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:31:52] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:31:52] STEP 3: Bonus calculated | Data: {"original_amount":200,"final_amount":215}
[2025-03-20 23:31:52] STEP 4: Generating payment token | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:31:52] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:31:52] STEP 5: Adding balance to passenger wallet | Data: {"passengerId":"113172279072358305645","amount":215}
[2025-03-20 23:31:52] STEP 5: Balance added to passenger wallet | Data: {"status":"success","message":"Wallet record created successfully"}
[2025-03-20 23:31:52] STEP 6: Adding balance to Sefer wallet | Data: {"passengerId":"113172279072358305645","amount":215,"paymentMethod":"visa-in"}
[2025-03-20 23:31:52] STEP 4: Token generated successfully | Data: {"token_length":64}
[2025-03-20 23:31:52] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"dc156df7310f9ce998bf0fae3a325a716ec7806ff037021c4b12b3b800f37bf2"}
[2025-03-20 23:31:52] STEP 6: Balance added to Sefer wallet | Data: {"status":"success","message":"Wallet data saved successfully"}
[2025-03-20 23:31:52] STEP 7: Process completed successfully | Data: {"payment_id":"37","amount":215,"passengerId":"113172279072358305645"}
[2025-03-20 23:49:27] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-20 23:49:27] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-20 23:49:27] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"172ea88c6fc36188b435508f8f434736cc58f2b75feb54e6b8fa1674d4a9910a"}
[2025-03-21 09:32:00] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 09:32:00] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 09:32:00] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"6ad135e7b01bf9c1ab99f68d0dead8f91bc93588c173d837a8f3ce77e96c6eee"}
[2025-03-21 09:33:06] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 09:33:06] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 09:33:06] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"4ebb300836e9cb522a0afd422e818c2603fda11ef52e050a78624f728b994f01"}
[2025-03-21 09:41:54] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 09:45:44] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 09:48:54] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 11:30:48] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 11:37:18] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 12:19:24] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 12:20:48] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 12:22:09] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 12:22:09] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 12:22:09] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"a5589a7714ea56acd72341a0c14079d3b8d548dbef885a2f71ea19cd20325c91"}
[2025-03-21 12:37:16] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 12:37:16] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 12:37:17] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"d6f2e4bc82d052bcba3d287e5c4f3465ad8f3707ee739692e2832a5b9dc131c6"}
[2025-03-21 12:49:11] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 12:51:03] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 12:51:03] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 12:51:04] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"3081636c569695289e5484b738d6cf63bd015505490b3c94841538767ff2f058"}
[2025-03-21 14:04:09] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:04:09] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:04:10] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"67e48b2025ea10823d2c37eb9f821963efff9fa26b5e41d5b1d391376a31b59a"}
[2025-03-21 14:07:48] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:17:03] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:17:03] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:17:03] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"e952b7b4417a71eaff2b348e8241c4a63d97b12d4ad1d79acfb5cce1992a2acd"}
[2025-03-21 14:24:19] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:28:35] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:32:45] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:37:37] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:38:56] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:38:56] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:38:56] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"a8aad013fb6332aef78521c6cccff74485c158bbdb3242e51e66ab7f1059e4c9"}
[2025-03-21 14:42:15] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:42:15] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:42:15] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"2803a235094afa54c82ad250292f15a121f524bf4c109df32342068a03c9c212"}
[2025-03-21 14:45:52] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:45:52] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:45:52] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"1e6a84b59f5580fb4fe52248222620c7cb3c44f8edfeb0db0003192a90403aa3"}
[2025-03-21 14:54:41] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 14:59:31] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 14:59:31] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 14:59:31] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"7dee4184aa286693ef8e3a2c4fe03b103d6ff8348198f5faa6bfc91c4ed6ae21"}
[2025-03-21 15:19:15] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:19:15] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:19:15] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"0ebad59f5b4b439fae5e5e8f6fa65e816ac5943e724ef1758dc714bdea39bdb8"}
[2025-03-21 15:21:45] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:21:45] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:21:45] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"abfb981f8fbfba8cf3591c502d27a9b03066d909c95f44b3adfee6b01523e4df"}
[2025-03-21 15:23:37] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:23:37] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:23:37] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"c0775be365dbad9fc99ee84786b7101d4bbd51bf4d8b29475e7407b350a5873f"}
[2025-03-21 15:28:30] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:28:30] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:28:31] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"51181d3015c2756d256569e96ec7221b34aba737483a3f8e92858840c50441ae"}
[2025-03-21 15:28:55] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:28:55] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:28:55] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"6a3c946d98dbc3ed66e8e30b80c56fc8925073fce70105260c64bc86c1e5cd6c"}
[2025-03-21 15:35:16] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:35:16] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:35:16] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"b4f3b175044981388b0ecd6cf9f7f9713f591f20c58e55a977c9be9029a45fb4"}
[2025-03-21 15:38:43] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:38:43] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:38:43] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"de17e4d8db68e3e0649d6515937fa1ef8464a47bef52a8178a751e54d1fde4e3"}
[2025-03-21 15:39:48] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:39:48] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:39:48] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"cf0b6242a0c25023b69dfdfa17ee4ff5c4e265e0b1ae43276891347f08f6d648"}
[2025-03-21 15:43:53] STEP 1: No payment found | Data: {"user_id":"+201010101010"}
[2025-03-21 15:44:58] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:44:58] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:44:59] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"fc66691cf53e4f559b3ff957a13384a84052ca52b191de3c5a76ed5572827e2e"}
[2025-03-21 15:47:30] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:47:30] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:47:30] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"c16c271306018e5791ba0e0ca8012ba4c3674837bec30164c39a61e0715f7124"}
[2025-03-21 15:49:41] STEP 3.1: Bonus calculation input | Data: {"amount":200}
[2025-03-21 15:49:41] STEP 3.2: Bonus calculation result | Data: {"input":200,"output":215}
[2025-03-21 15:49:41] STEP 6.0.2: Generated new Sefer token | Data: {"token_length":"2d2024c3b3954388a45dc40ec0ac8a62af917975def467636a26ee14ca97c8b9"}
[2025-03-21 16:36:27] STEP 1: No payment found | Data: {"user_id":"+201010101010"}

View File

@@ -1,125 +0,0 @@
<?php
// /v1/main/ride/mtn/driver/confirm_payment.php
include "../../../connect.php";
// It's better to use __DIR__ for reliable file path resolution.
// Assuming your private_key.pem is in the same directory as this script.
$privateKeyPath = __DIR__ . "/private_key.pem";
$baseUrl = rtrim(getenv('MTN_API_BASE_URL'), '/');
$terminalId = getenv('MTN_TERMINAL_ID');
$privateKey = openssl_pkey_get_private(file_get_contents($privateKeyPath));
$invoice = filterRequest('invoiceNumber');
$phone = filterRequest('phone');
$guid = filterRequest('guid');
$operationNumber = filterRequest('operationNumber');
$code = filterRequest('otp'); // The OTP
error_log("MTN Confirm (Driver): Start request for invoice={$invoice}, phone={$phone}, guid={$guid}, opNum={$operationNumber}");
if (!$invoice || !$phone || !$guid || !$operationNumber || !$code) {
error_log("MTN Confirm (Driver): Missing parameters");
printFailure("Missing parameters.");
exit;
}
// Encrypt the code
$hashBin = hash('sha256', $code, true);
$codeB64 = base64_encode($hashBin);
$body = [
'Invoice' => intval($invoice),
'Phone' => $phone,
'Guid' => $guid,
'OperationNumber' => intval($operationNumber),
'Code' => $codeB64
];
$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE);
error_log("MTN Confirm (Driver): Prepared body JSON: " . $bodyJson);
// Generate signature
$signResult = openssl_sign($bodyJson, $sig, $privateKey, OPENSSL_ALGO_SHA256);
if (!$signResult) {
error_log("MTN Confirm (Driver): Failed to generate signature");
printFailure("Signature error.");
exit;
}
$xSignature = base64_encode($sig);
error_log("MTN Confirm (Driver): Generated signature");
// Send the request
$ch = curl_init("{$baseUrl}/pos_web/payment_phone/confirm");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $bodyJson,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Request-Name: pos_web/payment_phone/confirm",
"Subject: {$terminalId}",
"X-Signature: {$xSignature}"
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
error_log("MTN Confirm (Driver): HTTP $httpCode - Response: $response");
if ($curlError) {
error_log("MTN Confirm (Driver): cURL error - $curlError");
}
// --- SOLUTION IMPLEMENTED HERE ---
// 1. Decode the response from MTN to check its contents.
$responseData = json_decode($response, true) ?: [];
// 2. First, check for network/gateway level failure.
if ($httpCode !== 200) {
error_log("MTN Confirm (Driver): HTTP failure for invoice {$invoice}. Code: {$httpCode}");
// Use printFailure to send a structured error to Flutter
printFailure(['message' => 'MTN Gateway Error', 'http' => $httpCode, 'details' => $responseData]);
exit;
}
// 3. Now, check for business-logic failure (like "Balance not enough").
$errno = $responseData['Errno'] ?? -1; // Default to an error state if Errno is missing
if ($errno !== 0) {
$apiError = $responseData['Error'] ?? 'Unknown MTN API Error';
error_log("MTN Confirm (Driver): Business failure for invoice {$invoice}. Errno: {$errno}, Reason: {$apiError}");
// This now sends the specific error message in the format Flutter expects!
printFailure(['message' => $apiError, 'errno' => $errno, 'details' => $responseData]);
exit;
}
// --- ONLY PROCEED TO DATABASE ON FULL SUCCESS (HTTP 200 AND Errno 0) ---
try {
$stmt = $con->prepare(
"UPDATE `paymentsLogSyriaDriver` SET status = 1, updated_at = NOW()
WHERE order_ref = :inv"
);
$stmt->execute([':inv' => $invoice]);
error_log("MTN Confirm (Driver): Payment updated successfully in DB for invoice={$invoice}");
// The file path correction from before remains important.
include_once __DIR__ . '/finalize_wallet_payment.php';
// Call the wallet finalization logic
if (function_exists('finalizeWalletPayment')) {
$_GET['orderRef'] = $invoice;
finalizeWalletPayment($con);
} else {
error_log("MTN Confirm (Driver): FATAL - finalizeWalletPayment() function does not exist after include.");
}
// On success, send a success response to Flutter
printSuccess(['message' => 'Payment confirmed successfully', 'details' => $responseData]);
} catch (PDOException $e) {
error_log("MTN Confirm (Driver): DB update error - " . $e->getMessage());
printFailure("Database processing error.");
}

View File

@@ -1,103 +0,0 @@
<?php
// wallet/finalize_wallet_payment.php
include_once "../../../jwtconnect.php";
define("LOG_FILE", "../logs/payment_verification.log");
function logError($step, $message, $data = null) {
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$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, $logEntry . PHP_EOL, FILE_APPEND);
}
function generateToken($con, $driverId, $amount): ?string {
global $secretKey;
$data = $driverId . $amount . time() . ($secretKey ?? 'default_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;
}
function generatePaymentID($con, $driverId, $amount, $method): ?string {
$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;
}
function finalizeWalletPayment($con) {
$orderRef = $_GET['orderRef'] ?? null;
if (empty($orderRef)) {
logError("FINALIZE", "Missing orderRef");
return;
}
// 1. تحقق من الدفع
$stmt = $con->prepare("SELECT * FROM `paymentsLogSyriaDriver` WHERE order_ref = :order_ref AND status = 1 LIMIT 1");
$stmt->execute([':order_ref' => $orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
logError("FINALIZE", "Payment not found or not completed", ['orderRef' => $orderRef]);
return;
}
try {
$driverId = $payment['user_id'];
$originalAmount = floatval($payment['amount']);
$paymentMethod = $payment['payment_method'] ?? 'ecash';
// حساب المكافأة
$bonusAmount = match ((int)$originalAmount) {
10000 => 10000.0,
20000 => 21000.0,
40000 => 45000.0,
100000 => 110000.0,
default => $originalAmount,
};
// إنشاء التوكنات
$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');
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new Exception('Failed to generate payment ID');
// 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]);
// 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
]);
$con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token")->execute([':token' => $tokenSefer]);
logError("FINALIZE", "Wallets updated successfully", ['orderRef' => $orderRef]);
printSuccess("FINALIZE", "Wallets updated successfully");
} catch (Throwable $e) {
logError("FINALIZE", "Exception during finalization: " . $e->getMessage(), ['orderRef' => $orderRef]);
}
}

View File

@@ -1,47 +0,0 @@
<?php
// File: generate_keys.php
// الوظيفة: إنشاء زوج المفاتيح (العام والخاص) لمرة واحدة فقط
// إعدادات لتوليد المفتاح
$config = [
"digest_alg" => "sha256",
"private_key_bits" => 1024,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
// إنشاء زوج المفاتيح
$res = openssl_pkey_new($config);
if (!$res) {
die('Failed to generate new private key. Error: ' . openssl_error_string());
}
// استخراج المفتاح الخاص
openssl_pkey_export($res, $private_key);
// استخراج المفتاح العام
$public_key_details = openssl_pkey_get_details($res);
$public_key = $public_key_details["key"];
// حفظ المفاتيح في ملفات
file_put_contents('private_key.pem', $private_key);
file_put_contents('public_key.pem', $public_key);
echo "<h1>Keys Generated Successfully!</h1>";
echo "<h2>Private Key (saved to private_key.pem):</h2>";
echo "<pre>" . htmlspecialchars($private_key) . "</pre>";
echo "<h2>Public Key (saved to public_key.pem):</h2>";
echo "<pre>" . htmlspecialchars($public_key) . "</pre>";
// --- تحضير المفتاح العام لعملية التفعيل ---
// إزالة الهيدر والفوتر والأسطر الجديدة كما هو مطلوب
$formatted_public_key = str_replace("-----BEGIN PUBLIC KEY-----", "", $public_key);
$formatted_public_key = str_replace("-----END PUBLIC KEY-----", "", $formatted_public_key);
$formatted_public_key = preg_replace("/\s+/", "", $formatted_public_key);
echo "<h2>Formatted Public Key (for Terminal Activation):</h2>";
echo "<p><strong>انسخ هذا المفتاح لاستخدامه في خطوة تفعيل الجهاز (activate_terminal.php)</strong></p>";
echo "<textarea rows='5' cols='80' readonly>" . htmlspecialchars($formatted_public_key) . "</textarea>";
?>

View File

@@ -1,54 +0,0 @@
<?php
// /v1/main/ride/mtn/passenger/initiate_payment.php
include "../../../connect.php";
$baseUrl = rtrim(getenv('MTN_API_BASE_URL'), '/');
$terminalId = getenv('MTN_TERMINAL_ID');
$privateKeyPem = getenv('MTN_PRIVATE_KEY');
$invoice = filterRequest('invoice'); // رقم الفاتورة
$phone = filterRequest('phone'); // رقم الزبون
$guid = uniqid('mtn_');
if (!$invoice || !$phone) {
printFailure("Missing invoice or phone.");
exit;
}
$body = json_encode([
'Invoice' => intval($invoice),
'Phone' => $phone,
'Guid' => $guid
], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
$hash = hash('sha256', $body, true);
openssl_sign($hash, $sig, $privateKeyPem, OPENSSL_ALGO_SHA256);
$xSignature = base64_encode($sig);
$ch = curl_init("{$baseUrl}/pos_web/payment_phone/initiate");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Request-Name: pos_web/payment_phone/initiate",
"Subject: {$terminalId}",
"X-Signature: {$xSignature}"
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// سجل المحاولة مع Guid
$stmt = $con->prepare(
"UPDATE `mtn_payments`
SET guid = :guid, status = 3, updated_at = NOW()
WHERE invoice = :inv"
);
$stmt->execute([':guid'=>$guid, ':inv'=>$invoice]);
header('Content-Type: application/json');
http_response_code($httpCode);
echo $response;

View File

@@ -1,56 +0,0 @@
<?php
// بيانات التفعيل
$terminalId = "9001000000060863";
$activationCode = "26164711";
$serialNumber = "INTALEQ-001"; // يمكنك تغييره
// المفتاح العام على سطر واحد — بدون BEGIN/END وبدون أسطر جديدة
//$publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNxFbepx2OrpyrNG4+/aAaH3Rjc8dGw6B6vMAfsZzzm4wzoSkrtsr6jfuaMTZRLwxS5h8k1ztLG1HrOmL/NDsiE/7yxaKLAIZyWB/rR9byvPeOCC8QnCd/08kmxNl/l7Akn6qlPwsVpKUUNsr0SkU9lShMAw4OBgQq399jsbkFSwIDAQAB";
$publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOhVAdUyxFpVNSyjRndMWEPAN9vJEetMzLbjF9DTn2lPVuRj/Mkwq9wCNhy+tdeX2lIn4K3EkONBvYJubBhxnYOoQuMchPW5vG7VnmpLjZ7TkpM2n9fcMu8u1GkLatLblDI4LTfvn3851+nhpnYlUVkjw5GAhH4XnEpveIjqDhzQIDAQAB";
// جسم الطلب
$body = [
"Key" => $publicKey,
"Secret" => $activationCode,
"Serial" => $serialNumber
];
//$bodyJson = json_encode($body, JSON_UNESCAPED_SLASHES);
$bodyJson = trim(stripslashes(json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_LINE_TERMINATORS)),'"');
//$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 1. توليد هاش SHA256 للـ JSON
//$bodyHash = hash('sha256', $bodyJson, true);
// 2. تحميل المفتاح الخاص للتوقيع
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem")); // تأكد من وجود هذا الملف بجانب السكربت
// 3. توقيع الهاش
openssl_sign($bodyJson, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// 4. تحويل التوقيع إلى Base64
$xSignature = base64_encode($signature);
// 5. إرسال الطلب
$headers = [
"Content-Type: application/json",
"Accept-Language: en",
"Request-Name: pos_web/pos/activate",
"Subject: $terminalId",
"X-Signature: $xSignature"
];
$ch = curl_init("https://cashmobile.mtnsyr.com:9000");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyJson);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ✅ النتيجة
header('Content-Type: application/json');
echo json_encode([
"httpCode" => $httpCode,
"response" => json_decode($response, true),
"sentBody" => $body,
]);

View File

@@ -1,129 +0,0 @@
<?php
include "../../../connect.php";
date_default_timezone_set("Asia/Damascus");
// ========== إعدادات MTN ==========
$terminalId = "9001000000060863";
$currencyCode = 760;
$sessionNumber = 0;
$ttl = 15;
// ====== استقبال البيانات من فلاتر ======
$amount = filterRequest("amount");
$passengerId = filterRequest("passengerId");
$phone = filterRequest("phone");
// ✅ Log مبدئي
error_log("🚦 START | passengerId: $passengerId | phone: $phone | amount: $amount");
// تحقق من المدخلات
if (empty($amount) || empty($passengerId) || empty($phone) || $amount <= 0) {
error_log("❌ Invalid input: amount=$amount, passengerId=$passengerId, phone=$phone");
printFailure("بيانات الدفع غير كاملة أو غير صالحة.");
exit;
}
// ====== توليد invoiceNumber و GUID ======
$invoiceNumber = mt_rand(10000000000, 99999999999);
//$invoiceNumber = "MTN_" . $passengerId . "_" . time();
$guid = uniqid("mtn_");
error_log("🧾 Generated Invoice: $invoiceNumber");
error_log("🧭 Generated GUID: $guid");
// ====== 1. إنشاء الفاتورة ======
$createInvoiceBody = [
"Amount" => intval($amount * 100),
"Invoice" => $invoiceNumber,
"Session" => $sessionNumber,
"TTL" => $ttl
];
error_log("📦 Create Invoice Body: " . json_encode($createInvoiceBody, JSON_UNESCAPED_UNICODE));
$invoiceResponse = sendMtnApiRequest("pos_web/invoice/create", $terminalId, $createInvoiceBody);
error_log("📥 Create Invoice Response: " . json_encode($invoiceResponse, JSON_UNESCAPED_UNICODE));
if (!$invoiceResponse || isset($invoiceResponse['Errno']) && $invoiceResponse['Errno'] != 0) {
error_log("❌ Failed to create invoice. Error: " . json_encode($invoiceResponse));
printFailure("فشل إنشاء الفاتورة عبر MTN.");
exit;
}
// ====== 2. بدء الدفع ======
$initiateBody = [
"Invoice" => $invoiceNumber,
"Phone" => $phone,
"Guid" => $guid
];
error_log("📤 body initiateBody: $initiateBody");
error_log("📦 Initiate Payment Body: " . json_encode($initiateBody, JSON_UNESCAPED_UNICODE));
$initiateResponse = sendMtnApiRequest("pos_web/payment_phone/initiate", $terminalId, $initiateBody);
error_log("📥 Initiate Response: " . json_encode($initiateResponse, JSON_UNESCAPED_UNICODE));
if (!$initiateResponse || !isset($initiateResponse['OperationNumber'])) {
error_log("❌ Failed to initiate payment.");
printFailure($initiateResponse);
exit;
}
$operationNumber = $initiateResponse['OperationNumber'];
// ====== 3. تسجيل العملية ======
try {
$stmt = $con->prepare("INSERT INTO `paymentsLogSyriaDriver`
(`user_id`, `amount`, `status`, `order_ref`, `payment_method`, `created_at`)
VALUES (?, ?, 2, ?, 'mtn', NOW())");
$stmt->execute([$passengerId, $amount, $invoiceNumber]);
error_log("✅ DB Log Inserted.");
} catch (PDOException $e) {
error_log("❌ DB ERROR: " . $e->getMessage());
printFailure("فشل في تسجيل العملية.");
exit;
}
// ====== 4. نجاح
error_log("✅ Payment initiation successful.");
printSuccess([
"invoiceNumber" => $invoiceNumber,
"operationNumber" => $operationNumber,
"guid" => $guid
]);
// ====== دالة إرسال الطلب =====================
function sendMtnApiRequest($requestName, $terminalId, $body)
{
$apiUrl = "https://cashmobile.mtnsyr.com:9000";
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem"));
// ✅ تحويل الـ body إلى JSON بدون فراغات أو أسطر
$bodyJson = trim(stripslashes(json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_LINE_TERMINATORS)), '"');
//$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// ✅ توليد التوقيع
// $bodyHash = hash('sha256', $bodyJson, true);
error_log("📤 body before JSON: $bodyJson");
openssl_sign($bodyJson, $signature, $privateKey, OPENSSL_ALGO_SHA256);
$xSignature = base64_encode($signature);
error_log("📤 body xSignature: $xSignature");
// ✅ رؤوس الطلب
$headers = [
"Content-Type: application/json",
"Accept-Language: en",
"Request-Name: $requestName",
"Subject: $terminalId",
"X-Signature: $xSignature"
];
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyJson);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// ✅ لوق داخلي
error_log("🔐 Signature for $requestName: $xSignature");
error_log("📤 Sent JSON: $bodyJson");
curl_close($ch);
return json_decode($response, true);
}

View File

@@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDOhVAdUyxFpVNSyjRndMWEPAN9vJEetMzLbjF9DTn2lPVuRj/M
kwq9wCNhy+tdeX2lIn4K3EkONBvYJubBhxnYOoQuMchPW5vG7VnmpLjZ7TkpM2n9
fcMu8u1GkLatLblDI4LTfvn3851+nhpnYlUVkjw5GAhH4XnEpveIjqDhzQIDAQAB
AoGBALRcAvqJT8nHN7y+8QNFHNZ+XwIpc4egmJY1Ny0iJvPtZWaYHVG5PRE4Qu4+
29+3oX5dYDx146tu4L5mQvLS3ULBsvxaUZt2lT/vxkQzI9pNfXw584WvIrbtxQod
ILvBcnamwQa9hEOIFZVyZ/hzkzUcMO6cAXqvsfqqPgJhm7PBAkEA+xgE9CUOLDFl
vLePQKGcHIUOsPLr16qNEgGhTW7Km3OMMqoB2f7t67xOHGqK6tnANRM4Sk6IModI
wbZuVh4jMQJBANKOVmIdDLNffZVHp90SDRG7/YdK2R5ob361CIkcUzjh927Wfs5W
A/WroB7eJ7pWiq2BMaj/xq65nYaCOldvaV0CQQDm12c+eY61DFjnDa6ykaEvCxi9
jydJp+93vW3o/VFhZvJeZbO8EcX0MrNxJnY+gSBW6yuWDOrj4UH/bVO08pIRAkEA
lH3TiBAqo9nlTEEjrnILi4VD0IVFx/8pGnf71A6I1qXuBVn6RfQ9iKWIIBzWccCU
vrZNWn1AFntLD9CJ6p3k9QJBAMbSQ9CoXWlOLJRduV15ER1ZyE/inVd4jIvtjAgz
b7QaM62Ecxl3D8EI/LTSZV9Oa8D/62cJeMsflVa7gpavL70=
-----END RSA PRIVATE KEY-----

View File

@@ -1,6 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqBQZEJXWCQwPsPzBM70M3TjyU
5vwCZWoEtUomR9Qu+dEQaa0Hniz6JY8+goCxfMYuZQw6+kimctA2KqzT2pCsJufN
b92pSAMZgb0RSTl2y62oJkJd2WY7dj36AvPEyw6DxCFItvFOu7HGl3LlHQBriiw3
jwtuS6DO7gbmAJPU8wIDAQAB
-----END PUBLIC KEY-----

View File

@@ -1,115 +0,0 @@
<?php
include "../../connect.php";
// --- 2. استقبال البيانات من الطلب ---
$driver_id = filterRequest("driver_id");
$driver_name = filterRequest("driver_name");
$amount = filterRequest("amount");
$wallet_type = filterRequest("wallet_type");
$wallet_number = filterRequest("wallet_number");
// التحقق من أن البيانات الأساسية موجودة
if (empty($driver_id) || empty($driver_name) || empty($amount) || empty($wallet_type) || empty($wallet_number)) {
printFailure('Missing required fields.');
exit();
}
// --- 3. إدراج الطلب في قاعدة البيانات ---
try {
$sql = "INSERT INTO driver_withdrawal_requests (driver_id, driver_name, amount, wallet_type, wallet_number) VALUES (?, ?, ?, ?, ?)";
$stmt = $con->prepare($sql);
// تنفيذ الاستعلام مع تمرير البيانات
$success = $stmt->execute([
$driver_id,
$driver_name,
$amount,
$wallet_type,
$wallet_number
]);
if ($success) {
// --- 4. الحصول على رقم الطلب وإرسال إشعار واتساب ---
$transaction_id = $con->lastInsertId(); // الحصول على رقم التعريف الخاص بالطلب الجديد
sendWhatsAppNotification($transaction_id, $driver_name, $amount, $wallet_type, $wallet_number);
// إرسال استجابة نجاح إلى التطبيق
printSuccess("Withdrawal request saved and notification sent.");
} else {
printFailure('Failed to save withdrawal request.');
}
} catch (PDOException $e) {
// التعامل مع أخطاء قاعدة البيانات
error_log("Database Error in request_withdrawal.php: " . $e->getMessage());
printFailure('A database error occurred.');
}
/**
* دالة لإرسال إشعار إلى خدمة العملاء عبر RaseelPlus API
*/
function sendWhatsAppNotification($transaction_id, $driver_name, $amount, $wallet_type, $wallet_number) {
// استخدام متغيرات البيئة (Environment Variables) هو الطريقة الأكثر أماناً لإدارة المعلومات الحساسة
// بدلاً من كتابتها مباشرة في الكود.
$customer_service_number = getenv('CUSTOMER_SERVICE_WHATSAPP');
// $customer_service_number = "9639XXXXXXXX"; // كرقم احتياطي مؤقت
// نص الرسالة مع إضافة رقم الطلب
$messageBody = "طلب سحب جديد (رقم الطلب: #$transaction_id):\n\n" .
"اسم السائق: " . $driver_name . "\n" .
"المبلغ: " . $amount . " ل.س\n" .
"نوع المحفظة: " . $wallet_type . "\n" .
"رقم المحفظة: " . $wallet_number;
// بيانات الطلب (Payload) للـ API
$payload = [
"number" => $customer_service_number,
"type" => "text",
"message" => $messageBody,
"instance_id" => getenv('instance_idWhatsApp');
"access_token" => getenv('access_tokenWhatsApp');
];
// استدعاء الـ API
// ملاحظة: لا نتحقق من استجابة الـ API هنا لأن العملية الرئيسية (حفظ الطلب) قد نجحت بالفعل.
// يمكن إضافة تسجيل للأخطاء إذا لزم الأمر.
callAPI_Withdrawal("POST", "https://raseelplus.com/api/send", json_encode($payload));
}
/**
* دالة لإجراء استدعاءات API باستخدام cURL
*/
function callAPI_Withdrawal($method, $url, $data) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Accept: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
// تسجيل الخطأ في سجلات الخادم للمراجعة لاحقًا
error_log("[callAPI_Withdrawal] cURL Error #: " . $err);
return null;
} else {
return json_decode($response);
}
}
?>

View File

@@ -1,169 +0,0 @@
<?php
// /v1/main/ride/mtn/passenger/confirm_payment.php
include "../../../connect.php";
$baseUrl = rtrim(getenv('MTN_API_BASE_URL'), '/');
$terminalId = getenv('MTN_TERMINAL_ID');
$privateKeyPem = getenv('MTN_PRIVATE_KEY');
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem"));
$invoice = filterRequest('invoiceNumber');
$phone = filterRequest('phone');
$guid = filterRequest('guid');
$operationNumber = filterRequest('operationNumber');
$code = filterRequest('otp'); // الـ OTP
error_log("MTN Confirm: Start request for invoice={$invoice}, phone={$phone}, guid={$guid}, opNum={$operationNumber}");
if (!$invoice || !$phone || !$guid || !$operationNumber || !$code) {
error_log("MTN Confirm: Missing parameters");
printFailure("Missing parameters.");
exit;
}
// تشفير الكود
$hashBin = hash('sha256', $code, true);
$codeB64 = base64_encode($hashBin);
$body = [
'Invoice' => intval($invoice),
'Phone' => $phone,
'Guid' => $guid,
'OperationNumber' => intval($operationNumber),
'Code' => $codeB64
];
$bodyJson = trim(stripslashes(json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_LINE_TERMINATORS)), '"');
error_log("MTN Confirm: Prepared body JSON: " . $bodyJson);
// توليد التوقيع
$signResult = openssl_sign($bodyJson, $sig, $privateKey, OPENSSL_ALGO_SHA256);
if (!$signResult) {
error_log("MTN Confirm: Failed to generate signature");
printFailure("Signature error.");
exit;
}
$xSignature = base64_encode($sig);
error_log("MTN Confirm: Generated signature");
// إرسال الطلب
$ch = curl_init("{$baseUrl}/pos_web/payment_phone/confirm");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $bodyJson,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Request-Name: pos_web/payment_phone/confirm",
"Subject: {$terminalId}",
"X-Signature: {$xSignature}"
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
error_log("MTN Confirm: HTTP $httpCode - Response: $response");
if ($curlError) {
error_log("MTN Confirm: cURL error - $curlError");
}
// تحديث قاعدة البيانات في حال نجاح
if ($httpCode === 200) {
try {
$stmt = $con->prepare(
"UPDATE `paymentsLogSyria` SET status = 1, updated_at = NOW()
WHERE order_ref = :inv"
);
$stmt->execute([':inv' => $invoice]);
error_log("MTN Confirm: Payment updated successfully in DB for invoice={$invoice}");
$stmt = $con->prepare("SELECT * FROM paymentsLogSyria WHERE order_ref = :order_ref LIMIT 1");
$stmt->execute([':order_ref' => $invoice]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if ($payment) {
$userId = $payment['user_id'];
$amount = $payment['amount'];
$paymentMethod = $payment['payment_method'] ?? 'mtn';
$finalAmount = calculateBonus($amount);
$token = generatePaymentToken($userId, $finalAmount);
$walletResult = addToPassengerWallet($userId, $finalAmount, $token);
$seferToken = generatePaymentToken($userId, $amount);
$seferWalletResult = addToSeferWallet($userId, $amount, $paymentMethod, $seferToken);
printSuccess('MTN Confirm');
exit;
}
} catch (PDOException $e) {
error_log("MTN Confirm: DB update error - " . $e->getMessage());
}
} else {
error_log("MTN Confirm: Payment failed with HTTP code $httpCode");
}
header('Content-Type: application/json');
http_response_code($httpCode);
echo $response;
function calculateBonus($amount) {
if ($amount == 200000) return 205000;
if ($amount == 400000) return 425000;
if ($amount == 1000000) return 1040000;
return $amount;
}
function generatePaymentToken($passengerId, $amount) {
$url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = ['passengerId' => $passengerId, 'amount' => $amount];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
$data = json_decode($response, true);
return $data['message'] ?? null;
}
function addToPassengerWallet($passengerId, $amount, $token) {
$url = BASE_URL . "/passengerWallet/add.php";
$postData = ['passenger_id' => $passengerId, 'balance' => $amount, 'token' => $token];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
return json_decode($response, true);
}
function addToSeferWallet($passengerId, $amount, $paymentMethod, $token) {
$url = BASE_URL . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $token,
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200) return null;
return json_decode($response, true);
}
?>

View File

@@ -1,103 +0,0 @@
<?php
// wallet/finalize_wallet_payment.php
include_once "../../../jwtconnect.php";
define("LOG_FILE", "../logs/payment_verification.log");
function logError($step, $message, $data = null) {
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$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, $logEntry . PHP_EOL, FILE_APPEND);
}
function generateToken($con, $driverId, $amount): ?string {
global $secretKey;
$data = $driverId . $amount . time() . ($secretKey ?? 'default_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;
}
function generatePaymentID($con, $driverId, $amount, $method): ?string {
$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;
}
function finalizeWalletPayment($con) {
$orderRef = $_GET['orderRef'] ?? null;
if (empty($orderRef)) {
logError("FINALIZE", "Missing orderRef");
return;
}
// 1. تحقق من الدفع
$stmt = $con->prepare("SELECT * FROM `paymentsLogSyriaDriver` WHERE order_ref = :order_ref AND status = 1 LIMIT 1");
$stmt->execute([':order_ref' => $orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
logError("FINALIZE", "Payment not found or not completed", ['orderRef' => $orderRef]);
return;
}
try {
$driverId = $payment['user_id'];
$originalAmount = floatval($payment['amount']);
$paymentMethod = $payment['payment_method'] ?? 'ecash';
// حساب المكافأة
$bonusAmount = match ((int)$originalAmount) {
10000 => 10000.0,
20000 => 21000.0,
40000 => 45000.0,
100000 => 110000.0,
default => $originalAmount,
};
// إنشاء التوكنات
$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');
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new Exception('Failed to generate payment ID');
// 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]);
// 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
]);
$con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token")->execute([':token' => $tokenSefer]);
logError("FINALIZE", "Wallets updated successfully", ['orderRef' => $orderRef]);
printSuccess("FINALIZE", "Wallets updated successfully");
} catch (Throwable $e) {
logError("FINALIZE", "Exception during finalization: " . $e->getMessage(), ['orderRef' => $orderRef]);
}
}

View File

@@ -1,47 +0,0 @@
<?php
// File: generate_keys.php
// الوظيفة: إنشاء زوج المفاتيح (العام والخاص) لمرة واحدة فقط
// إعدادات لتوليد المفتاح
$config = [
"digest_alg" => "sha256",
"private_key_bits" => 1024,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
// إنشاء زوج المفاتيح
$res = openssl_pkey_new($config);
if (!$res) {
die('Failed to generate new private key. Error: ' . openssl_error_string());
}
// استخراج المفتاح الخاص
openssl_pkey_export($res, $private_key);
// استخراج المفتاح العام
$public_key_details = openssl_pkey_get_details($res);
$public_key = $public_key_details["key"];
// حفظ المفاتيح في ملفات
file_put_contents('private_key.pem', $private_key);
file_put_contents('public_key.pem', $public_key);
echo "<h1>Keys Generated Successfully!</h1>";
echo "<h2>Private Key (saved to private_key.pem):</h2>";
echo "<pre>" . htmlspecialchars($private_key) . "</pre>";
echo "<h2>Public Key (saved to public_key.pem):</h2>";
echo "<pre>" . htmlspecialchars($public_key) . "</pre>";
// --- تحضير المفتاح العام لعملية التفعيل ---
// إزالة الهيدر والفوتر والأسطر الجديدة كما هو مطلوب
$formatted_public_key = str_replace("-----BEGIN PUBLIC KEY-----", "", $public_key);
$formatted_public_key = str_replace("-----END PUBLIC KEY-----", "", $formatted_public_key);
$formatted_public_key = preg_replace("/\s+/", "", $formatted_public_key);
echo "<h2>Formatted Public Key (for Terminal Activation):</h2>";
echo "<p><strong>انسخ هذا المفتاح لاستخدامه في خطوة تفعيل الجهاز (activate_terminal.php)</strong></p>";
echo "<textarea rows='5' cols='80' readonly>" . htmlspecialchars($formatted_public_key) . "</textarea>";
?>

View File

@@ -1,54 +0,0 @@
<?php
// /v1/main/ride/mtn/passenger/initiate_payment.php
include "../../../connect.php";
$baseUrl = rtrim(getenv('MTN_API_BASE_URL'), '/');
$terminalId = getenv('MTN_TERMINAL_ID');
$privateKeyPem = getenv('MTN_PRIVATE_KEY');
$invoice = filterRequest('invoice'); // رقم الفاتورة
$phone = filterRequest('phone'); // رقم الزبون
$guid = uniqid('mtn_');
if (!$invoice || !$phone) {
printFailure("Missing invoice or phone.");
exit;
}
$body = json_encode([
'Invoice' => intval($invoice),
'Phone' => $phone,
'Guid' => $guid
], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
$hash = hash('sha256', $body, true);
openssl_sign($hash, $sig, $privateKeyPem, OPENSSL_ALGO_SHA256);
$xSignature = base64_encode($sig);
$ch = curl_init("{$baseUrl}/pos_web/payment_phone/initiate");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Request-Name: pos_web/payment_phone/initiate",
"Subject: {$terminalId}",
"X-Signature: {$xSignature}"
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// سجل المحاولة مع Guid
$stmt = $con->prepare(
"UPDATE `mtn_payments`
SET guid = :guid, status = 3, updated_at = NOW()
WHERE invoice = :inv"
);
$stmt->execute([':guid'=>$guid, ':inv'=>$invoice]);
header('Content-Type: application/json');
http_response_code($httpCode);
echo $response;

View File

@@ -1,56 +0,0 @@
<?php
// بيانات التفعيل
$terminalId = "9001000000060863";
$activationCode = "26164711";
$serialNumber = "INTALEQ-001"; // يمكنك تغييره
// المفتاح العام على سطر واحد — بدون BEGIN/END وبدون أسطر جديدة
//$publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNxFbepx2OrpyrNG4+/aAaH3Rjc8dGw6B6vMAfsZzzm4wzoSkrtsr6jfuaMTZRLwxS5h8k1ztLG1HrOmL/NDsiE/7yxaKLAIZyWB/rR9byvPeOCC8QnCd/08kmxNl/l7Akn6qlPwsVpKUUNsr0SkU9lShMAw4OBgQq399jsbkFSwIDAQAB";
$publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOhVAdUyxFpVNSyjRndMWEPAN9vJEetMzLbjF9DTn2lPVuRj/Mkwq9wCNhy+tdeX2lIn4K3EkONBvYJubBhxnYOoQuMchPW5vG7VnmpLjZ7TkpM2n9fcMu8u1GkLatLblDI4LTfvn3851+nhpnYlUVkjw5GAhH4XnEpveIjqDhzQIDAQAB";
// جسم الطلب
$body = [
"Key" => $publicKey,
"Secret" => $activationCode,
"Serial" => $serialNumber
];
//$bodyJson = json_encode($body, JSON_UNESCAPED_SLASHES);
$bodyJson = trim(stripslashes(json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_LINE_TERMINATORS)),'"');
//$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 1. توليد هاش SHA256 للـ JSON
//$bodyHash = hash('sha256', $bodyJson, true);
// 2. تحميل المفتاح الخاص للتوقيع
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem")); // تأكد من وجود هذا الملف بجانب السكربت
// 3. توقيع الهاش
openssl_sign($bodyJson, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// 4. تحويل التوقيع إلى Base64
$xSignature = base64_encode($signature);
// 5. إرسال الطلب
$headers = [
"Content-Type: application/json",
"Accept-Language: en",
"Request-Name: pos_web/pos/activate",
"Subject: $terminalId",
"X-Signature: $xSignature"
];
$ch = curl_init("https://cashmobile.mtnsyr.com:9000");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyJson);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ✅ النتيجة
header('Content-Type: application/json');
echo json_encode([
"httpCode" => $httpCode,
"response" => json_decode($response, true),
"sentBody" => $body,
]);

View File

@@ -1,247 +0,0 @@
<?php
// /v1/main/ride/mtn/passenger/confirm_payment.php
include "../../../connect.php";
header('Content-Type: application/json; charset=utf-8');
/**
* Helpers
*/
function mlog(string $msg) { error_log($msg); } // timestamp يضاف تلقائياً من PHP
// قاعدة URL للتطبيق (لمعالجة BASE_URL غير المعروفة)
if (!defined('BASE_URL')) {
$APP_BASE_URL = rtrim(getenv('APP_BASE_URL') ?: '', '/');
if ($APP_BASE_URL === '') {
$scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : 'https';
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
define('BASE_URL', $scheme . '://' . $host);
} else {
define('BASE_URL', $APP_BASE_URL);
}
}
try {
$baseUrl = rtrim(getenv('MTN_API_BASE_URL'), '/');
$terminalId = getenv('MTN_TERMINAL_ID');
$privateKeyPem = getenv('MTN_PRIVATE_KEY');
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem"));
$invoice = filterRequest('invoiceNumber');
$phone = filterRequest('phone');
$guid = filterRequest('guid');
$operationNumber = filterRequest('operationNumber');
$code = filterRequest('otp'); // الـ OTP
$lang = filterRequest("lang");
mlog("MTN Confirm: Start request for invoice={$invoice}, phone={$phone}, guid={$guid}, opNum={$operationNumber}");
if (!$invoice || !$phone || !$guid || !$operationNumber || !$code) {
mlog("MTN Confirm: Missing parameters");
printFailure("Missing parameters.");
exit;
}
// تشفير الكود (SHA256 ثم Base64)
$hashBin = hash('sha256', $code, true);
$codeB64 = base64_encode($hashBin);
// جسم الطلب نحو MTN
$body = [
'Invoice' => (int)$invoice,
'Phone' => $phone,
'Guid' => $guid,
'OperationNumber' => (int)$operationNumber,
'Code' => $codeB64,
'Accept-Language' => $lang
];
$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE);
mlog("MTN Confirm: Prepared body JSON: " . $bodyJson);
// توقيع الجسم
$sig = null;
$signResult = openssl_sign($bodyJson, $sig, $privateKey, OPENSSL_ALGO_SHA256);
if (!$signResult || !$sig) {
mlog("MTN Confirm: Failed to generate signature");
printFailure("Signature error.");
exit;
}
$xSignature = base64_encode($sig);
mlog("MTN Confirm: Generated signature");
// إرسال الطلب إلى MTN
$ch = curl_init("{$baseUrl}/pos_web/payment_phone/confirm");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $bodyJson,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Request-Name: pos_web/payment_phone/confirm",
"Subject: {$terminalId}",
"X-Signature: {$xSignature}"
],
CURLOPT_TIMEOUT => 25,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
mlog("MTN Confirm: HTTP {$httpCode} - Response: " . ($response ?? ''));
if ($curlError) {
mlog("MTN Confirm: cURL error - {$curlError}");
}
// فك JSON لرد MTN (حتى لو خطأ) لعرض سبب واضح
$mtn = json_decode($response ?: '{}', true);
if (!is_array($mtn)) {
$mtn = [];
}
// 🧠 سياسة القرار:
// - إذا HTTP≠200 → فشل شبكة/بوابة
// - إذا HTTP=200 لكن Errno≠0 → خطأ من MTN (مثل Incorrect sms code)
// - فقط إذا HTTP=200 && Errno=0 → نجاح، نحدّث DB ونضيف للمحافظ
if ($httpCode !== 200) {
// لا تحدّث DB
printFailure([
'message' => 'MTN confirm HTTP failure',
'http' => $httpCode,
'mtn' => $mtn
]);
exit;
}
// HTTP 200 — افحص Errno
$errno = isset($mtn['Errno']) ? (int)$mtn['Errno'] : null;
if ($errno !== 0) {
// لا تحدّث DB في هذه الحالة
$errText = isset($mtn['Error']) ? $mtn['Error'] : 'Unknown MTN error';
// اطبع لوج مشابه للمثال المطلوب
// مثال: {"Errno":662,"Error":"Incorrect sms code","Abuse":2,"Transaction":""}
mlog("MTN Confirm: Business failure from MTN - Errno={$errno}, Error=" . json_encode($mtn, JSON_UNESCAPED_UNICODE));
printFailure([
'message' => $errText,
'errno' => $errno,
'mtn' => $mtn
]);
exit;
}
// ✅ نجاح كامل من MTN — تحديث DB ثم المحافظ
try {
global $con;
$stmt = $con->prepare(
"UPDATE `paymentsLogSyria` SET status = 1, updated_at = NOW()
WHERE order_ref = :inv"
);
$stmt->execute([':inv' => $invoice]);
mlog("MTN Confirm: Payment updated successfully in DB for invoice={$invoice}");
$stmt = $con->prepare("SELECT * FROM paymentsLogSyria WHERE order_ref = :order_ref LIMIT 1");
$stmt->execute([':order_ref' => $invoice]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
mlog("MTN Confirm: Payment row not found after update");
printFailure("Payment row not found");
exit;
}
$userId = $payment['user_id'];
$amount = $payment['amount'];
$paymentMethod = $payment['payment_method'] ?? 'mtn';
$finalAmount = calculateBonus($amount);
$token = generatePaymentToken($userId, $finalAmount);
$walletResult = addToPassengerWallet($userId, $finalAmount, $token);
$seferToken = generatePaymentToken($userId, $amount);
$seferWalletResult = addToSeferWallet($userId, $amount, $paymentMethod, $seferToken);
// رجّع رد موحّد + ضمّن رد MTN
printSuccess([
'message' => 'MTN Confirm',
'data' => [
'invoice' => $invoice,
'finalAmount' => $finalAmount,
'wallet' => $walletResult,
'seferWallet' => $seferWalletResult,
'mtn' => $mtn
]
]);
exit;
} catch (PDOException $e) {
mlog("MTN Confirm: DB update error - " . $e->getMessage());
printFailure("DB error");
exit;
}
} catch (Throwable $e) {
mlog("MTN Confirm: Exception - " . $e->getMessage());
printFailure("Server error");
exit;
}
/**
* نفس دوال المساعدة، لكن باستعمال BASE_URL المؤمّنة أعلاه
*/
function calculateBonus($amount) {
if ($amount == 20000) return 20500;
if ($amount == 40000) return 42500;
if ($amount == 100000) return 104000;
return $amount;
}
function generatePaymentToken($passengerId, $amount) {
$url = rtrim(BASE_URL, '/') . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = ['passengerId' => $passengerId, 'amount' => $amount];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200 || !$response) return null;
$data = json_decode($response, true);
return $data['message'] ?? null;
}
function addToPassengerWallet($passengerId, $amount, $token) {
$url = rtrim(BASE_URL, '/') . "/passengerWallet/add.php";
$postData = ['passenger_id' => $passengerId, 'balance' => $amount, 'token' => $token];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200 || !$response) return null;
return json_decode($response, true);
}
function addToSeferWallet($passengerId, $amount, $paymentMethod, $token) {
$url = rtrim(BASE_URL, '/') . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $token,
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200 || !$response) return null;
return json_decode($response, true);
}

View File

@@ -1,130 +0,0 @@
<?php
include "../../../connect.php";
date_default_timezone_set("Asia/Damascus");
// ========== إعدادات MTN ==========
$terminalId = "9001000000060863";
$currencyCode = 760;
$sessionNumber = 0;
$ttl = 15;
// ====== استقبال البيانات من فلاتر ======
$amount = filterRequest("amount");
$passengerId = filterRequest("passengerId");
$phone = filterRequest("phone");
$lang = filterRequest("lang");
// ✅ Log مبدئي
error_log("🚦 START | passengerId: $passengerId | phone: $phone | amount: $amount");
// تحقق من المدخلات
if (empty($amount) || empty($passengerId) || empty($phone) || $amount <= 0) {
error_log("❌ Invalid input: amount=$amount, passengerId=$passengerId, phone=$phone");
printFailure("بيانات الدفع غير كاملة أو غير صالحة.");
exit;
}
// ====== توليد invoiceNumber و GUID ======
$invoiceNumber = mt_rand(10000000000, 99999999999);
//$invoiceNumber = "MTN_" . $passengerId . "_" . time();
$guid = uniqid("mtn_");
error_log("🧾 Generated Invoice: $invoiceNumber");
error_log("🧭 Generated GUID: $guid");
// ====== 1. إنشاء الفاتورة ======
$createInvoiceBody = [
"Amount" => intval($amount * 100),
"Invoice" => $invoiceNumber,
"Session" => $sessionNumber,
"TTL" => $ttl
];
error_log("📦 Create Invoice Body: " . json_encode($createInvoiceBody, JSON_UNESCAPED_UNICODE));
$invoiceResponse = sendMtnApiRequest("pos_web/invoice/create", $terminalId, $createInvoiceBody);
error_log("📥 Create Invoice Response: " . json_encode($invoiceResponse, JSON_UNESCAPED_UNICODE));
if (!$invoiceResponse || isset($invoiceResponse['Errno']) && $invoiceResponse['Errno'] != 0) {
error_log("❌ Failed to create invoice. Error: " . json_encode($invoiceResponse));
printFailure("فشل إنشاء الفاتورة عبر MTN.");
exit;
}
// ====== 2. بدء الدفع ======
$initiateBody = [
"Invoice" => $invoiceNumber,
"Phone" => $phone,
"Guid" => $guid
];
error_log("📤 body initiateBody: $initiateBody");
error_log("📦 Initiate Payment Body: " . json_encode($initiateBody, JSON_UNESCAPED_UNICODE));
$initiateResponse = sendMtnApiRequest("pos_web/payment_phone/initiate", $terminalId, $initiateBody);
error_log("📥 Initiate Response: " . json_encode($initiateResponse, JSON_UNESCAPED_UNICODE));
if (!$initiateResponse || !isset($initiateResponse['OperationNumber'])) {
error_log("❌ Failed to initiate payment.");
printFailure($initiateResponse);
exit;
}
$operationNumber = $initiateResponse['OperationNumber'];
// ====== 3. تسجيل العملية ======
try {
$stmt = $con->prepare("INSERT INTO `paymentsLogSyria`
(`user_id`, `amount`, `status`, `order_ref`, `payment_method`, `created_at`)
VALUES (?, ?, 2, ?, 'mtn', NOW())");
$stmt->execute([$passengerId, $amount, $invoiceNumber]);
error_log("✅ DB Log Inserted.");
} catch (PDOException $e) {
error_log("❌ DB ERROR: " . $e->getMessage());
printFailure("فشل في تسجيل العملية.");
exit;
}
// ====== 4. نجاح
error_log("✅ Payment initiation successful.");
printSuccess([
"invoiceNumber" => $invoiceNumber,
"operationNumber" => $operationNumber,
"guid" => $guid
]);
// ====== دالة إرسال الطلب =====================
function sendMtnApiRequest($requestName, $terminalId, $body)
{
$apiUrl = "https://cashmobile.mtnsyr.com:9000";
$privateKey = openssl_pkey_get_private(file_get_contents("private_key.pem"));
// ✅ تحويل الـ body إلى JSON بدون فراغات أو أسطر
$bodyJson = trim(stripslashes(json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_LINE_TERMINATORS)), '"');
//$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// ✅ توليد التوقيع
// $bodyHash = hash('sha256', $bodyJson, true);
error_log("📤 body before JSON: $bodyJson");
openssl_sign($bodyJson, $signature, $privateKey, OPENSSL_ALGO_SHA256);
$xSignature = base64_encode($signature);
error_log("📤 body xSignature: $xSignature");
// ✅ رؤوس الطلب
$headers = [
"Content-Type: application/json",
"Accept-Language: $lang",
"Request-Name: $requestName",
"Subject: $terminalId",
"X-Signature: $xSignature"
];
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyJson);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// ✅ لوق داخلي
error_log("🔐 Signature for $requestName: $xSignature");
error_log("📤 Sent JSON: $bodyJson");
curl_close($ch);
return json_decode($response, true);
}

View File

@@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDOhVAdUyxFpVNSyjRndMWEPAN9vJEetMzLbjF9DTn2lPVuRj/M
kwq9wCNhy+tdeX2lIn4K3EkONBvYJubBhxnYOoQuMchPW5vG7VnmpLjZ7TkpM2n9
fcMu8u1GkLatLblDI4LTfvn3851+nhpnYlUVkjw5GAhH4XnEpveIjqDhzQIDAQAB
AoGBALRcAvqJT8nHN7y+8QNFHNZ+XwIpc4egmJY1Ny0iJvPtZWaYHVG5PRE4Qu4+
29+3oX5dYDx146tu4L5mQvLS3ULBsvxaUZt2lT/vxkQzI9pNfXw584WvIrbtxQod
ILvBcnamwQa9hEOIFZVyZ/hzkzUcMO6cAXqvsfqqPgJhm7PBAkEA+xgE9CUOLDFl
vLePQKGcHIUOsPLr16qNEgGhTW7Km3OMMqoB2f7t67xOHGqK6tnANRM4Sk6IModI
wbZuVh4jMQJBANKOVmIdDLNffZVHp90SDRG7/YdK2R5ob361CIkcUzjh927Wfs5W
A/WroB7eJ7pWiq2BMaj/xq65nYaCOldvaV0CQQDm12c+eY61DFjnDa6ykaEvCxi9
jydJp+93vW3o/VFhZvJeZbO8EcX0MrNxJnY+gSBW6yuWDOrj4UH/bVO08pIRAkEA
lH3TiBAqo9nlTEEjrnILi4VD0IVFx/8pGnf71A6I1qXuBVn6RfQ9iKWIIBzWccCU
vrZNWn1AFntLD9CJ6p3k9QJBAMbSQ9CoXWlOLJRduV15ER1ZyE/inVd4jIvtjAgz
b7QaM62Ecxl3D8EI/LTSZV9Oa8D/62cJeMsflVa7gpavL70=
-----END RSA PRIVATE KEY-----

View File

@@ -1,6 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDqBQZEJXWCQwPsPzBM70M3TjyU
5vwCZWoEtUomR9Qu+dEQaa0Hniz6JY8+goCxfMYuZQw6+kimctA2KqzT2pCsJufN
b92pSAMZgb0RSTl2y62oJkJd2WY7dj36AvPEyw6DxCFItvFOu7HGl3LlHQBriiw3
jwtuS6DO7gbmAJPU8wIDAQAB
-----END PUBLIC KEY-----

View File

@@ -13,7 +13,7 @@ header('Content-Type: application/json');
$expectedToken = trim(file_get_contents('/home/intaleq-wallet/.mtnKey')); // يجب استبداله بتوكن حقيقي
$receivedToken = $_SERVER['HTTP_X_AUTH_TOKEN'] ?? '';
if ($receivedToken !== $expectedToken) {
if (!hash_equals($expectedToken, $receivedToken)) {
http_response_code(401); // Unauthorized
echo json_encode(["status" => "error", "message" => "Authentication failed."]);
exit;

View File

@@ -6,28 +6,39 @@ $balance = filterRequest("balance");
$token = filterRequest("token");
// Retrieve token details from the database
$stmt = $con->prepare("SELECT * FROM payment_tokens_passenger WHERE token = :token AND isUsed = FALSE");
$stmt->execute([':token' => $token]);
try {
$con->beginTransaction();
$tokenData = $stmt->fetch();
// Retrieve token details from the database securely and lock the row
$stmt = $con->prepare("SELECT * FROM payment_tokens_passenger WHERE token = :token AND isUsed = FALSE FOR UPDATE");
$stmt->execute([':token' => $token]);
$tokenData = $stmt->fetch();
if ($tokenData) {
// Insert into passengerWallet securely using prepared statements
$sql = "INSERT INTO `passengerWallet` (`passenger_id`, `balance`) VALUES (:passenger_id, :balance)";
$stmt = $con->prepare($sql);
$stmt->execute([':passenger_id' => $passenger_id, ':balance' => $balance]);
if ($tokenData) {
// Insert into passengerWallet securely using prepared statements
$sql = "INSERT INTO `passengerWallet` (`passenger_id`, `balance`) VALUES (:passenger_id, :balance)";
$stmtInsert = $con->prepare($sql);
$stmtInsert->execute([':passenger_id' => $passenger_id, ':balance' => $balance]);
if ($stmt->rowCount() > 0) {
// Mark the token as used
$updateTokenStmt = $con->prepare("UPDATE payment_tokens_passenger SET isUsed = TRUE WHERE token = :token");
$updateTokenStmt->execute([':token' => $token]);
printSuccess("Wallet record created successfully");
if ($stmtInsert->rowCount() > 0) {
// Mark the token as used
$updateTokenStmt = $con->prepare("UPDATE payment_tokens_passenger SET isUsed = TRUE WHERE id = :tokenID");
$updateTokenStmt->execute([':tokenID' => $tokenData['id']]);
$con->commit();
printSuccess("Wallet record created successfully");
} else {
$con->rollBack();
printFailure("Failed to create wallet record");
}
} else {
printFailure("Failed to create wallet record");
$con->rollBack();
printFailure("Invalid or already used token");
}
} else {
printFailure("Invalid or already used token");
} catch (Exception $e) {
if ($con->inTransaction()) {
$con->rollBack();
}
printFailure("Database error: " . $e->getMessage());
}
?>

View File

@@ -1,100 +0,0 @@
<?php
include "../../connect.php";
// 1. احصل على AUTH TOKEN
$api_key = getenv("payMobApiKey1"); // ضع API Key الخاص بك هنا
$email= filterRequest("amount");
$first_name= filterRequest("first_name");
$last_name= filterRequest("last_name");
$phone_number= filterRequest("phone_number");
$amount= filterRequest("amount");
$auth_url = "https://accept.paymob.com/api/auth/tokens";
$auth_data = json_encode(["api_key" => $api_key]);
$response = callAPI("POST", $auth_url, $auth_data);
// printResponse("AUTH TOKEN RESPONSE", $response);
$auth_token = $response->token ?? null;
if (!$auth_token) {
die("❌ فشل الحصول على AUTH TOKEN!");
}
// $amount=$amount*100;
// 2. أنشئ الطلب ORDER
$order_url = "https://accept.paymob.com/api/ecommerce/orders";
$order_data = [
"auth_token" => $auth_token,
"delivery_needed" => false,
"amount_cents" => $amount,
"currency" => "EGP",
"merchant_order_id" => uniqid(),
"items" => []
];
$response = callAPI("POST", $order_url, json_encode($order_data));
// printResponse("ORDER RESPONSE", $response);
$order_id = $response->id ?? null;
if (!$order_id) {
die("❌ فشل إنشاء الطلب!");
}
$integration_id=getenv("paymobIntegratedIdCard");
// 3. احصل على Payment Key
$payment_key_url = "https://accept.paymob.com/api/acceptance/payment_keys";
$payment_key_data = [
"auth_token" => $auth_token,
"amount_cents" => $amount,
"expiration" => 3600,
"order_id" => $order_id,
"billing_data" => [
"first_name" =>$first_name,
"last_name" => $last_name,
"email" => $email,
"phone_number" => $phone_number,
"country" => "EG",
"city" => "Cairo",
"state" => "shobra",
"street" => "Test St.",
"building" => "1",
"apartment" => "10",
"floor" => "2",
"postal_code" => "12345",
"shipping_method"=> 'card'
],
"currency" => "EGP",
"integration_id" => $integration_id, // ضع الـ Integration ID الصحيح
];
$response = callAPI("POST", $payment_key_url, json_encode($payment_key_data));
// printResponse("PAYMENT TOKEN RESPONSE", $response);
$payment_token = $response->token ?? null;
if (!$payment_token) {
die("❌ فشل الحصول على PAYMENT TOKEN!");
}
// 4. إنشاء IFRAME URL
$iframe_id = "837992"; // ضع الـ Iframe ID الصحيح
$iframe_url = "https://accept.paymob.com/api/acceptance/iframes/$iframe_id?payment_token=$payment_token";
if($payment_token){
printSuccess($iframe_url);
}
// دالة لطلب API عبر CURL
function callAPI($method, $url, $data)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"]
]);
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response);
}

View File

@@ -1,358 +0,0 @@
<?php
include "../../connect.php";
define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride");
define("LOG_FILE", "../logs/payment_verification.log"); // Define log file path
// Function to write to error log
function logError($step, $message, $data = null) {
$timestamp = date('Y-m-d H:i:s');
$logEntry = "[{$timestamp}] STEP {$step}: {$message}";
if ($data !== null) {
$logEntry .= " | Data: " . json_encode($data);
}
// Ensure log directory exists
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
// Append to log file
file_put_contents(LOG_FILE, $logEntry . PHP_EOL, FILE_APPEND);
// Also log to PHP error log for server monitoring
// error_log("PAYMENT_VERIFICATION: {$logEntry}");
}
// Receive parameters from GET request
$user_id = filterRequest("user_id");
$passengerId = filterRequest("passengerId");
$paymentMethod = filterRequest("paymentMethod");
// Log initial request
// logError("0", "Request received", [
// "user_id" => $user_id,
// "passengerId" => $passengerId
// ]);
// Validate user_id and passengerId
if (!$user_id || !$passengerId) {
// logError("1", "Invalid parameters", [
// "user_id" => $user_id,
// "passengerId" => $passengerId
// ]);
printFailure("Invalid user ID or passenger ID.");
exit;
}
try {
// Step 1: Get the latest successful payment
// logError("1", "Querying latest payment", ["user_id" => $user_id]);
$stmt = $con->prepare("SELECT * FROM paymentsLog WHERE user_id = :user_id AND created_at >= DATE_SUB(NOW(), INTERVAL 2 MINUTE)
ORDER BY created_at DESC
LIMIT 1");
$stmt->bindParam(':user_id', $user_id, PDO::PARAM_STR);
$stmt->execute();
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
logError("1", "No payment found", ["user_id" => $user_id]);
printFailure("No payment data found.");
exit;
}
// logError("1", "Payment found", [
// "payment_id" => $payment['id'] ?? 'unknown',
// "status" => $payment['status'],
// "amount" => $payment['amount']/100 ?? 'unknown'
// ]);
// Step 2: Check payment status
if ($payment['status'] != 1) {
// logError("2", "Payment not successful", ["status" => $payment['status']]);
printFailure("Payment is not successful yet.");
exit;
}
// logError("2", "Payment status verified", ["status" => $payment['status']]);
$amount = $payment['amount']/100; // Paid amount
// Step 3: Calculate bonus based on the paid amount
// logError("3", "Calculating bonus", ["amount" => $amount]);
$finalAmount = calculateBonus($amount);
if ($finalAmount <= 0) {
// logError("3", "Bonus calculation failed", [
// "original_amount" => $amount,
// "calculated_amount" => $finalAmount
// ]);
printFailure("Invalid amount for bonus calculation.");
exit;
}
// logError("3", "Bonus calculated", [
// "original_amount" => $amount,
// "final_amount" => $finalAmount
// ]);
// // Step 4: Generate payment token
// logError("4", "Generating payment token", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount
// ]);
$token = generatePaymentToken($passengerId, $finalAmount);
if (!$token) {
// logError("4", "Token generation failed");
printFailure("Payment verified, but failed to generate token.");
exit;
}
// logError("4", "Token generated successfully", ["token_length" => strlen($token)]);
// // Step 5: Add balance to passenger's wallet
// logError("5", "Adding balance to passenger wallet", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount
// ]);
$walletResult = addToPassengerWallet($passengerId, $finalAmount, $token);
if (!$walletResult || !isset($walletResult['status']) || $walletResult['status'] != "success") {
// logError("5", "Failed to add balance to passenger wallet", $walletResult);
printFailure("Payment verified, but failed to add balance to passenger wallet.");
exit;
}
// logError("5", "Balance added to passenger wallet", $walletResult);
// Step 6: Add balance to Sefer wallet
// logError("6", "Adding balance to Sefer wallet", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount,
// "paymentMethod" => $paymentMethod
// ]);
$token = generatePaymentToken($passengerId, $finalAmount);
if (!$token) {
// logError("4", "Token generation failed");
printFailure("Payment verified, but failed to generate token.");
exit;
}
// logError("4", "Token generated successfully", ["token_length" => strlen($token)]);
$seferWalletResult = addToSeferWallet($passengerId, $amount, $paymentMethod);
if (!$seferWalletResult || !isset($seferWalletResult['status']) || $seferWalletResult['status'] != "success") {
// logError("6", "Failed to add balance to Sefer wallet", $seferWalletResult);
printFailure("Payment verified, but failed to add balance to Sefer wallet.");
exit;
}
// logError("6", "Balance added to Sefer wallet", $seferWalletResult);
// // Final success
// logError("7", "Process completed successfully", [
// "payment_id" => $payment['id'] ?? 'unknown',
// "amount" => $finalAmount,
// "passengerId" => $passengerId
// ]);
printSuccess( "Payment data saved successfully");
} catch (PDOException $e) {
logError("ERROR", "Database error: " . $e->getMessage());
printFailure("Database error occurred.");
} catch (Exception $e) {
logError("ERROR", "General error: " . $e->getMessage());
printFailure("An error occurred during payment verification.");
}
// 🎯 Function to generate payment token with error logging
function generatePaymentToken($passengerId, $amount) {
$url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = [
'passengerId' => $passengerId,
'amount' => $amount
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("4.1", "cURL error in token generation", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("4.2", "HTTP error in token generation", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data || !isset($data['message'])) {
logError("4.3", "Invalid response format in token generation", [
"response" => $response
]);
return null;
}
return $data['message']; // ✅ Return token
}
// 🎯 Function to add balance to passenger's wallet with error logging
function addToPassengerWallet($passengerId, $amount, $token) {
$url = BASE_URL . "/passengerWallet/add.php";
$postData = [
'passenger_id' => $passengerId,
'balance' => $amount,
'token' => $token
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("5.1", "cURL error in passenger wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("5.2", "HTTP error in passenger wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("5.3", "Invalid response format in passenger wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to add balance to Sefer wallet with error logging
function addToSeferWallet($passengerId, $amount, $paymentMethod) {
// Generate a new token specifically for the Sefer wallet
$seferToken = generatePaymentToken($passengerId, $amount);
if (!$seferToken) {
logError("6.0.1", "Failed to generate Sefer token");
return null;
}
logError("6.0.2", "Generated new Sefer token", [
"token_length" => ($seferToken)
]);
$url = BASE_URL . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $seferToken, // Use the new Sefer-specific token
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("6.1", "cURL error in Sefer wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("6.2", "HTTP error in Sefer wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("6.3", "Invalid response format in Sefer wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to calculate bonus
function calculateBonus($amount) {
logError("3.1", "Bonus calculation input", ["amount" => $amount]);
$result = 0;
if ($amount == 100) $result = 100;
else if ($amount == 200) $result = 215;
else if ($amount == 400) $result = 450;
else if ($amount == 1000) $result = 1140;
logError("3.2", "Bonus calculation result", [
"input" => $amount,
"output" => $result
]);
return $result;
}
?>

View File

@@ -1,100 +0,0 @@
<?php
include "../../../connect.php";
// 1. احصل على AUTH TOKEN
$api_key = getenv("payMobApiKey1"); // ضع API Key الخاص بك هنا
$email= filterRequest("amount");
$first_name= filterRequest("first_name");
$last_name= filterRequest("last_name");
$phone_number= filterRequest("phone_number");
$amount= filterRequest("amount");
$auth_url = "https://accept.paymob.com/api/auth/tokens";
$auth_data = json_encode(["api_key" => $api_key]);
$response = callAPI("POST", $auth_url, $auth_data);
// printResponse("AUTH TOKEN RESPONSE", $response);
$auth_token = $response->token ?? null;
if (!$auth_token) {
die("❌ فشل الحصول على AUTH TOKEN!");
}
$amount=$amount*100;
// 2. أنشئ الطلب ORDER
$order_url = "https://accept.paymob.com/api/ecommerce/orders";
$order_data = [
"auth_token" => $auth_token,
"delivery_needed" => false,
"amount_cents" => $amount,
"currency" => "EGP",
"merchant_order_id" => uniqid(),
"items" => []
];
$response = callAPI("POST", $order_url, json_encode($order_data));
// printResponse("ORDER RESPONSE", $response);
$order_id = $response->id ?? null;
if (!$order_id) {
die("❌ فشل إنشاء الطلب!");
}
$integration_id=getenv("paymobIntegratedIdCardDriver");
// 3. احصل على Payment Key
$payment_key_url = "https://accept.paymob.com/api/acceptance/payment_keys";
$payment_key_data = [
"auth_token" => $auth_token,
"amount_cents" => $amount,
"expiration" => 3600,
"order_id" => $order_id,
"billing_data" => [
"first_name" =>$first_name,
"last_name" => $last_name,
"email" => $email,
"phone_number" => $phone_number,
"country" => "EG",
"city" => "Cairo",
"state" => "shobra",
"street" => "Test St.",
"building" => "1",
"apartment" => "10",
"floor" => "2",
"postal_code" => "12345",
"shipping_method"=> 'card'
],
"currency" => "EGP",
"integration_id" => $integration_id, // ضع الـ Integration ID الصحيح
];
$response = callAPI("POST", $payment_key_url, json_encode($payment_key_data));
// printResponse("PAYMENT TOKEN RESPONSE", $response);
$payment_token = $response->token ?? null;
if (!$payment_token) {
die("❌ فشل الحصول على PAYMENT TOKEN!");
}
// 4. إنشاء IFRAME URL
$iframe_id = "837992"; // ضع الـ Iframe ID الصحيح
$iframe_url = "https://accept.paymob.com/api/acceptance/iframes/$iframe_id?payment_token=$payment_token";
if($payment_token){
printSuccess($iframe_url);
}
// دالة لطلب API عبر CURL
function callAPI($method, $url, $data)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"]
]);
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response);
}

View File

@@ -1,118 +0,0 @@
<?php
include "../../../connect.php";
// 1⃣ AUTH TOKEN
$api_key = getenv("payMobApiKey1");
$integration_id = getenv("paymobIntegratedIdDriverWallet"); // 🔁 تأكد أنه خاص بالسائق
$email = filterRequest("email");
$first_name = filterRequest("first_name");
$last_name = filterRequest("last_name");
$phone_number = filterRequest("phone_number"); // هاتف السائق
$wallet_phone = '+2'.$phone_number;
$amount = filterRequest("amount");
$auth_url = "https://accept.paymob.com/api/auth/tokens";
$auth_data = json_encode(["api_key" => $api_key]);
$response = callAPI("POST", $auth_url, $auth_data);
$auth_token = $response->token ?? null;
if (!$auth_token) {
error_log("❌ AUTH TOKEN retrieval failed!");
die("❌ AUTH TOKEN retrieval failed!");
}
$amount=$amount*100;
// 2⃣ ORDER CREATE
$order_url = "https://accept.paymob.com/api/ecommerce/orders";
$order_data = [
"auth_token" => $auth_token,
"delivery_needed" => false,
"amount_cents" => $amount,
"currency" => "EGP",
"merchant_order_id" => uniqid("DRV_"),
"items" => []
];
$response = callAPI("POST", $order_url, json_encode($order_data));
$order_id = $response->id ?? null;
if (!$order_id) {
error_log("❌ Failed to create order for driver wallet!");
die("❌ Failed to create order for driver wallet!");
}
// 3⃣ PAYMENT KEY
$payment_key_url = "https://accept.paymob.com/api/acceptance/payment_keys";
$payment_key_data = [
"auth_token" => $auth_token,
"amount_cents" => $amount,
"expiration" => 3600,
"order_id" => $order_id,
"billing_data" => [
"first_name" => $first_name,
"last_name" => $last_name,
"email" => $email,
"phone_number" => $phone_number,
"country" => "EG",
"city" => "Cairo",
"state" => "Nasr City",
"street" => "Driver Zone",
"building" => "5",
"apartment" => "D1",
"floor" => "1",
"postal_code" => "11765",
"shipping_method" => "driver_wallet"
],
"currency" => "EGP",
"integration_id" => $integration_id
];
$response = callAPI("POST", $payment_key_url, json_encode($payment_key_data));
$payment_token = $response->token ?? null;
if (!$payment_token) {
error_log("❌ Failed to get PAYMENT TOKEN for driver!");
die("❌ Failed to get PAYMENT TOKEN for driver!");
}
// 4⃣ Final Step: Pay with Wallet
$redirect_url = payWithWallet($payment_token, $wallet_phone);
if ($redirect_url) {
printSuccess($redirect_url);
error_log("✅ redirect_url (driver): " . $redirect_url);
} else {
error_log("❌ Driver wallet payment failed!");
printFailure("Payment verified, but failed to redirect.");
}
// 🔁 Shared helper functions
function callAPI($method, $url, $data)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"]
]);
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response);
}
function payWithWallet($paymentToken, $walletPhone)
{
$url = "https://accept.paymob.com/api/acceptance/payments/pay";
$data = [
"source" => [
"identifier" => $walletPhone,
"subtype" => "WALLET"
],
"payment_token" => $paymentToken
];
$response = callAPI("POST", $url, json_encode($data));
return $response->redirect_url ?? null;
}

View File

@@ -1,146 +0,0 @@
<?php
include "../../../connect.php";
define('BASE_URL', 'https://wl.tripz-egypt.com/v1/main/ride');
try {
$driverId = filterRequest('driverID');
$user_id = filterRequest('user_id');
$paymentMethod = filterRequest('paymentMethod');
if (empty($user_id) || empty($driverId)) {
printFailure('Missing user_id or driverID.');
exit;
}
// 1⃣ تحقق من سجل الدفع خلال آخر دقيقتين
$stmt = $con->prepare(
'SELECT * FROM payment_log_driver
WHERE user_id = :uid
AND created_at >= DATE_SUB(NOW(), INTERVAL 2 MINUTE)
ORDER BY created_at DESC LIMIT 1'
);
$stmt->execute([':uid' => $user_id]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment || $payment['status'] != 1) {
printFailure('No valid payment found.');
exit;
}
$originalAmount = floatval($payment['amount']);
$bonus = match ((int)$originalAmount) {
80 => 80.0,
200 => 215.0,
400 => 450.0,
1000 => 1140.0,
default => $originalAmount,
};
// 2⃣ توكن لـ DriverWallet
$tokenDriver = generateToken($con, $driverId, $bonus);
if (!$tokenDriver) {
printFailure('Failed to generate token for driver wallet.');
exit;
}
// 3⃣ توكن مستقل لـ SeferWallet
$tokenSefer = generateToken($con, $driverId, $originalAmount);
if (!$tokenSefer) {
printFailure('Failed to generate token for sefer wallet.');
exit;
}
// 4⃣ Payment ID
$paymentID = generatePaymentID($con, $driverId, $bonus, $paymentMethod);
if (!$paymentID) {
printFailure('Failed to generate payment ID.');
exit;
}
// 5⃣ Insert into driverWallet
$insertDriver = $con->prepare("INSERT INTO driverWallet (driverID, paymentID, amount, paymentMethod) VALUES (:driverID, :paymentID, :amount, :paymentMethod)");
$insertDriver->execute([
':driverID' => $driverId,
':paymentID' => $paymentID,
':amount' => $bonus,
':paymentMethod' => $paymentMethod
]);
if ($insertDriver->rowCount() === 0) {
printFailure('Failed to insert into driverWallet.');
exit;
}
// 6⃣ Update tokenDriver to isUsed = TRUE
$markTokenDriver = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token");
$markTokenDriver->execute([':token' => $tokenDriver]);
// 7⃣ Insert into 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
]);
// 8⃣ Update tokenSefer to isUsed = TRUE
$markTokenSefer = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token");
$markTokenSefer->execute([':token' => $tokenSefer]);
// 🎉 Success response
printSuccess([
'message' => 'Payment verified and all wallets updated successfully.',
'amount' => $originalAmount,
'bonus' => $bonus,
'paymentID' => $paymentID,
'tokenUsed' => [
'driverWalletToken' => $tokenDriver,
'seferWalletToken' => $tokenSefer
]
]);
} catch (Throwable $e) {
printFailure("Server error: " . $e->getMessage());
}
// ───────────────────────────
// FUNCTIONS
// ───────────────────────────
function generateToken($con, $driverId, $amount): ?string {
global $secretKey;
// نفس المنطق من سكربتك
$data = $driverId . $amount . time();
$data .= $secretKey;
$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;
}
function generatePaymentID($con, $driverId, $amount, $method): ?string {
$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;
}

View File

@@ -1,110 +0,0 @@
<?php
// paymob_payout.php
// سكريبت بي ات بي لمعاملات Paymob Payout (محفظة وبنك) بدون تخزين في قاعدة البيانات
declare(strict_types=1);
include '../../../connect.php'; // يعطيك $con، filterRequest(), printSuccess(), printFailure()
// 1) جلب باراميترات الطلب عبر filterRequest
$driverId = filterRequest('driverID');
$amount = filterRequest('amount');
$method = filterRequest('method'); // 'wallet' أو 'bank'
$msisdn = filterRequest('msisdn');
$bankCard = filterRequest('bankCard'); // يُستعمل عند method == 'bank'
$bankCode = filterRequest('bankCode'); // يُستعمل عند method == 'bank'
if (empty($driverId) || empty($amount) || empty($method)) {
printFailure('Missing parameters');
exit;
}
// 2) جلب بيانات Paymob من البيئة (Environment Variables)
$pmUser = getenv('payMobOutUserName');
$pmPass = getenv('payMobOutPassword');
$pmClientId = getenv('PAYMOBOUTCLIENT_ID'); // من static const pmobid
$pmSecret = getenv('PAYMOBOUTCLIENTSECRET'); // من static const pmobsec
// 3) دالة للحصول على OAuth Token من Paymob
function fetchPaymobToken(string $user, string $pass, string $cid, string $secret): ?string {
$ch = curl_init('https://payouts.paymobsolutions.com/api/secure/o/token/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'password',
'username' => $user,
'password' => $pass,
'client_id' => $cid,
'client_secret' => $secret,
]),
]);
$resp = curl_exec($ch);
if (!$resp) return null;
$data = json_decode($resp, true);
return $data['access_token'] ?? null;
}
$oauthToken = fetchPaymobToken($pmUser, $pmPass, $pmClientId, $pmSecret);
if (!$oauthToken) {
printFailure('Failed to retrieve Paymob token');
exit;
}
// 4) دوال صرف الأموال
function disburseWallet(string $token, string $amt, string $msisdn): array {
$ch = curl_init('https://payouts.paymobsolutions.com/api/secure/disburse/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => $amt,
'issuer' => 'wallet',
'msisdn' => $msisdn,
]),
]);
$resp = curl_exec($ch);
return $resp ? json_decode($resp, true) : [];
}
function disburseBank(string $token, string $amt, string $card, string $code): array {
$ch = curl_init('https://payouts.paymobsolutions.com/api/secure/disburse/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => $amt,
'issuer' => 'bank_card',
'bank_card_number' => $card,
'bank_code' => $code,
'bank_transaction_type' => 'cash_transfer',
]),
]);
$resp = curl_exec($ch);
return $resp ? json_decode($resp, true) : [];
}
// 5) استدعاء الدالة المناسبة وتنفيذ الصرف
if ($method === 'wallet') {
$result = disburseWallet($oauthToken, $amount, $msisdn);
} else {
$result = disburseBank($oauthToken, $amount, $bankCard, $bankCode);
}
// 6) التحقق من نجاح الصرف وإرجاع النتيجة
if (empty($result) || ($result['disbursement_status'] ?? '') !== 'successful') {
printFailure('Disbursement failed');
exit;
}
// 7) إرجاع التوكن والنتيجة للعميل بدون تخزين في DB
printSuccess( $result);
?>

View File

@@ -1,142 +0,0 @@
<?php
include "../../../jwtconnect.php";
// ------------------------------
// قراءة HMAC من الهيدر أو من الـ query
// ------------------------------
$received_hmac = $_SERVER['HTTP_HMAC'] ?? ($_GET['hmac'] ?? '');
$received_hmac = trim($received_hmac);
// ------------------------------
// قراءة البيانات القادمة من Paymob
// ------------------------------
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// ------------------------------
// المفتاح السري
// ------------------------------
$secret_key = getenv('hmacPaymob');
// ------------------------------
// دالة لتحويل القيم إلى النصوص
// ------------------------------
function normalize($value) {
if ($value === true) return 'true';
if ($value === false) return 'false';
if (is_null($value)) return '';
return (string)$value;
}
// ------------------------------
// التحقق من صحة HMAC
// ------------------------------
function isValidHmac($data, $secret_key, $received_hmac) {
if (!isset($data['obj'])) return false;
$obj = $data['obj'];
// دمج جميع الحقول بشكل متسلسل
$fields = [
normalize($obj['amount_cents'] ?? ''),
normalize($obj['created_at'] ?? ''),
normalize($obj['currency'] ?? ''),
normalize($obj['error_occured'] ?? false),
normalize($obj['has_parent_transaction'] ?? false),
normalize($obj['id'] ?? ''),
normalize($obj['integration_id'] ?? ''),
normalize($obj['is_3d_secure'] ?? false),
normalize($obj['is_auth'] ?? false),
normalize($obj['is_capture'] ?? false),
normalize($obj['is_refunded'] ?? false),
normalize($obj['is_standalone_payment'] ?? false),
normalize($obj['is_voided'] ?? false),
normalize($obj['order']['id'] ?? ''),
normalize($obj['owner'] ?? ''),
normalize($obj['pending'] ?? false),
normalize($obj['source_data']['pan'] ?? ''),
normalize($obj['source_data']['sub_type'] ?? ''),
normalize($obj['source_data']['type'] ?? ''),
normalize($obj['success'] ?? false)
];
// دمج الحقول في رسالة واحدة
$message = implode('', $fields);
// حساب HMAC باستخدام المفتاح السري
$calculated_hmac = hash_hmac('sha512', $message, $secret_key);
//
/*طباعة الرسائل لأغراض التصحيح
error_log("🔐 Message used for HMAC: " . $message);
error_log("🔐 Calculated HMAC: " . $calculated_hmac);
error_log("📩 Received HMAC: " . $received_hmac);
error_log("Calculated HMAC length: " . strlen($calculated_hmac));
error_log("Received HMAC length: " . strlen($received_hmac));
*/
// التحقق من تطابق HMAC
if (hash_equals($calculated_hmac, $received_hmac)) {
error_log("✅ Valid HMAC signature verified.");
return $calculated_hmac;
} else {
http_response_code(401);
echo json_encode(["error" => "Unauthorized Invalid HMAC"]);
exit;
}
}
isValidHmac($data, $secret_key, $received_hmac);
// ------------------------------
// إذا كانت HMAC صحيحة، نتابع العملية
// ------------------------------
if ($data && isset($data['obj'])) {
$transaction = $data['obj'];
$payment_id = $transaction['id'] ?? null;
$amount = $transaction['amount_cents'] ?? 0;
$status = $transaction['success'] ?? false;
$is_voided = $transaction['is_voided'] ?? false;
$is_refunded = $transaction['is_refunded'] ?? false;
$order_id = $transaction['order']['id'] ?? null;
$merchant_order_id = $transaction['order']['merchant_order_id'] ?? null;
$payment_method = $transaction['source_data']['type'] ?? 'unknown';
$card_last4 = $transaction['source_data']['pan'] ?? '****';
$transaction_type = $transaction['data']['migs_transaction']['type'] ?? 'UNKNOWN';
$created_at = $transaction['created_at'] ?? date("Y-m-d H:i:s");
$user_id = $transaction['order']['shipping_data']['phone_number'];
$user_id='+2'. $user_id;
$amount=$amount/100;
// التحقق من حالة الدفع
if (!$status) {
error_log("❌ Invalid payment status: " . $status);
echo json_encode(["error" => "Invalid payment status"]);
exit;
}
// إضافة البيانات إلى قاعدة البيانات
$query = "INSERT INTO payment_log_driver (`payment_id`, `user_id`, `amount`, `status`)
VALUES (:payment_id, :user_id, :amount, :status)";
$stmt = $con->prepare($query);
$stmt->bindParam(':payment_id', $payment_id);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':amount', $amount);
$stmt->bindParam(':status', $status);
try {
$stmt->execute();
if ($stmt->rowCount() > 0) {
http_response_code(200);
echo json_encode(["success" => true, "message" => "Payment data saved successfully"]);
error_log("Payment data saved successfully" . $status);
} else {
http_response_code(200);
echo json_encode(["success" => false, "message" => "Payment data already up to date."]);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(["error" => "Failed to execute the query: " . $e->getMessage()]);
}
}
?>

View File

@@ -1,142 +0,0 @@
<?php
include "../../../jwtconnect.php";
// ------------------------------
// قراءة HMAC من الهيدر أو من الـ query
// ------------------------------
$received_hmac = $_SERVER['HTTP_HMAC'] ?? ($_GET['hmac'] ?? '');
$received_hmac = trim($received_hmac);
// ------------------------------
// قراءة البيانات القادمة من Paymob
// ------------------------------
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// ------------------------------
// المفتاح السري
// ------------------------------
$secret_key = getenv('hmacPaymob');
// ------------------------------
// دالة لتحويل القيم إلى النصوص
// ------------------------------
function normalize($value) {
if ($value === true) return 'true';
if ($value === false) return 'false';
if (is_null($value)) return '';
return (string)$value;
}
// ------------------------------
// التحقق من صحة HMAC
// ------------------------------
function isValidHmac($data, $secret_key, $received_hmac) {
if (!isset($data['obj'])) return false;
$obj = $data['obj'];
// دمج جميع الحقول بشكل متسلسل
$fields = [
normalize($obj['amount_cents'] ?? ''),
normalize($obj['created_at'] ?? ''),
normalize($obj['currency'] ?? ''),
normalize($obj['error_occured'] ?? false),
normalize($obj['has_parent_transaction'] ?? false),
normalize($obj['id'] ?? ''),
normalize($obj['integration_id'] ?? ''),
normalize($obj['is_3d_secure'] ?? false),
normalize($obj['is_auth'] ?? false),
normalize($obj['is_capture'] ?? false),
normalize($obj['is_refunded'] ?? false),
normalize($obj['is_standalone_payment'] ?? false),
normalize($obj['is_voided'] ?? false),
normalize($obj['order']['id'] ?? ''),
normalize($obj['owner'] ?? ''),
normalize($obj['pending'] ?? false),
normalize($obj['source_data']['pan'] ?? ''),
normalize($obj['source_data']['sub_type'] ?? ''),
normalize($obj['source_data']['type'] ?? ''),
normalize($obj['success'] ?? false)
];
// دمج الحقول في رسالة واحدة
$message = implode('', $fields);
// حساب HMAC باستخدام المفتاح السري
$calculated_hmac = hash_hmac('sha512', $message, $secret_key);
//
/*طباعة الرسائل لأغراض التصحيح
error_log("🔐 Message used for HMAC: " . $message);
error_log("🔐 Calculated HMAC: " . $calculated_hmac);
error_log("📩 Received HMAC: " . $received_hmac);
error_log("Calculated HMAC length: " . strlen($calculated_hmac));
error_log("Received HMAC length: " . strlen($received_hmac));
*/
// التحقق من تطابق HMAC
if (hash_equals($calculated_hmac, $received_hmac)) {
error_log("✅ Valid HMAC signature verified.");
return $calculated_hmac;
} else {
http_response_code(401);
echo json_encode(["error" => "Unauthorized Invalid HMAC"]);
exit;
}
}
isValidHmac($data, $secret_key, $received_hmac);
// ------------------------------
// إذا كانت HMAC صحيحة، نتابع العملية
// ------------------------------
if ($data && isset($data['obj'])) {
$transaction = $data['obj'];
$payment_id = $transaction['id'] ?? null;
$amount = $transaction['amount_cents'] ?? 0;
$status = $transaction['success'] ?? false;
$is_voided = $transaction['is_voided'] ?? false;
$is_refunded = $transaction['is_refunded'] ?? false;
$order_id = $transaction['order']['id'] ?? null;
$merchant_order_id = $transaction['order']['merchant_order_id'] ?? null;
$payment_method = $transaction['source_data']['type'] ?? 'unknown';
$card_last4 = $transaction['source_data']['pan'] ?? '****';
$transaction_type = $transaction['data']['migs_transaction']['type'] ?? 'UNKNOWN';
$created_at = $transaction['created_at'] ?? date("Y-m-d H:i:s");
$user_id = $transaction['order']['shipping_data']['phone_number'];
$user_id='+'. $user_id;
$amount=$amount/100;
// التحقق من حالة الدفع
if (!$status) {
error_log("❌ Invalid payment status: " . $status);
echo json_encode(["error" => "Invalid payment status"]);
exit;
}
// إضافة البيانات إلى قاعدة البيانات
$query = "INSERT INTO payment_log_driver (`payment_id`, `user_id`, `amount`, `status`)
VALUES (:payment_id, :user_id, :amount, :status)";
$stmt = $con->prepare($query);
$stmt->bindParam(':payment_id', $payment_id);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':amount', $amount);
$stmt->bindParam(':status', $status);
try {
$stmt->execute();
if ($stmt->rowCount() > 0) {
http_response_code(200);
echo json_encode(["success" => true, "message" => "Payment data saved successfully"]);
error_log("Payment data saved successfully" . $status);
} else {
http_response_code(200);
echo json_encode(["success" => false, "message" => "Payment data already up to date."]);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(["error" => "Failed to execute the query: " . $e->getMessage()]);
}
}
?>

View File

@@ -1,33 +0,0 @@
Transaction ID: 275749381
Amount (EGP): 25
Order ID: 308769116
Merchant Order ID: 67db4baf5ad92
Payment Method: card (Last 4: 2346)
Transaction Type: PAYMENT
Success: Yes
Voided: No
Refunded: No
Created At: 2025-03-20T00:57:04.742244
----------------------------
Transaction ID: 275751796
Amount (EGP): 25
Order ID: 308771809
Merchant Order ID: 67db4dc9f0427
Payment Method: card (Last 4: 2346)
Transaction Type: PAYMENT
Success: Yes
Voided: No
Refunded: No
Created At: 2025-03-20T01:06:02.249734
----------------------------
Transaction ID: 275752145
Amount (EGP): 25
Order ID: 308772211
Merchant Order ID: 67db4e263aafe
Payment Method: card (Last 4: 2346)
Transaction Type: PAYMENT
Success: Yes
Voided: No
Refunded: No
Created At: 2025-03-20T01:07:31.653223
----------------------------

View File

@@ -1,137 +0,0 @@
<?php
include "../../jwtconnect.php";
// ------------------------------
// قراءة HMAC من الهيدر أو من الـ query
// ------------------------------
$received_hmac = $_SERVER['HTTP_HMAC'] ?? ($_GET['hmac'] ?? '');
$received_hmac = trim($received_hmac);
// ------------------------------
// قراءة البيانات القادمة من Paymob
// ------------------------------
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// ------------------------------
// المفتاح السري
// ------------------------------
$secret_key = getenv('hmacPaymob');
// ------------------------------
// دالة لتحويل القيم إلى النصوص
// ------------------------------
function normalize($value) {
if ($value === true) return 'true';
if ($value === false) return 'false';
if (is_null($value)) return '';
return (string)$value;
}
// ------------------------------
// التحقق من صحة HMAC
// ------------------------------
function isValidHmac($data, $secret_key, $received_hmac) {
if (!isset($data['obj'])) return false;
$obj = $data['obj'];
// دمج جميع الحقول بشكل متسلسل
$fields = [
normalize($obj['amount_cents'] ?? ''),
normalize($obj['created_at'] ?? ''),
normalize($obj['currency'] ?? ''),
normalize($obj['error_occured'] ?? false),
normalize($obj['has_parent_transaction'] ?? false),
normalize($obj['id'] ?? ''),
normalize($obj['integration_id'] ?? ''),
normalize($obj['is_3d_secure'] ?? false),
normalize($obj['is_auth'] ?? false),
normalize($obj['is_capture'] ?? false),
normalize($obj['is_refunded'] ?? false),
normalize($obj['is_standalone_payment'] ?? false),
normalize($obj['is_voided'] ?? false),
normalize($obj['order']['id'] ?? ''),
normalize($obj['owner'] ?? ''),
normalize($obj['pending'] ?? false),
normalize($obj['source_data']['pan'] ?? ''),
normalize($obj['source_data']['sub_type'] ?? ''),
normalize($obj['source_data']['type'] ?? ''),
normalize($obj['success'] ?? false)
];
// دمج الحقول في رسالة واحدة
$message = implode('', $fields);
// حساب HMAC باستخدام المفتاح السري
$calculated_hmac = hash_hmac('sha512', $message, $secret_key);
// طباعة الرسائل لأغراض التصحيح
// error_log("🔐 Message used for HMAC: " . $message);
// error_log("🔐 Calculated HMAC: " . $calculated_hmac);
// error_log("📩 Received HMAC: " . $received_hmac);
// error_log("Calculated HMAC length: " . strlen($calculated_hmac));
// error_log("Received HMAC length: " . strlen($received_hmac));
// التحقق من تطابق HMAC
if (hash_equals($calculated_hmac, $received_hmac)) {
error_log("✅ Valid HMAC signature verified.");
return $calculated_hmac;
} else {
http_response_code(401);
echo json_encode(["error" => "Unauthorized Invalid HMAC"]);
exit;
}
}
isValidHmac($data, $secret_key, $received_hmac);
// ------------------------------
// إذا كانت HMAC صحيحة، نتابع العملية
// ------------------------------
if ($data && isset($data['obj'])) {
$transaction = $data['obj'];
$payment_id = $transaction['id'] ?? null;
$amount = $transaction['amount_cents'] ?? 0;
$status = $transaction['success'] ?? false;
$is_voided = $transaction['is_voided'] ?? false;
$is_refunded = $transaction['is_refunded'] ?? false;
$order_id = $transaction['order']['id'] ?? null;
$merchant_order_id = $transaction['order']['merchant_order_id'] ?? null;
$payment_method = $transaction['source_data']['type'] ?? 'unknown';
$card_last4 = $transaction['source_data']['pan'] ?? '****';
$transaction_type = $transaction['data']['migs_transaction']['type'] ?? 'UNKNOWN';
$created_at = $transaction['created_at'] ?? date("Y-m-d H:i:s");
$user_id = $transaction['order']['shipping_data']['phone_number'];
// التحقق من حالة الدفع
if (!$status) {
error_log("❌ Invalid payment status: " . $status);
echo json_encode(["error" => "Invalid payment status"]);
exit;
}
// إضافة البيانات إلى قاعدة البيانات
$query = "INSERT INTO paymentsLog (`payment_id`, `user_id`, `amount`, `status`)
VALUES (:payment_id, :user_id, :amount, :status)";
$stmt = $con->prepare($query);
$stmt->bindParam(':payment_id', $payment_id);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':amount', $amount);
$stmt->bindParam(':status', $status);
try {
$stmt->execute();
if ($stmt->rowCount() > 0) {
http_response_code(200);
echo json_encode(["success" => true, "message" => "Payment data saved successfully"]);
} else {
http_response_code(200);
echo json_encode(["success" => false, "message" => "Payment data already up to date."]);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(["error" => "Failed to execute the query: " . $e->getMessage()]);
}
}
?>

View File

@@ -1,27 +0,0 @@
[21-Mar-2025 19:37:11 Europe/Berlin] PHP Notice: Array to string conversion in /home2/seferli1/wallet.sefer.live/seferpw.shop/sefer/ride/payMob/wallet/paymob_webhook.php on line 15
[21-Mar-2025 19:37:11 Europe/Berlin] Data: Array
[21-Mar-2025 19:37:11 Europe/Berlin] ✅ Valid HMAC signature verified.
[21-Mar-2025 19:37:11 Europe/Berlin] ❌ Invalid payment status:
[21-Mar-2025 19:37:11 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!
[21-Mar-2025 19:37:11 Europe/Berlin]
[21-Mar-2025 19:38:41 Europe/Berlin] PHP Notice: Array to string conversion in /home2/seferli1/wallet.sefer.live/seferpw.shop/sefer/ride/payMob/wallet/paymob_webhook.php on line 15
[21-Mar-2025 19:38:41 Europe/Berlin] Data: Array
[21-Mar-2025 19:38:41 Europe/Berlin] ✅ Valid HMAC signature verified.
[21-Mar-2025 19:38:41 Europe/Berlin] ❌ Invalid payment status:
[21-Mar-2025 19:38:41 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!
[21-Mar-2025 19:38:41 Europe/Berlin]
[21-Mar-2025 19:39:40 Europe/Berlin] PHP Notice: Array to string conversion in /home2/seferli1/wallet.sefer.live/seferpw.shop/sefer/ride/payMob/wallet/paymob_webhook.php on line 15
[21-Mar-2025 19:39:40 Europe/Berlin] Data: Array
[21-Mar-2025 19:39:40 Europe/Berlin] ✅ Valid HMAC signature verified.
[21-Mar-2025 19:39:40 Europe/Berlin] ❌ Invalid payment status:
[21-Mar-2025 19:39:40 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!
[21-Mar-2025 19:41:14 Europe/Berlin] ✅ Valid HMAC signature verified.
[21-Mar-2025 19:41:14 Europe/Berlin] ❌ Invalid payment status:
[21-Mar-2025 19:41:14 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!
[21-Mar-2025 19:41:58 Europe/Berlin] ✅ Valid HMAC signature verified.
[21-Mar-2025 19:41:58 Europe/Berlin] ❌ Invalid payment status:
[21-Mar-2025 19:41:59 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!
[21-Mar-2025 19:43:19 Europe/Berlin] redirect_url ishttps://vcheckout.paymobsolutions.com/checkout/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NDI1ODI4OTksImlkIjo2MTk5MDYyNzI0fQ.KH7jKKINyVzxJMH9IT2MyiAXRK_yMHVw-f4pIzyHzj0
[22-Mar-2025 15:38:59 Europe/Berlin] ✅ Valid HMAC signature verified.
[22-Mar-2025 15:38:59 Europe/Berlin] ❌ Invalid payment status:
[22-Mar-2025 15:39:00 Europe/Berlin] ❌ فشل الدفع عبر المحفظة!

View File

@@ -1,129 +0,0 @@
<?php
include "../../../connect.php";
// 1. احصل على AUTH TOKEN
$api_key = getenv("payMobApiKey1");
$integration_id = getenv("paymobIntegratedIdWallet");
$email = filterRequest("email");
$first_name = filterRequest("first_name");
$last_name = filterRequest("last_name");
$phone_number = filterRequest("phone_number");
$wallet_phone = filterRequest("phone_number");
$amount = filterRequest("amount");
$auth_url = "https://accept.paymob.com/api/auth/tokens";
$auth_data = json_encode(["api_key" => $api_key]);
$response = callAPI("POST", $auth_url, $auth_data);
$auth_token = $response->token ?? null;
if (!$auth_token) {
error_log("❌ فشل الحصول على AUTH TOKEN!");
die("❌ فشل الحصول على AUTH TOKEN!");
}
// 2. أنشئ الطلب ORDER
$order_url = "https://accept.paymob.com/api/ecommerce/orders";
$order_data = [
"auth_token" => $auth_token,
"delivery_needed" => false,
"amount_cents" => $amount,
"currency" => "EGP",
"merchant_order_id" => uniqid(),
"items" => []
];
$response = callAPI("POST", $order_url, json_encode($order_data));
$order_id = $response->id ?? null;
if (!$order_id) {
error_log("❌ فشل إنشاء الطلب!");
die("❌ فشل إنشاء الطلب!");
}
// error_log("orde is" .$order_id);
// 3. احصل على Payment Key
$payment_key_url = "https://accept.paymob.com/api/acceptance/payment_keys";
$payment_key_data = [
"auth_token" => $auth_token,
"amount_cents" => $amount,
"expiration" => 3600,
"order_id" => $order_id,
"billing_data" => [
"first_name" => $first_name,
"last_name" => $last_name,
"email" => $email,
"phone_number" => $phone_number,
"country" => "EG",
"city" => "Cairo",
"state" => "shobra",
"street" => "Test St.",
"building" => "1",
"apartment" => "10",
"floor" => "2",
"postal_code" => "12345",
"shipping_method" => "wallet"
],
"currency" => "EGP",
"integration_id" => $integration_id // إذا كان مضبوط
];
$response = callAPI("POST", $payment_key_url, json_encode($payment_key_data));
$payment_token = $response->token ?? null;
// error_log("payment_token is" .$payment_token);
if (!$payment_token) {
error_log("❌ فشل الحصول على PAYMENT TOKEN!");
die("❌ فشل الحصول على PAYMENT TOKEN!");
}
// error_log("phone wallet is ".$wallet_phone);
// 4. الدفع عبر المحفظة Wallet
$redirect_url = payWithWallet($payment_token, $wallet_phone);
if ($redirect_url) {
printSuccess($redirect_url);
error_log("redirect_url is" .$redirect_url);
} else {
error_log("❌ فشل الدفع عبر المحفظة!");
printFailure("Payment verified, but failed to generate token.");
// die("❌ فشل الدفع عبر المحفظة!");
}
// دالة لطلب API عبر CURL
function callAPI($method, $url, $data)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"]
]);
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response);
}
// الدالة الخاصة بالدفع بالمحفظة
function payWithWallet($paymentToken, $walletPhone)
{
$url = "https://accept.paymob.com/api/acceptance/payments/pay";
$data = [
"source" => [
"identifier" => $walletPhone,
"subtype" => "WALLET"
],
"payment_token" => $paymentToken
];
// Log the full data being sent to Paymob
// error_log("Data being sent to Paymob: " . json_encode($data));
$response = callAPI("POST", $url, json_encode($data));
// Log the full response for debugging
// error_log("Payment response: " . print_r($response, true));
return $response->redirect_url ?? null;
}

View File

@@ -1,358 +0,0 @@
<?php
include "../../../connect.php";
define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride");
define("LOG_FILE", "../logs/payment_verification.log"); // Define log file path
// Function to write to error log
function logError($step, $message, $data = null) {
$timestamp = date('Y-m-d H:i:s');
$logEntry = "[{$timestamp}] STEP {$step}: {$message}";
if ($data !== null) {
$logEntry .= " | Data: " . json_encode($data);
}
// Ensure log directory exists
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
// Append to log file
file_put_contents(LOG_FILE, $logEntry . PHP_EOL, FILE_APPEND);
// Also log to PHP error log for server monitoring
// error_log("PAYMENT_VERIFICATION: {$logEntry}");
}
// Receive parameters from GET request
$user_id = filterRequest("user_id");
$passengerId = filterRequest("passengerId");
$paymentMethod = filterRequest("paymentMethod");
// Log initial request
// logError("0", "Request received", [
// "user_id" => $user_id,
// "passengerId" => $passengerId
// ]);
// Validate user_id and passengerId
if (!$user_id || !$passengerId) {
// logError("1", "Invalid parameters", [
// "user_id" => $user_id,
// "passengerId" => $passengerId
// ]);
printFailure("Invalid user ID or passenger ID.");
exit;
}
try {
// Step 1: Get the latest successful payment
// logError("1", "Querying latest payment", ["user_id" => $user_id]);
$stmt = $con->prepare("SELECT * FROM paymentsLog WHERE user_id = :user_id AND created_at >= DATE_SUB(NOW(), INTERVAL 2 MINUTE)
ORDER BY created_at DESC
LIMIT 1");
$stmt->bindParam(':user_id', $user_id, PDO::PARAM_STR);
$stmt->execute();
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
logError("1", "No payment found", ["user_id" => $user_id]);
printFailure("No payment data found.");
exit;
}
// logError("1", "Payment found", [
// "payment_id" => $payment['id'] ?? 'unknown',
// "status" => $payment['status'],
// "amount" => $payment['amount']/100 ?? 'unknown'
// ]);
// Step 2: Check payment status
if ($payment['status'] != 1) {
// logError("2", "Payment not successful", ["status" => $payment['status']]);
printFailure("Payment is not successful yet.");
exit;
}
// logError("2", "Payment status verified", ["status" => $payment['status']]);
$amount = $payment['amount']/100; // Paid amount
// Step 3: Calculate bonus based on the paid amount
// logError("3", "Calculating bonus", ["amount" => $amount]);
$finalAmount = calculateBonus($amount);
if ($finalAmount <= 0) {
// logError("3", "Bonus calculation failed", [
// "original_amount" => $amount,
// "calculated_amount" => $finalAmount
// ]);
printFailure("Invalid amount for bonus calculation.");
exit;
}
// logError("3", "Bonus calculated", [
// "original_amount" => $amount,
// "final_amount" => $finalAmount
// ]);
// // Step 4: Generate payment token
// logError("4", "Generating payment token", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount
// ]);
$token = generatePaymentToken($passengerId, $finalAmount);
if (!$token) {
// logError("4", "Token generation failed");
printFailure("Payment verified, but failed to generate token.");
exit;
}
// logError("4", "Token generated successfully", ["token_length" => strlen($token)]);
// // Step 5: Add balance to passenger's wallet
// logError("5", "Adding balance to passenger wallet", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount
// ]);
$walletResult = addToPassengerWallet($passengerId, $finalAmount, $token);
if (!$walletResult || !isset($walletResult['status']) || $walletResult['status'] != "success") {
// logError("5", "Failed to add balance to passenger wallet", $walletResult);
printFailure("Payment verified, but failed to add balance to passenger wallet.");
exit;
}
// logError("5", "Balance added to passenger wallet", $walletResult);
// Step 6: Add balance to Sefer wallet
// logError("6", "Adding balance to Sefer wallet", [
// "passengerId" => $passengerId,
// "amount" => $finalAmount,
// "paymentMethod" => $paymentMethod
// ]);
$token = generatePaymentToken($passengerId, $finalAmount);
if (!$token) {
// logError("4", "Token generation failed");
printFailure("Payment verified, but failed to generate token.");
exit;
}
// logError("4", "Token generated successfully", ["token_length" => strlen($token)]);
$seferWalletResult = addToSeferWallet($passengerId, $amount, $paymentMethod);
if (!$seferWalletResult || !isset($seferWalletResult['status']) || $seferWalletResult['status'] != "success") {
// logError("6", "Failed to add balance to Sefer wallet", $seferWalletResult);
printFailure("Payment verified, but failed to add balance to Sefer wallet.");
exit;
}
// logError("6", "Balance added to Sefer wallet", $seferWalletResult);
// // Final success
// logError("7", "Process completed successfully", [
// "payment_id" => $payment['id'] ?? 'unknown',
// "amount" => $finalAmount,
// "passengerId" => $passengerId
// ]);
printSuccess( "Payment data saved successfully");
} catch (PDOException $e) {
logError("ERROR", "Database error: " . $e->getMessage());
printFailure("Database error occurred.");
} catch (Exception $e) {
logError("ERROR", "General error: " . $e->getMessage());
printFailure("An error occurred during payment verification.");
}
// 🎯 Function to generate payment token with error logging
function generatePaymentToken($passengerId, $amount) {
$url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
$postData = [
'passengerId' => $passengerId,
'amount' => $amount
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("4.1", "cURL error in token generation", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("4.2", "HTTP error in token generation", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data || !isset($data['message'])) {
logError("4.3", "Invalid response format in token generation", [
"response" => $response
]);
return null;
}
return $data['message']; // ✅ Return token
}
// 🎯 Function to add balance to passenger's wallet with error logging
function addToPassengerWallet($passengerId, $amount, $token) {
$url = BASE_URL . "/passengerWallet/add.php";
$postData = [
'passenger_id' => $passengerId,
'balance' => $amount,
'token' => $token
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("5.1", "cURL error in passenger wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("5.2", "HTTP error in passenger wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("5.3", "Invalid response format in passenger wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to add balance to Sefer wallet with error logging
function addToSeferWallet($passengerId, $amount, $paymentMethod) {
// Generate a new token specifically for the Sefer wallet
$seferToken = generatePaymentToken($passengerId, $amount);
if (!$seferToken) {
logError("6.0.1", "Failed to generate Sefer token");
return null;
}
logError("6.0.2", "Generated new Sefer token", [
"token_length" => ($seferToken)
]);
$url = BASE_URL . "/seferWallet/add.php";
$postData = [
'amount' => $amount,
'paymentMethod' => $paymentMethod,
'passengerId' => $passengerId,
'token' => $seferToken, // Use the new Sefer-specific token
'driverId' => 'passenger'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
logError("6.1", "cURL error in Sefer wallet update", [
"error" => $curlError,
"url" => $url
]);
return null;
}
if ($httpCode != 200) {
logError("6.2", "HTTP error in Sefer wallet update", [
"http_code" => $httpCode,
"response" => $response
]);
return null;
}
$data = json_decode($response, true);
if (!$data) {
logError("6.3", "Invalid response format in Sefer wallet update", [
"response" => $response
]);
return null;
}
return $data; // ✅ Return result
}
// 🎯 Function to calculate bonus
function calculateBonus($amount) {
logError("3.1", "Bonus calculation input", ["amount" => $amount]);
$result = 0;
if ($amount == 100) $result = 100;
else if ($amount == 200) $result = 215;
else if ($amount == 400) $result = 450;
else if ($amount == 1000) $result = 1140;
logError("3.2", "Bonus calculation result", [
"input" => $amount,
"output" => $result
]);
return $result;
}
?>

View File

@@ -1,137 +0,0 @@
<?php
include "../../../jwtconnect.php";
// ------------------------------
// قراءة HMAC من الهيدر أو من الـ query
// ------------------------------
$received_hmac = $_SERVER['HTTP_HMAC'] ?? ($_GET['hmac'] ?? '');
$received_hmac = trim($received_hmac);
// ------------------------------
// قراءة البيانات القادمة من Paymob
// ------------------------------
$raw_body = file_get_contents("php://input");
$data = json_decode($raw_body, true);
// ------------------------------
// المفتاح السري
// ------------------------------
$secret_key = getenv('hmacPaymob');
// ------------------------------
// دالة لتحويل القيم إلى النصوص
// ------------------------------
function normalize($value) {
if ($value === true) return 'true';
if ($value === false) return 'false';
if (is_null($value)) return '';
return (string)$value;
}
// ------------------------------
// التحقق من صحة HMAC
// ------------------------------
function isValidHmac($data, $secret_key, $received_hmac) {
if (!isset($data['obj'])) return false;
$obj = $data['obj'];
// دمج جميع الحقول بشكل متسلسل
$fields = [
normalize($obj['amount_cents'] ?? ''),
normalize($obj['created_at'] ?? ''),
normalize($obj['currency'] ?? ''),
normalize($obj['error_occured'] ?? false),
normalize($obj['has_parent_transaction'] ?? false),
normalize($obj['id'] ?? ''),
normalize($obj['integration_id'] ?? ''),
normalize($obj['is_3d_secure'] ?? false),
normalize($obj['is_auth'] ?? false),
normalize($obj['is_capture'] ?? false),
normalize($obj['is_refunded'] ?? false),
normalize($obj['is_standalone_payment'] ?? false),
normalize($obj['is_voided'] ?? false),
normalize($obj['order']['id'] ?? ''),
normalize($obj['owner'] ?? ''),
normalize($obj['pending'] ?? false),
normalize($obj['source_data']['pan'] ?? ''),
normalize($obj['source_data']['sub_type'] ?? ''),
normalize($obj['source_data']['type'] ?? ''),
normalize($obj['success'] ?? false)
];
// دمج الحقول في رسالة واحدة
$message = implode('', $fields);
// حساب HMAC باستخدام المفتاح السري
$calculated_hmac = hash_hmac('sha512', $message, $secret_key);
// طباعة الرسائل لأغراض التصحيح
// error_log("🔐 Message used for HMAC: " . $message);
// error_log("🔐 Calculated HMAC: " . $calculated_hmac);
// error_log("📩 Received HMAC: " . $received_hmac);
// error_log("Calculated HMAC length: " . strlen($calculated_hmac));
// error_log("Received HMAC length: " . strlen($received_hmac));
// التحقق من تطابق HMAC
if (hash_equals($calculated_hmac, $received_hmac)) {
error_log("✅ Valid HMAC signature verified.");
return $calculated_hmac;
} else {
http_response_code(401);
echo json_encode(["error" => "Unauthorized Invalid HMAC"]);
exit;
}
}
isValidHmac($data, $secret_key, $received_hmac);
// ------------------------------
// إذا كانت HMAC صحيحة، نتابع العملية
// ------------------------------
if ($data && isset($data['obj'])) {
$transaction = $data['obj'];
$payment_id = $transaction['id'] ?? null;
$amount = $transaction['amount_cents'] ?? 0;
$status = $transaction['success'] ?? false;
$is_voided = $transaction['is_voided'] ?? false;
$is_refunded = $transaction['is_refunded'] ?? false;
$order_id = $transaction['order']['id'] ?? null;
$merchant_order_id = $transaction['order']['merchant_order_id'] ?? null;
$payment_method = $transaction['source_data']['type'] ?? 'unknown';
$card_last4 = $transaction['source_data']['pan'] ?? '****';
$transaction_type = $transaction['data']['migs_transaction']['type'] ?? 'UNKNOWN';
$created_at = $transaction['created_at'] ?? date("Y-m-d H:i:s");
$user_id = $transaction['order']['shipping_data']['phone_number'];
// التحقق من حالة الدفع
if (!$status) {
error_log("❌ Invalid payment status: " . $status);
echo json_encode(["error" => "Invalid payment status"]);
exit;
}
// إضافة البيانات إلى قاعدة البيانات
$query = "INSERT INTO paymentsLog (`payment_id`, `user_id`, `amount`, `status`)
VALUES (:payment_id, :user_id, :amount, :status)";
$stmt = $con->prepare($query);
$stmt->bindParam(':payment_id', $payment_id);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':amount', $amount);
$stmt->bindParam(':status', $status);
try {
$stmt->execute();
if ($stmt->rowCount() > 0) {
http_response_code(200);
echo json_encode(["success" => true, "message" => "Payment data saved successfully"]);
} else {
http_response_code(200);
echo json_encode(["success" => false, "message" => "Payment data already up to date."]);
}
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(["error" => "Failed to execute the query: " . $e->getMessage()]);
}
}
?>

View File

@@ -9,33 +9,45 @@ $rideId = filterRequest("rideId");
$driverID = filterRequest("driverID");
$token = filterRequest("token");
// ✅ تحقق من التوكن
$stmt = $con->prepare("SELECT * FROM payment_tokens WHERE token = :token AND isUsed = FALSE");
$stmt->execute([ ':token' => $token ]);
$tokenData = $stmt->fetch();
try {
$con->beginTransaction();
if ($tokenData) {
// ✅ إدخال الدفع بمفتاح قصير وخفيف
$sql = "INSERT INTO payments (id, amount, payment_method, passengerID, rideId, driverID)
VALUES (UUID_SHORT(), :amount, :payment_method, :passengerID, :rideId, :driverID)";
$stmt = $con->prepare($sql);
$stmt->execute([
':amount' => $amount,
':payment_method' => $payment_method,
':passengerID' => $passengerID,
':rideId' => $rideId,
':driverID' => $driverID
]);
// ✅ تحقق من التوكن مع قفل السجل (FOR UPDATE) لمنع ثغرة السباق (Race Condition)
$stmt = $con->prepare("SELECT * FROM payment_tokens WHERE token = :token AND isUsed = FALSE FOR UPDATE");
$stmt->execute([ ':token' => $token ]);
$tokenData = $stmt->fetch();
if ($stmt->rowCount() > 0) {
printSuccess("Payment record created successfully");
if ($tokenData) {
// ✅ إدخال الدفع بمفتاح قصير وخفيف
$sql = "INSERT INTO payments (id, amount, payment_method, passengerID, rideId, driverID)
VALUES (UUID_SHORT(), :amount, :payment_method, :passengerID, :rideId, :driverID)";
$stmtInsert = $con->prepare($sql);
$stmtInsert->execute([
':amount' => $amount,
':payment_method' => $payment_method,
':passengerID' => $passengerID,
':rideId' => $rideId,
':driverID' => $driverID
]);
// ✅ تحديث حالة التوكن
$stmt = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE id = :tokenID");
$stmt->execute([ ':tokenID' => $tokenData['id'] ]);
if ($stmtInsert->rowCount() > 0) {
// ✅ تحديث حالة التوكن
$stmtUpdate = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE id = :tokenID");
$stmtUpdate->execute([ ':tokenID' => $tokenData['id'] ]);
$con->commit();
printSuccess("Payment record created successfully");
} else {
$con->rollBack();
printFailure("Failed to save record");
}
} else {
printFailure("Failed to save record");
$con->rollBack();
printFailure("Invalid or already used token");
}
} else {
printFailure("Invalid or already used token");
} catch (Exception $e) {
if ($con->inTransaction()) {
$con->rollBack();
}
printFailure("An error occurred: " . $e->getMessage());
}

View File

@@ -1,33 +0,0 @@
<?php
include "../../connect.php";
$promoCode = filterRequest("promoCode");
$amount = filterRequest("amount");
$description = filterRequest("description");
$validityStartDate = filterRequest("validityStartDate");
$validityEndDate = filterRequest("validityEndDate");
$sql = "INSERT INTO `promos` (
`promo_code`,
`amount`,
`description`,
`validity_start_date`,
`validity_end_date`
) VALUES (
'$promoCode', '$amount',
'$description',
'$validityStartDate',
'$validityEndDate'
)";
$stmt = $con->prepare($sql);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// Print a success message
printSuccess($message = "Promo data saved successfully");
} else {
// Print a failure message
printFailure($message = "Failed to save promo data");
}
?>

View File

@@ -1,18 +0,0 @@
<?php
include "../../connect.php";
$id = filterRequest("id");
$sql = "DELETE FROM `promos` WHERE `id` = '$id'";
$stmt = $con->prepare($sql);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// Print a success message
printSuccess($message = "Promo data deleted successfully");
} else {
// Print a failure message
printFailure($message = "Failed to delete promo data");
}
?>

View File

@@ -1,31 +0,0 @@
<?php
include "../../connect.php";
$promo_code = filterRequest("promo_code");
$sql = "SELECT
`id`,
`promo_code`,
`amount`,
`description`,
`validity_start_date`,
`validity_end_date`
FROM
`promos`
WHERE
`promo_code` = '$promo_code' AND CURDATE() BETWEEN validity_start_date AND validity_end_date;";
$stmt = $con->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result) {
// Print all promo records
printSuccess( $result);
} else {
// Print a failure message
printFailure($message = "Failed to retrieve promo records");
}
?>

View File

@@ -1,21 +0,0 @@
<?php
include "../../connect.php";
// $promo_code = filterRequest("promo_code");
$sql = "SELECT `id`, `promo_code`, `amount`, `description`, `validity_start_date`, `validity_end_date` FROM `promos` WHERE `validity_start_date`=CURDATE();";
$stmt = $con->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result) {
// Print all promo records
printSuccess( $result);
} else {
// Print a failure message
printFailure($message = "Failed to retrieve promo records");
}
?>

View File

@@ -1,27 +0,0 @@
<?php
include "../../connect.php";
$id = filterRequest("id");
$promoCode = filterRequest("promoCode");
$description = filterRequest("description");
$validityStartDate = filterRequest("validityStartDate");
$validityEndDate = filterRequest("validityEndDate");
$sql = "UPDATE `promos` SET
`promo_code` = '$promoCode',
`description` = '$description',
`validity_start_date` = '$validityStartDate',
`validity_end_date` = '$validityEndDate'
WHERE `id` = '$id'";
$stmt = $con->prepare($sql);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// Print a success message
printSuccess($message = "Promo data updated successfully");
} else {
// Print a failure message
printFailure($message = "Failed to update promo data");
}
?>

View File

@@ -1,22 +0,0 @@
<?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

@@ -1,45 +0,0 @@
<?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

@@ -1,7 +0,0 @@
[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

@@ -1,120 +0,0 @@
<?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

@@ -1,22 +0,0 @@
<?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

@@ -1,41 +0,0 @@
<?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

@@ -1,127 +0,0 @@
<?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

@@ -1,121 +0,0 @@
<?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

@@ -1,117 +0,0 @@
<?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

@@ -1,60 +0,0 @@
<?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

@@ -1,100 +0,0 @@
[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

View File

@@ -1,237 +0,0 @@
<?php
// /v1/main/ride/syriatel/driver/confirm_payment.php
// يعتمد على connect.php و syriatel_token_handler.php فقط
include_once "../../../connect.php";
include_once "./syriatel_token_handler.php";
header('Content-Type: application/json; charset=utf-8');
// ================== Helpers (طباعة/لوج) ==================
if (!function_exists('printSuccess')) {
function printSuccess($data = null, $message = "success") {
echo json_encode(["status" => "success", "message" => $message, "data" => $data], JSON_UNESCAPED_UNICODE);
exit;
}
}
if (!function_exists('printFailure')) {
function printFailure($message = "failure", $code = null) {
$resp = ["status" => "failure", "message" => $message];
if ($code !== null) $resp["code"] = $code;
echo json_encode($resp, JSON_UNESCAPED_UNICODE);
exit;
}
}
define("WALLET_LOG", __DIR__ . "/../logs/payment_verification.log");
function wlog($step, $msg, $data = null) {
$dir = dirname(WALLET_LOG);
if (!is_dir($dir)) { @mkdir($dir, 0755, true); }
$line = "[".date('Y-m-d H:i:s')."] STEP {$step}: {$msg}";
if ($data !== null) $line .= " | Data: ".json_encode($data, JSON_UNESCAPED_UNICODE);
file_put_contents(WALLET_LOG, $line.PHP_EOL, FILE_APPEND);
}
// ================== منطق التوكن/المعرف ==================
function generateToken(PDO $con, string $driverId, float $amount): ?string {
// secretKey يُفترض قادم من connect/env
global $secretKey;
$data = $driverId.$amount.time().($secretKey ?? 'default_secret');
$hash = hash('sha256', $data);
$rand = bin2hex(random_bytes(16));
$token = substr($hash.$rand, 0, 64);
$stmt = $con->prepare("INSERT INTO payment_tokens (token, driverID, dateCreated, amount)
VALUES (:t, :d, NOW(), :a)");
$stmt->execute([':t'=>$token, ':d'=>$driverId, ':a'=>$amount]);
return $stmt->rowCount() ? $token : null;
}
function generatePaymentID(PDO $con, string $driverId, float $amount, string $method): ?string {
$stmt = $con->prepare("INSERT INTO paymentsDriverPoints (amount, payment_method, driverID)
VALUES (:a, :m, :d)");
$stmt->execute([':a'=>$amount, ':m'=>$method, ':d'=>$driverId]);
return $stmt->rowCount() ? $con->lastInsertId() : null;
}
// ================== منطق إنهاء الدفع (مضمَّن) ==================
function finalizeWalletPaymentInline(PDO $con, string $orderRef): void {
// نقفل الصف لمنع السباقات
$stmt = $con->prepare("SELECT * FROM paymentsLogSyriaDriver
WHERE order_ref = :r LIMIT 1 FOR UPDATE");
$stmt->execute([':r'=>$orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
wlog("FINALIZE", "Payment row not found", ['orderRef'=>$orderRef]);
throw new RuntimeException("Payment not found.");
}
// نتأكد من نجاح مزود الدفع
if ((int)$payment['status'] !== 1) {
wlog("FINALIZE", "Payment not completed yet", ['orderRef'=>$orderRef, 'status'=>$payment['status']]);
throw new RuntimeException("Payment not completed.");
}
// حارس التكرار: إذا تمّت معالجة المحفظة سابقاً لا نكرر
if (!empty($payment['processed_wallet']) && (int)$payment['processed_wallet'] === 1) {
wlog("FINALIZE", "Already processed_wallet=1, skip.", ['orderRef'=>$orderRef]);
return; // لا نرمي استثناء؛ العملية سبق احتسابها
}
$driverId = $payment['user_id']; // This is now correctly handled as a string
$originalAmount = (float)$payment['amount'];
$paymentMethod = $payment['payment_method'] ?: 'ecash';
// البونص
$bonusAmount = match ((int)$originalAmount) {
100 => 100.0,
200 => 210.0,
400 => 450.0,
1000 => 1100.0,
default => $originalAmount,
};
// تنفيذ ككل داخل معاملة
$con->beginTransaction();
try {
// توليد التوكنات/المعرف
$tokenDriver = generateToken($con, $driverId, $bonusAmount);
if (!$tokenDriver) throw new RuntimeException("Failed to generate driver token");
$tokenSefer = generateToken($con, $driverId, $originalAmount);
if (!$tokenSefer) throw new RuntimeException("Failed to generate sefer token");
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new RuntimeException("Failed to create payment ID");
// driverWallet
$q = $con->prepare("INSERT INTO driverWallet (driverID, paymentID, amount, paymentMethod)
VALUES (:d, :r, :a, :m)");
$q->execute([
':d'=>$driverId, ':a'=>$bonusAmount,
':m'=>$paymentMethod, ':r'=>$orderRef
]);
if ($q->rowCount() === 0) throw new RuntimeException("Insert driverWallet failed");
// وسم التوكن كمستخدم
$con->prepare("UPDATE payment_tokens SET isUsed = 1 WHERE token = :t")->execute([':t'=>$tokenDriver]);
// seferWallet
$q2 = $con->prepare("INSERT INTO seferWallet (driverId, passengerId, amount, paymentMethod, token, createdAt)
VALUES (:d, :p, :a, :m, :t, CURRENT_TIMESTAMP)");
$q2->execute([
':d'=>$driverId, ':p'=>'driver', ':a'=>$originalAmount,
':m'=>$paymentMethod, ':t'=>$tokenSefer
]);
if ($q2->rowCount() === 0) throw new RuntimeException("Insert seferWallet failed");
$con->prepare("UPDATE payment_tokens SET isUsed = 1 WHERE token = :t")->execute([':t'=>$tokenSefer]);
// تأشير السجل كمنتهٍ للمحفظة
$con->prepare("UPDATE paymentsLogSyriaDriver
SET processed_wallet = 1, updated_at = NOW()
WHERE order_ref = :r")->execute([':r'=>$orderRef]);
$con->commit();
wlog("FINALIZE", "Wallets updated successfully", ['orderRef'=>$orderRef, 'driverId'=>$driverId]);
} catch (Throwable $e) {
$con->rollBack();
wlog("FINALIZE", "Exception: ".$e->getMessage(), ['orderRef'=>$orderRef]);
throw $e;
}
}
// ================== مدخل تأكيد الدفع ==================
$transactionID = filterRequest('transactionID');
$otp = filterRequest('otp');
error_log("Syriatel Confirm: Request for transaction {$transactionID}");
if (!$transactionID || !$otp) {
printFailure("Missing transaction ID or OTP.");
}
// بيئة
$baseUrl = rtrim((string)getenv('SYRIATEL_API_BASE_URL'), '/');
$merchantMSISDN = (string)getenv('SYRIATEL_MERCHANT_MSISDN');
if ($baseUrl === '' || $merchantMSISDN === '') {
error_log("Syriatel Confirm: Missing SYRIATEL envs");
printFailure("Server configuration error.");
}
try {
// 1) Auth token
$token = function_exists('GetSerialToken') ? GetSerialToken() : getSyriatelToken();
if (!$token) { printFailure("Could not authenticate with the payment provider."); }
// 2) Call provider
$body = [
"OTP" => $otp,
"merchantMSISDN" => $merchantMSISDN,
"transactionID" => $transactionID,
"token" => $token
];
$url = "{$baseUrl}/ePaymentExternalModule/paymentConfirmation";
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Accept: application/json",
"User-Agent: Mozilla/5.0",
],
CURLOPT_CONNECTTIMEOUT => 8,
CURLOPT_TIMEOUT => 40,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
error_log("Syriatel Confirm: HTTP {$httpCode} - ".substr((string)$response, 0, 300));
if ($errno) { printFailure("Payment gateway communication error.", $errno); }
if ($httpCode !== 200 || !$response) { printFailure("Payment gateway communication error (HTTP {$httpCode})."); }
$responseData = json_decode($response, true);
if (!is_array($responseData)) { printFailure("Invalid provider response."); }
$ok = (isset($responseData['errorDesc']) && $responseData['errorDesc'] === "Success");
if ($ok) {
// نحدّث حالة الدفع، ونُتم المحفظة بشكل آمن داخل نفس الطلب
$con->prepare("UPDATE paymentsLogSyriaDriver
SET status = 1, updated_at = NOW()
WHERE order_ref = :r")->execute([':r'=>$transactionID]);
// إنهاء المحفظة (داخلية)
$walletOk = true; $walletMsg = null;
try {
finalizeWalletPaymentInline($con, $transactionID);
} catch (Throwable $ex) {
$walletOk = false; $walletMsg = $ex->getMessage();
}
$payload = [
'message' => 'Payment confirmed.',
'transactionID' => $transactionID,
'provider' => $responseData
];
if (!$walletOk && $walletMsg) {
$payload['walletNotice'] = "Payment successful, but wallet update failed: ".$walletMsg;
}
printSuccess($payload);
}
$errorMessage = $responseData['errorDesc'] ?? 'Unknown provider error';
printFailure($errorMessage);
} catch (Throwable $e) {
error_log("Syriatel Confirm: Exception - ".$e->getMessage());
printFailure("An unexpected server error occurred.");
}

View File

@@ -1,127 +0,0 @@
<?php
// wallet/finalize_wallet_payment.php
// تم حذف include_once من هنا لأنه يُفترض أن ملف الاتصال قد تم تحميله بالفعل
// بواسطة الملف الذي يستدعي هذه الدالة (confirm_payment.php).
// include_once "../../../jwtconnect.php";
define("LOG_FILE", __DIR__ . "/../logs/payment_verification.log");
if (!function_exists('logError')) {
function logError($step, $message, $data = null) {
$logDir = dirname(LOG_FILE);
if (!is_dir($logDir)) { mkdir($logDir, 0755, true); }
$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, $logEntry . PHP_EOL, FILE_APPEND);
}
}
if (!function_exists('generateToken')) {
function generateToken($con, $driverId, $amount): ?string {
global $secretKey;
$data = $driverId . $amount . time() . ($secretKey ?? 'default_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): ?string {
$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('finalizeWalletPayment')) {
function finalizeWalletPayment($con) {
$orderRef = $_GET['orderRef'] ?? null;
if (empty($orderRef)) {
logError("FINALIZE", "Missing orderRef");
return; // لا نستخدم throw هنا لأن الخطأ داخلي
}
// 1. تحقق من الدفع
$stmt = $con->prepare("SELECT * FROM `paymentsLogSyriaDriver` WHERE order_ref = :order_ref AND status = 1 LIMIT 1");
$stmt->execute([':order_ref' => $orderRef]);
$payment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
logError("FINALIZE", "Payment not found or not completed", ['orderRef' => $orderRef]);
return;
}
// [تحسين] استخدام معاملات لضمان سلامة البيانات
$con->beginTransaction();
try {
$driverId = $payment['user_id'];
$originalAmount = floatval($payment['amount']);
$paymentMethod = $payment['payment_method'] ?? 'ecash';
// حساب المكافأة
$bonusAmount = match ((int)$originalAmount) {
100 => 100.0,
200 => 210.0,
400 => 450.0,
1000 => 1100.0,
default => $originalAmount,
};
// إنشاء التوكنات
$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');
$paymentID = generatePaymentID($con, $driverId, $bonusAmount, $paymentMethod);
if (!$paymentID) throw new Exception('Failed to generate payment ID');
// 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]);
// 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]);
// إذا نجحت كل العمليات، قم بتثبيتها في قاعدة البيانات
$con->commit();
logError("FINALIZE", "Wallets updated successfully", ['orderRef' => $orderRef]);
// لا نطبع نجاح هنا، الملف المستدعي هو المسؤول عن إرسال الرد النهائي
} catch (Throwable $e) {
// في حالة حدوث أي خطأ، تراجع عن كل التغييرات
$con->rollBack();
logError("FINALIZE", "Exception during finalization: " . $e->getMessage(), ['orderRef' => $orderRef]);
// نمرر الخطأ للملف الأعلى ليعالجه
throw $e;
}
}
}

View File

@@ -1,141 +0,0 @@
<?php
// /v1/main/ride/syriatel/driver/start_payment.php
include "../../../connect.php";
include_once "./syriatel_token_handler.php";
header('Content-Type: application/json; charset=utf-8');
/** دوال الطباعة (لو موجودة أصلاً في connect.php تجاهل هذه) */
if (!function_exists('printSuccess')) {
function printSuccess($data = null, $message = "success") {
echo json_encode(["status"=>"success","message"=>$message,"data"=>$data], JSON_UNESCAPED_UNICODE); exit;
}
}
if (!function_exists('printFailure')) {
function printFailure($message = "failure", $code = null) {
$resp = ["status"=>"failure","message"=>$message]; if ($code!==null) $resp["code"]=$code;
echo json_encode($resp, JSON_UNESCAPED_UNICODE); exit;
}
}
/** مولّد مرجع الطلب (TransactionID) */
function generate_order_ref(): string {
// مرجع مقروء + فريد: INT-YYYYMMDDHHMMSS-6digits
$ts = date('YmdHis');
$rand = str_pad((string)random_int(0, 999999), 6, '0', STR_PAD_LEFT);
return "INT-$ts-$rand";
}
// --- Input Parameters ---
$amount = filterRequest('amount');
$driverId = filterRequest('driverId');
$phone = filterRequest('phone'); // customerMSISDN
$lang = filterRequest('lang') ?? 'ar';
error_log("Syriatel Start: Request received for driver {$driverId} with amount {$amount}");
if (!$amount || !$driverId || !$phone) {
printFailure("Missing required parameters.");
}
// --- Environment Variables ---
$baseUrl = rtrim((string)getenv('SYRIATEL_API_BASE_URL'), '/');
$merchantMSISDN = (string)getenv('SYRIATEL_MERCHANT_MSISDN');
if ($baseUrl === '' || $merchantMSISDN === '') {
error_log("Syriatel Start: Missing SYRIATEL_API_BASE_URL or SYRIATEL_MERCHANT_MSISDN");
printFailure("Server configuration error.");
}
// --- Logic ---
try {
// 1) Token
$token = getSyriatelToken();
error_log("Syriatel Start: token=" . ($token ? substr($token,0,8).'...' : 'NULL'));
if (!$token) {
printFailure("Could not authenticate with the payment provider.");
}
// 2) Transaction ID + log DB
$transactionID = generate_order_ref();
$stmt = $con->prepare(
"INSERT INTO `paymentsLogSyriaDriver` (user_id, amount, status, order_ref, payment_method, created_at)
VALUES (:user_id, :amount, 0, :order_ref, 'syriatel', NOW())"
);
$stmt->execute([
':user_id' => $driverId,
':amount' => $amount,
':order_ref' => $transactionID
]);
error_log("Syriatel Start: Logged transaction {$transactionID} for driver {$driverId}");
// 3) Payment Request → Syriatel
$body = [
"customerMSISDN" => $phone, // مثال: 09xxxxxxxx (حسب وثيقتهم)
"merchantMSISDN" => $merchantMSISDN, // من env
"amount" => $amount,
"transactionID" => $transactionID,
"token" => $token
];
error_log("Syriatel Start: customerMSISDN {$phone} merchantMSISDN {$merchantMSISDN}");
$url = "{$baseUrl}/ePaymentExternalModule/paymentRequest";
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"User-Agent: Mozilla/5.0",
"Accept: application/json"
],
CURLOPT_CONNECTTIMEOUT => 8,
CURLOPT_TIMEOUT => 40,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errstr = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
error_log("Syriatel Start: paymentRequest HTTP {$httpCode} errno={$errno} resp=" . substr((string)$response,0,300));
if ($errno) {
printFailure("Payment gateway communication error.", $errno);
}
if ($httpCode !== 200) {
printFailure("Payment gateway communication error (HTTP {$httpCode}).");
}
$responseData = json_decode($response, true);
// حسب الدوكيومنت: resultCode = 1 يعني OTP انرسل بنجاح
//errorCode = 0 => Success
if (isset($responseData['errorCode']) && (string)$responseData['errorCode'] === "0") {
printSuccess([
'message' => 'OTP sent successfully.',
'transactionID' => $transactionID,
]);
}
// 2) إذا resultCode = 1 => OTP sent
elseif (isset($responseData['resultCode']) && (int)$responseData['resultCode'] === 1) {
printSuccess([
'message' => 'OTP sent successfully.',
'transactionID' => $transactionID,
]);
}
// 3) أي شيء آخر => فشل
else {
$errorMessage = $responseData['resultDescription']
?? $responseData['errorDesc']
?? 'Failed to initiate payment.';
printFailure($errorMessage);
}
} catch (Throwable $e) {
error_log("Syriatel Start: Exception - " . $e->getMessage());
printFailure("An unexpected server error occurred.");
}

View File

@@ -1,74 +0,0 @@
<?php // syriatel_token_handler
function getSyriatelToken(): ?string {
// اضبط البيئة: prod أو stage (افتراضي prod)
$env = getenv("SYRIATEL_ENV") ?: "prod";
// Base URLs من Postman
$baseStage = "https://merchants.syriatel.sy:1443/ePayment_external_Json_test/rs/ePaymentExternalModule";
$baseProd = "https://merchants.syriatel.sy:1443/ePayment_external_Json/rs/ePaymentExternalModule";
$baseUrl = ($env === "stage") ? $baseStage : $baseProd;
$url = $baseUrl . "/getToken";
// ⚠️ لا تضع قيم افتراضية حساسة Hardcoded
$username = getenv("SYRIATEL_USERNAME");
$password = getenv("SYRIATEL_PASSWORD");
if (!$username || !$password) {
error_log("[GetSyriatelToken] Missing credentials in ENV");
printFailure("Payment provider credentials are missing.");
return null;
}
error_log("[GetSyriatelToken] Env={$env} | URL={$url} | user={$username}");
$payload = [
"username" => $username,
"password" => $password
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"User-Agent: Mozilla/5.0",
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_CONNECTTIMEOUT => 8,
CURLOPT_TIMEOUT => 40,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errstr = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($errno) {
error_log("[GetSyriatelToken] cURL error {$errno}: {$errstr}");
printFailure("Could not connect to the payment provider.", $errno);
return null;
}
if ($httpCode !== 200 || !$response) {
error_log("[GetSyriatelToken] HTTP {$httpCode} | Empty/invalid response");
printFailure("Could not authenticate with the payment provider.");
return null;
}
$data = json_decode($response, true);
$token = $data["token"] ?? null;
if (!$token) {
error_log("[GetSyriatelToken] Token not found in response: " . substr($response, 0, 300));
printFailure("Could not authenticate with the payment provider.");
return null;
}
error_log("[GetSyriatelToken] Token received successfully");
return $token;
}

View File

@@ -1,25 +0,0 @@
[2025-11-04 11:16:27] STEP FINALIZE: Exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'orderRef' in 'field list' | Data: {"orderRef":"INT-20251104111538-994380"}
[2025-11-05 11:36:24] STEP FINALIZE: Exception: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined | Data: {"orderRef":"INT-20251105113557-052588"}
[2025-11-08 07:24:27] STEP FINALIZE: Exception: generateToken(): Argument #2 ($driverId) must be of type int, string given, called in /home/intaleq-wallet/htdocs/walletintaleq.intaleq.xyz/v1/main/ride/syriatel/driver/confirm_payment.php on line 98 | Data: {"orderRef":"INT-20251108072402-591731"}
[2025-11-15 03:12:44] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251115031225-211431","driverId":"1031b1b342a9a9e20b95"}
[2025-11-16 23:34:48] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251116233429-590104","driverId":"048e59b0737d7ad85370"}
[2025-11-17 07:48:33] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251117074803-798991","driverId":"28b3b16129d555cafb9b"}
[2025-11-22 16:35:44] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251122163518-755824","driverId":"986bf7b2242410647d05"}
[2025-11-25 11:50:26] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251125114917-921160","driverId":"7b437f291b5330536488"}
[2025-11-25 22:53:31] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251125225306-092996","driverId":"aec6f1335b72b5976dea"}
[2025-11-25 23:38:09] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251125233750-436593","driverId":"aec6f1335b72b5976dea"}
[2025-11-26 16:24:04] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251126162327-487255","driverId":"7a30afbb9b33d68a8b78"}
[2025-11-27 11:13:43] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251127111247-519577","driverId":"92e2fd19f4be30c3c727"}
[2025-11-27 16:48:44] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251127164535-525644","driverId":"e49604074b0b27710516"}
[2025-11-29 17:23:58] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251129172343-124569","driverId":"2870ec487be28f0929c7"}
[2025-11-30 21:34:28] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251130213350-345293","driverId":"3de8047aee520ff6555f"}
[2025-12-02 14:52:41] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251202145224-318083","driverId":"590c719b3aaefb07d001"}
[2025-12-13 13:33:03] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251213133220-085952","driverId":"94973848bd46ab517fa4"}
[2025-12-14 21:59:36] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251214215921-864193","driverId":"e0d0a6a92804240482fc"}
[2025-12-16 20:05:03] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251216200446-674525","driverId":"793ebf9e18327a828c55"}
[2025-12-18 11:20:20] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251218111954-420209","driverId":"df4e0e0cb135ac836e68"}
[2025-12-18 11:22:21] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251218112152-679624","driverId":"df4e0e0cb135ac836e68"}
[2025-12-18 21:25:11] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251218212432-696061","driverId":"64bfc098a99342c0c729"}
[2025-12-21 13:03:16] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251221130240-780780","driverId":"527c0a89cdf35841e4eb"}
[2025-12-21 13:14:09] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251221131302-717915","driverId":"527c0a89cdf35841e4eb"}
[2025-12-31 10:56:16] STEP FINALIZE: Wallets updated successfully | Data: {"orderRef":"INT-20251231105523-483044","driverId":"d881d416c9d712c9b222"}

View File

@@ -1,201 +0,0 @@
<?php
// /v1/main/ride/syriatel/passenger/confirm_payment.php
include "../../../connect.php";
include_once __DIR__ . "/syriatel_token_handler.php";
header('Content-Type: application/json; charset=utf-8');
/** Helpers **/
function mlog(string $msg) { error_log($msg); }
// تعريف دالة توليد التوكن محلياً (نفس منطق السائق ولكن للراكب)
if (!function_exists('generateLocalToken')) {
function generateLocalToken($con, $userId, $amount) {
// مفتاح سري بسيط للتشفير (يمكنك تغييره أو جلبه من ملف الإعدادات)
$secretKey = 'Tripz_Passenger_Secret_Key';
$data = $userId . $amount . time() . $secretKey;
$hash = hash('sha256', $data);
$randomBytes = bin2hex(random_bytes(16));
$token = substr($hash . $randomBytes, 0, 64);
$stmt = $con->prepare("INSERT INTO payment_tokens (token, passengerID, dateCreated, amount) VALUES (:token, :passengerID, NOW(), :amount)");
// لاحظ: استخدمنا passengerID هنا بدلاً من driverID بناء على الجدول، إذا كان الجدول موحداً استخدم العمود المناسب
// غالباً الجدول يحتوي user_id أو يتم استخدام driverID للكل.
// سأفترض هنا أن الجدول يقبل التوكن، وسأقوم بربطه بالراكب.
// إذا كان عمود driverID هو الوحيد الموجود، يمكن تمرير الراكب فيه أو تعديل الجدول.
// **للتوافق مع السائق:** سأستخدم الحقل العام أو أتجاوز الـ foreign key إذا وجد.
// لكن الأضمن:
$stmt->execute([':token' => $token, ':passengerID' => $userId, ':amount' => $amount]);
return $stmt->rowCount() > 0 ? $token : null;
}
}
// --- المدخلات ---
$transactionID = filterRequest('transactionID'); // يقابل order_ref
$otp = filterRequest('otp'); // كود التأكيد
$lang = filterRequest('lang'); // اختياري
mlog("Syriatel Confirm (Passenger): Start tx={$transactionID}");
if (!$transactionID || !$otp) {
printFailure($lang === 'ar' ? "رقم العملية أو رمز OTP مفقود." : "Missing transaction ID or OTP.");
exit;
}
// --- المتغيرات البيئية ---
$baseUrl = rtrim(getenv('SYRIATEL_API_BASE_URL'), '/');
$merchantMSISDN = getenv('SYRIATEL_MERCHANT_MSISDN');
if (!$baseUrl || !$merchantMSISDN) {
printFailure($lang === 'ar' ? "خطأ في إعدادات الخادم." : "Server configuration error.");
exit;
}
try {
// 1) توكن المصادقة من Syriatel
$token = getSyriatelToken();
if (!$token) {
printFailure($lang === 'ar' ? "تعذّر المصادقة مع مزوّد الدفع." : "Could not authenticate with the payment provider.");
exit;
}
// 2) تحضير وإرسال طلب التأكيد لشركة سيريتل
$body = [
"OTP" => $otp,
"merchantMSISDN" => $merchantMSISDN,
"transactionID" => $transactionID,
"token" => $token
];
$ch = curl_init("{$baseUrl}/ePaymentExternalModule/paymentConfirmation");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_TIMEOUT => 25,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$res = json_decode($response ?: '{}', true);
if (!is_array($res)) { $res = []; }
$errCode = isset($res['errorCode']) ? (string)$res['errorCode'] : null;
// التحقق من رد سيريتل
if ($httpCode !== 200 || $errCode !== "0") {
$errText = $res['errorDesc'] ?? $res['resultDescription'] ?? 'Payment failed';
mlog("Syriatel Confirm (Passenger): Failed - " . json_encode($res, JSON_UNESCAPED_UNICODE));
printFailure(['message' => $errText, 'syriatel' => $res]);
exit;
}
// ============================================================
// ✅ هنا يبدأ التعديل: التحديث المباشر لقاعدة البيانات (بدون cURL)
// ============================================================
global $con;
// 4) التحقق من السجل في قاعدة البيانات
$chk = $con->prepare("SELECT status, user_id, amount, payment_method FROM paymentsLogSyria WHERE order_ref = :ref LIMIT 1");
$chk->execute([':ref' => $transactionID]);
$payment = $chk->fetch(PDO::FETCH_ASSOC);
if (!$payment) {
printFailure($lang === 'ar' ? "لم يتم العثور على السجل." : "Payment row not found");
exit;
}
if ((int)$payment['status'] === 1) {
printSuccess(['message' => 'Already confirmed', 'data' => ['order_ref' => $transactionID]]);
exit;
}
// بدء المعاملة (Transaction)
$con->beginTransaction();
try {
// أ) تحديث حالة الدفع في السجل
$stmtUpdate = $con->prepare("UPDATE `paymentsLogSyria` SET status = 1, updated_at = NOW() WHERE order_ref = :ref");
$stmtUpdate->execute([':ref' => $transactionID]);
$passengerId = $payment['user_id'];
$originalAmount = floatval($payment['amount']);
$paymentMethod = $payment['payment_method'] ?? 'syriatel';
// ب) حساب المكافأة (نفس المنطق القديم)
$bonusAmount = match ((int)$originalAmount) {
500 => 530.0,
1000 => 1070.0,
2000 => 2180.0,
5000 => 5700.0,
default => $originalAmount,
};
// ج) إنشاء التوكنات مباشرة (بدون دالة خارجية)
// 1. توكن لمحفظة الراكب (بالمبلغ مع البونص)
$tokenPassenger = generateLocalToken($con, $passengerId, $bonusAmount);
if (!$tokenPassenger) throw new Exception('Failed to generate passenger token');
// 2. توكن لمحفظة السفر/الإيرادات (بالمبلغ الأصلي)
$tokenSefer = generateLocalToken($con, $passengerId, $originalAmount);
if (!$tokenSefer) throw new Exception('Failed to generate sefer token');
// د) الإضافة إلى passengerWallet مباشرة
// ملاحظة: تأكد من أسماء الأعمدة في جدول passengerWallet
$insertPassWallet = $con->prepare("INSERT INTO passengerWallet (passenger_id, balance, token, created_at) VALUES (:pid, :amount, :token, NOW())");
$insertPassWallet->execute([
':pid' => $passengerId,
':amount' => $bonusAmount,
':token' => $tokenPassenger
]);
if ($insertPassWallet->rowCount() === 0) throw new Exception('Insert to passengerWallet failed');
// هـ) الإضافة إلى seferWallet مباشرة
// ملاحظة: في الراكب، يكون driverId عادة هو 'passenger' لتمييز أن الدفع جاء من تطبيق الراكب
$insertSefer = $con->prepare("INSERT INTO seferWallet (driverId, passengerId, amount, paymentMethod, token, createdAt)
VALUES (:did, :pid, :amount, :method, :token, NOW())");
$insertSefer->execute([
':did' => 'passenger', // كما في السكربت القديم
':pid' => $passengerId,
':amount' => $originalAmount,
':method' => $paymentMethod,
':token' => $tokenSefer
]);
if ($insertSefer->rowCount() === 0) throw new Exception('Insert to seferWallet failed');
// و) تحديث التوكنات لتصبح مستخدمة (isUsed = TRUE)
$updateToken = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE token = :token");
$updateToken->execute([':token' => $tokenPassenger]);
$updateToken->execute([':token' => $tokenSefer]);
// ز) تثبيت المعاملة
$con->commit();
mlog("Syriatel Confirm (Passenger): Success DB Transaction for user {$passengerId}");
// إرجاع رد النجاح
printSuccess([
'message' => 'Syriatel Confirm Success',
'data' => [
'order_ref' => $transactionID,
'finalAmount' => $bonusAmount,
'syriatel' => $res
]
]);
exit;
} catch (Throwable $e) {
// في حال حدوث خطأ، تراجع عن كل شيء
$con->rollBack();
mlog("Syriatel Confirm (Passenger): Transaction Error - " . $e->getMessage());
printFailure($lang === 'ar' ? "فشل تحديث المحفظة." : "Wallet update failed.");
exit;
}
} catch (Throwable $e) {
mlog("Syriatel Confirm (Passenger): General Exception - " . $e->getMessage());
printFailure($lang === 'ar' ? "خطأ في الخادم." : "Server error");
exit;
}
?>

View File

@@ -1,124 +0,0 @@
<?php
// /v1/main/ride/syriatel/passenger/start_payment.php
include "../../../connect.php";
include_once "./syriatel_token_handler.php";
header('Content-Type: application/json; charset=utf-8');
// --- Input Parameters ---
$amount = filterRequest('amount');
$passengerId = filterRequest('passengerId'); // بدل driverId
$phone = filterRequest('phone'); // رقم الراكب (customerMSISDN)
$lang = filterRequest('lang') ?? 'ar';
error_log("Syriatel Start (Passenger): Request received for passenger {$passengerId} with amount {$amount}");
if (!$amount || !$passengerId || !$phone) {
printFailure($lang === 'ar' ? "بيانات ناقصة." : "Missing required parameters.");
exit;
}
function generate_order_ref(): string {
// مرجع مقروء + فريد: INT-YYYYMMDDHHMMSS-6digits
$ts = date('YmdHis');
$rand = str_pad((string)random_int(0, 999999), 6, '0', STR_PAD_LEFT);
return "INT-$ts-$rand";
}
// --- Environment Variables ---
$baseUrl = rtrim(getenv('SYRIATEL_API_BASE_URL'), '/');
$merchantMSISDN = getenv('SYRIATEL_MERCHANT_MSISDN');
if (!$baseUrl || !$merchantMSISDN) {
error_log("Syriatel Start (Passenger): Missing SYRIATEL_API_BASE_URL or SYRIATEL_MERCHANT_MSISDN env variables.");
printFailure($lang === 'ar' ? "خطأ إعدادات الخادم." : "Server configuration error.");
exit;
}
try {
// 1) Get Authentication Token
$token = getSyriatelToken();
error_log("Syriatel Start (Passenger):token= .$token");
if (!$token) {
printFailure($lang === 'ar' ? "تعذّر المصادقة مع مزوّد الدفع." : "Could not authenticate with the payment provider.");
exit;
}
// 2) Generate transaction ID + log
$transactionID = generate_order_ref(); // موجود لديك مسبقًا
// ملاحظة: استخدم جدول منفصل للركاب، أو وحّد الجدول مع حقل user_type. هنا نفترض جدول خاص بالراكب.
$stmt = $con->prepare(
"INSERT INTO `paymentsLogSyria`
(user_id, amount, status, order_ref, payment_method, created_at)
VALUES
(:user_id, :amount, 0, :order_ref, 'syriatel', NOW())"
);
$stmt->execute([
':user_id' => $passengerId,
':amount' => $amount,
':order_ref' => $transactionID
]);
error_log("Syriatel Start (Passenger): Logged transaction {$transactionID} for passenger {$passengerId}");
// 3) Call Syriatel paymentRequest
$body = [
"customerMSISDN" => $phone, // هاتف الراكب
"merchantMSISDN" => $merchantMSISDN, // هاتف التاجر (المحفظة)
"amount" => $amount,
"transactionID" => $transactionID,
"token" => $token
];
$ch = curl_init("{$baseUrl}/ePaymentExternalModule/paymentRequest");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_TIMEOUT => 25,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErr = curl_error($ch);
curl_close($ch);
if ($curlErr) {
error_log("Syriatel Start (Passenger): cURL Error - {$curlErr}");
}
error_log("Syriatel Start (Passenger): API Response HTTP {$httpCode} - {$response}");
if ($httpCode !== 200) {
printFailure($lang === 'ar' ? "خطأ اتصال ببوابة الدفع." : "Payment gateway communication error.");
exit;
}
$responseData = json_decode($response, true);
// حسب الدوكيومنت: resultCode = 1 يعني OTP انرسل بنجاح
//errorCode = 0 => Success
if (isset($responseData['errorCode']) && (string)$responseData['errorCode'] === "0") {
printSuccess([
'message' => 'OTP sent successfully.',
'transactionID' => $transactionID,
]);
}
// 2) إذا resultCode = 1 => OTP sent
elseif (isset($responseData['resultCode']) && (int)$responseData['resultCode'] === 1) {
printSuccess([
'message' => 'OTP sent successfully.',
'transactionID' => $transactionID,
]);
}
// 3) أي شيء آخر => فشل
else {
$errorMessage = $responseData['resultDescription']
?? $responseData['errorDesc']
?? 'Failed to initiate payment.';
printFailure($errorMessage);
}
} catch (Throwable $e) {
error_log("Syriatel Start: Exception - " . $e->getMessage());
printFailure("An unexpected server error occurred.");
}

View File

@@ -1 +0,0 @@
{"token":"E964A84D88C9A2306016886254475A49BE2BC95AFB6F4C30CD24857F5EFACDD2173D59A4B951CCEEE311AEFD3E40ABBF3E70BD2B1B8B3F0703E094C419E6291A6CFEA5C3CCD3B57E093FD58E6BB09ECF","expires_at":1759998218}

View File

@@ -1,74 +0,0 @@
<?php // syriatel_token_handler
function getSyriatelToken(): ?string {
// اضبط البيئة: prod أو stage (افتراضي prod)
$env = getenv("SYRIATEL_ENV") ?: "prod";
// Base URLs من Postman
$baseStage = "https://merchants.syriatel.sy:1443/ePayment_external_Json_test/rs/ePaymentExternalModule";
$baseProd = "https://merchants.syriatel.sy:1443/ePayment_external_Json/rs/ePaymentExternalModule";
$baseUrl = ($env === "stage") ? $baseStage : $baseProd;
$url = $baseUrl . "/getToken";
// ⚠️ لا تضع قيم افتراضية حساسة Hardcoded
$username = getenv("SYRIATEL_USERNAME");
$password = getenv("SYRIATEL_PASSWORD");
if (!$username || !$password) {
error_log("[GetSyriatelToken] Missing credentials in ENV");
printFailure("Payment provider credentials are missing.");
return null;
}
error_log("[GetSyriatelToken] Env={$env} | URL={$url} | user={$username}");
$payload = [
"username" => $username,
"password" => $password
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"User-Agent: Mozilla/5.0",
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_CONNECTTIMEOUT => 8,
CURLOPT_TIMEOUT => 40,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errstr = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($errno) {
error_log("[GetSyriatelToken] cURL error {$errno}: {$errstr}");
printFailure("Could not connect to the payment provider.", $errno);
return null;
}
if ($httpCode !== 200 || !$response) {
error_log("[GetSyriatelToken] HTTP {$httpCode} | Empty/invalid response");
printFailure("Could not authenticate with the payment provider.");
return null;
}
$data = json_decode($response, true);
$token = $data["token"] ?? null;
if (!$token) {
error_log("[GetSyriatelToken] Token not found in response: " . substr($response, 0, 300));
printFailure("Could not authenticate with the payment provider.");
return null;
}
error_log("[GetSyriatelToken] Token received successfully");
return $token;
}