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

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;
}