Update: 2026-06-11 18:22:57
This commit is contained in:
201
walletintaleq.intaleq.xyz/v2/main/ride/syriatel/passenger/confirm_payment.php
Executable file
201
walletintaleq.intaleq.xyz/v2/main/ride/syriatel/passenger/confirm_payment.php
Executable file
@@ -0,0 +1,201 @@
|
||||
<?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;
|
||||
}
|
||||
?>
|
||||
124
walletintaleq.intaleq.xyz/v2/main/ride/syriatel/passenger/start_payment.php
Executable file
124
walletintaleq.intaleq.xyz/v2/main/ride/syriatel/passenger/start_payment.php
Executable file
@@ -0,0 +1,124 @@
|
||||
<?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.");
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"token":"E964A84D88C9A2306016886254475A49BE2BC95AFB6F4C30CD24857F5EFACDD2173D59A4B951CCEEE311AEFD3E40ABBF3E70BD2B1B8B3F0703E094C419E6291A6CFEA5C3CCD3B57E093FD58E6BB09ECF","expires_at":1759998218}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?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;
|
||||
}
|
||||
Reference in New Issue
Block a user