Update: 2026-07-13 04:13:50
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* driverWallet/add.php — إضافة رصيد لمحفظة السائق
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════
|
||||
* SECURITY FIX:
|
||||
* - إضافة التحقق من ملكية الحساب (driverID == JWT user_id)
|
||||
* - لف العملية في Transaction ذرية
|
||||
* - استخدام FOR UPDATE لمنع Race Condition على التوكن
|
||||
* - التحقق من صحة المبلغ
|
||||
* ═══════════════════════════════════════════════════════════════
|
||||
*/
|
||||
|
||||
// Include the database connection file (calls authenticateJWT)
|
||||
include "../../connect.php";
|
||||
|
||||
// ── 1. استخراج user_id من JWT المصادق ──────────────────────────
|
||||
$jwtUserId = $decodedToken->user_id ?? $decodedToken->sub ?? null;
|
||||
|
||||
// ── 2. استخراج والتحقق من البيانات ──────────────────────────
|
||||
$driverID = filterRequest("driverID");
|
||||
$paymentID = filterRequest("paymentID");
|
||||
$amount = filterRequest("amount");
|
||||
$paymentMethod = filterRequest("paymentMethod");
|
||||
$token = filterRequest("token");
|
||||
|
||||
if (empty($driverID) || !isset($amount) || empty($paymentMethod) || empty($token)) {
|
||||
printFailure("Missing required parameters");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 3. التحقق من ملكية الحساب ────────────────────────────────
|
||||
// السائق المصادق يمكنه فقط إضافة رصيد لمحفظته الشخصية
|
||||
if ($jwtUserId !== null && $driverID !== $jwtUserId) {
|
||||
error_log(sprintf(
|
||||
'⚠️ [SECURITY] Ownership mismatch in add.php | jwt_user=%s | requested_driverID=%s | IP=%s',
|
||||
$jwtUserId, $driverID, $_SERVER['REMOTE_ADDR'] ?? 'unknown'
|
||||
));
|
||||
http_response_code(403);
|
||||
printFailure("Forbidden: You can only modify your own wallet");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 4. التحقق من المبلغ ─────────────────────────────────────
|
||||
$amount = floatval($amount);
|
||||
if ($amount <= 0 || $amount > 1000000) {
|
||||
printFailure("Invalid amount");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 5. العملية الذرية ─────────────────────────────────────────
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// التحقق من التوكن مع قفل السجل (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 ($tokenData) {
|
||||
// إدخال سجل المحفظة
|
||||
$sql = "INSERT INTO `driverWallet` (
|
||||
`driverID`,
|
||||
`paymentID`,
|
||||
`amount`,
|
||||
`paymentMethod`
|
||||
) VALUES (
|
||||
:driverID,
|
||||
:paymentID,
|
||||
:amount,
|
||||
:paymentMethod
|
||||
);";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([
|
||||
':driverID' => $driverID,
|
||||
':paymentID' => $paymentID,
|
||||
':amount' => $amount,
|
||||
':paymentMethod' => $paymentMethod
|
||||
]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// تحديث حالة التوكن
|
||||
$stmt = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE id = :tokenID");
|
||||
$stmt->execute([':tokenID' => $tokenData['id']]);
|
||||
|
||||
$con->commit();
|
||||
printSuccess("Record saved successfully");
|
||||
} else {
|
||||
$con->rollBack();
|
||||
printFailure("Failed to save record");
|
||||
}
|
||||
} else {
|
||||
$con->rollBack();
|
||||
printFailure("Invalid or already used token");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if ($con->inTransaction()) {
|
||||
$con->rollBack();
|
||||
}
|
||||
error_log("[driverWallet/add] " . $e->getMessage());
|
||||
printFailure("An error occurred");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// Include the database connection file
|
||||
include "../../jwtconnect.php";
|
||||
|
||||
//add300ToDriver.php
|
||||
|
||||
// Get the request parameters
|
||||
$driverID = filterRequest("driverID");
|
||||
$paymentID = filterRequest("paymentID");
|
||||
$amount = filterRequest("amount");
|
||||
$paymentMethod = filterRequest("paymentMethod");
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 1) ATOMIC CHECK + INSERT TO PREVENT RACE CONDITION
|
||||
// -------------------------------------------------------------
|
||||
$con->beginTransaction();
|
||||
|
||||
$check = $con->prepare("
|
||||
SELECT id
|
||||
FROM driverWallet
|
||||
WHERE driverID = :driverID AND paymentMethod = :paymentMethod
|
||||
LIMIT 1
|
||||
FOR UPDATE
|
||||
");
|
||||
|
||||
$check->execute([
|
||||
':driverID' => $driverID,
|
||||
':paymentMethod' => $paymentMethod
|
||||
]);
|
||||
|
||||
if ($check->rowCount() > 0) {
|
||||
$con->rollBack();
|
||||
printFailure("لقد تم منح هذا الدفع للسائق مسبقاً — لا يمكن تكراره.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 2) INSERT INTO driverWallet
|
||||
// -------------------------------------------------------------
|
||||
$sql = "INSERT INTO `driverWallet` (
|
||||
`driverID`,
|
||||
`paymentID`,
|
||||
`amount`,
|
||||
`paymentMethod`
|
||||
) VALUES (
|
||||
:driverID,
|
||||
:paymentID,
|
||||
:amount,
|
||||
:paymentMethod
|
||||
);";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute(array(
|
||||
':driverID' => $driverID,
|
||||
':paymentID' => $paymentID,
|
||||
':amount' => $amount,
|
||||
':paymentMethod' => $paymentMethod
|
||||
));
|
||||
|
||||
$con->commit();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
|
||||
printSuccess("Record saved successfully");
|
||||
|
||||
// Notify driver
|
||||
$messageBody = "تم إضافة رصيد بقيمة $amount إلى محفظتك بنجاح.";
|
||||
// sendWhatsAppFromServer($phone, $messageBody);
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 3) INSERT 30,000 POINTS FOR NEW DRIVER
|
||||
// -------------------------------------------------------------
|
||||
$sqlPoints = "INSERT INTO `paymentsDriverPoints`
|
||||
(`amount`, `payment_method`, `driverID`, `created_at`, `updated_at`)
|
||||
VALUES (:amount, :method, :driverID, NOW(), NOW())";
|
||||
|
||||
$stmtPoints = $con->prepare($sqlPoints);
|
||||
$stmtPoints->execute(array(
|
||||
':amount' => 300,
|
||||
':method' => $paymentMethod,
|
||||
':driverID' => $driverID
|
||||
));
|
||||
|
||||
} else {
|
||||
printFailure("Failed to save record");
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* addFromAdmin.php — إضافة رصيد من المسؤول (Admin Only)
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════
|
||||
* SECURITY FIX: كان هذا الملف بدون أي مصادقة! ❌
|
||||
* الآن يتطلب:
|
||||
* 1. JWT مصادق (عبر authenticateJWT)
|
||||
* 2. التحقق من دور المسؤول (admin role)
|
||||
* 3. التحقق من المبلغ (حد أقصى)
|
||||
* 4. تسجيل تدقيق لكل عملية (audit log)
|
||||
* ═══════════════════════════════════════════════════════════════
|
||||
*/
|
||||
|
||||
// Include the database connection WITH JWT authentication
|
||||
include "../../connect.php";
|
||||
// connect.php calls authenticateJWT() → 5-layer security check ✅
|
||||
|
||||
// ── 1. استخراج user_id من JWT المصادق ──────────────────────────
|
||||
$adminUserId = $decodedToken->user_id ?? $decodedToken->sub ?? null;
|
||||
$adminRole = $decodedToken->role ?? null;
|
||||
|
||||
// ── 2. التحقق من صلاحيات المسؤول ────────────────────────────
|
||||
// فقط المسؤول يمكنه إضافة رصيد يدوياً
|
||||
if ($adminRole !== 'admin' && $adminRole !== 'super_admin') {
|
||||
error_log(sprintf(
|
||||
'⚠️ [SECURITY] Non-admin attempted addFromAdmin | user=%s | role=%s | IP=%s',
|
||||
$adminUserId,
|
||||
$adminRole ?? '(null)',
|
||||
$_SERVER['REMOTE_ADDR'] ?? 'unknown'
|
||||
));
|
||||
http_response_code(403);
|
||||
printFailure("Forbidden: Admin access required");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 3. استخراج والتحقق من البيانات ──────────────────────────
|
||||
$driverID = filterRequest("driverID");
|
||||
$paymentID = filterRequest("paymentID");
|
||||
$amount = filterRequest("amount");
|
||||
$paymentMethod = filterRequest("paymentMethod");
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
if (empty($driverID) || !isset($amount) || empty($paymentMethod)) {
|
||||
printFailure("Missing required parameters: driverID, amount, paymentMethod");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 4. التحقق من المبلغ ─────────────────────────────────────
|
||||
$amount = floatval($amount);
|
||||
if ($amount <= 0 || $amount > 1000000) {
|
||||
error_log(sprintf(
|
||||
'⚠️ [SECURITY] Invalid amount in addFromAdmin | admin=%s | amount=%s | driverID=%s',
|
||||
$adminUserId, $amount, $driverID
|
||||
));
|
||||
printFailure("Invalid amount: must be between 0 and 1,000,000");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── 5. العملية الذرية ─────────────────────────────────────────
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// إدخال سجل المحفظة
|
||||
$sql = "INSERT INTO `driverWallet` (
|
||||
`driverID`,
|
||||
`paymentID`,
|
||||
`amount`,
|
||||
`paymentMethod`
|
||||
) VALUES (
|
||||
:driverID,
|
||||
:paymentID,
|
||||
:amount,
|
||||
:paymentMethod
|
||||
);";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([
|
||||
':driverID' => $driverID,
|
||||
':paymentID' => $paymentID ?? ('admin_' . time() . '_' . bin2hex(random_bytes(4))),
|
||||
':amount' => $amount,
|
||||
':paymentMethod' => $paymentMethod
|
||||
]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// ── 6. تسجيل تدقيق (Audit Log) ─────────────────────────
|
||||
$auditStmt = $con->prepare(
|
||||
"INSERT INTO `admin_audit_log` (`admin_id`, `action`, `table_name`, `record_id`, `details`)
|
||||
VALUES (:admin_id, :action, :table_name, :record_id, :details)"
|
||||
);
|
||||
$auditStmt->execute([
|
||||
':admin_id' => $adminUserId,
|
||||
':action' => 'addFromAdmin_wallet',
|
||||
':table_name' => 'driverWallet',
|
||||
':record_id' => $driverID,
|
||||
':details' => json_encode([
|
||||
'amount' => $amount,
|
||||
'paymentMethod' => $paymentMethod,
|
||||
'phone' => $phone,
|
||||
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
|
||||
'timestamp' => date('Y-m-d H:i:s')
|
||||
], JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
|
||||
$con->commit();
|
||||
|
||||
printSuccess("Record saved successfully");
|
||||
|
||||
// إرسال إشعار واتساب للسائق
|
||||
if (!empty($phone)) {
|
||||
$messageBody = "تم إضافة رصيد بقيمة $amount إلى محفظتك بنجاح.";
|
||||
sendWhatsAppFromServer($phone, $messageBody);
|
||||
}
|
||||
} else {
|
||||
$con->rollBack();
|
||||
printFailure("Failed to save record");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if ($con->inTransaction()) {
|
||||
$con->rollBack();
|
||||
}
|
||||
error_log("[addFromAdmin] Error: " . $e->getMessage());
|
||||
printFailure("An error occurred");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
//addPaymentToken.php
|
||||
$driverID = filterRequest("driverID");
|
||||
$amount = filterRequest("amount");
|
||||
|
||||
// Check if required fields are present
|
||||
if ($driverID === null || $amount === null) {
|
||||
printFailure("Missing required fields: driverID and amount must be provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Generate a more secure token
|
||||
$token = generateSecureToken($driverID, $amount);
|
||||
|
||||
// Store the token in the database
|
||||
$stmt = $con->prepare("INSERT INTO payment_tokens (token, driverID, dateCreated, amount) VALUES (?, ?, NOW(), ?)");
|
||||
|
||||
try {
|
||||
$stmt->execute([$token, $driverID, $amount]);
|
||||
if ($stmt->rowCount() > 0) {
|
||||
printSuccess($token);
|
||||
} else {
|
||||
printFailure("Failed to save record");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
error_log("[addPaymentToken] " . $e->getMessage());
|
||||
printFailure("Database error");
|
||||
}
|
||||
|
||||
function generateSecureToken($driverID, $amount) {
|
||||
global $secretKey;
|
||||
// Concatenate the parameters
|
||||
$data = $driverID . $amount . time();
|
||||
|
||||
// Add the secret key from the environment variable
|
||||
$data .= $secretKey;
|
||||
|
||||
// Generate a hash
|
||||
$hash = hash('sha256', $data);
|
||||
|
||||
// Add some randomness
|
||||
$randomBytes = bin2hex(random_bytes(16));
|
||||
|
||||
// Combine hash and random bytes
|
||||
$token = $hash . $randomBytes;
|
||||
|
||||
// Truncate to a reasonable length (e.g., 64 characters)
|
||||
return substr($token, 0, 64);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* add_s2s_reward.php — Payment Server Endpoint
|
||||
*
|
||||
* Inserts wallet credit/debit records into driverWallet.
|
||||
* Authenticated via X-S2S-Api-Key header matching the S2S_SHARED_KEY environment variable.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../../jwtconnect.php';
|
||||
|
||||
define('S2S_SHARED_KEY', getenv('S2S_SHARED_KEY'));
|
||||
|
||||
$providedKey = $_SERVER['HTTP_X_S2S_API_KEY'] ?? '';
|
||||
|
||||
if (empty($providedKey) || $providedKey !== S2S_SHARED_KEY) {
|
||||
http_response_code(401);
|
||||
printFailure("Unauthorized: Invalid or missing X-S2S-Api-Key.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$driverID = filterRequest("driverID");
|
||||
$paymentID = filterRequest("paymentID");
|
||||
$amount = filterRequest("amount");
|
||||
$paymentMethod = filterRequest("paymentMethod");
|
||||
$points = filterRequest("points"); // Optional raw points
|
||||
|
||||
if (empty($driverID) || empty($paymentID) || !isset($amount) || empty($paymentMethod)) {
|
||||
printFailure("Missing required parameters: driverID, paymentID, amount, paymentMethod");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// Prevent duplicate challenge claims using paymentsDriverPoints table
|
||||
if (strpos($paymentMethod, 'daily_') === 0 || strpos($paymentMethod, 'weekly_') === 0) {
|
||||
$checkSql = "SELECT id FROM paymentsDriverPoints WHERE driverID = :driver_id AND payment_method = :challenge_id AND DATE(created_at) = CURDATE() FOR UPDATE";
|
||||
$stmtCheck = $con->prepare($checkSql);
|
||||
$stmtCheck->execute([
|
||||
':driver_id' => $driverID,
|
||||
':challenge_id' => $paymentMethod
|
||||
]);
|
||||
|
||||
if ($stmtCheck->rowCount() > 0) {
|
||||
$con->rollBack();
|
||||
printFailure("Reward already claimed today");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO `driverWallet` (
|
||||
`driverID`,
|
||||
`paymentID`,
|
||||
`amount`,
|
||||
`paymentMethod`
|
||||
) VALUES (
|
||||
:driverID,
|
||||
:paymentID,
|
||||
:amount,
|
||||
:paymentMethod
|
||||
);";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([
|
||||
':driverID' => $driverID,
|
||||
':paymentID' => $paymentID,
|
||||
':amount' => $amount,
|
||||
':paymentMethod' => $paymentMethod
|
||||
]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// If points are provided, also insert into paymentsDriverPoints
|
||||
if (!empty($points)) {
|
||||
$sqlPoints = "INSERT INTO `paymentsDriverPoints` (
|
||||
`amount`,
|
||||
`payment_method`,
|
||||
`driverID`
|
||||
) VALUES (
|
||||
:points,
|
||||
:paymentMethod,
|
||||
:driverID
|
||||
);";
|
||||
$stmtPoints = $con->prepare($sqlPoints);
|
||||
$stmtPoints->execute([
|
||||
':points' => $points,
|
||||
':paymentMethod' => $paymentMethod,
|
||||
':driverID' => $driverID
|
||||
]);
|
||||
}
|
||||
|
||||
$con->commit();
|
||||
printSuccess("Record saved successfully");
|
||||
} else {
|
||||
$con->rollBack();
|
||||
printFailure("Failed to save record");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if ($con->inTransaction()) {
|
||||
$con->rollBack();
|
||||
}
|
||||
error_log("add_s2s_reward: " . $e->getMessage());
|
||||
printFailure("An error occurred");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
include '../../connect.php';
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 0);
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$driverID = filterRequest('driverID');
|
||||
$amount = floatval(filterRequest('amount'));
|
||||
|
||||
if (empty($driverID) || empty($amount) || $amount <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Missing required fields or invalid amount']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// 1. Fetch current budget
|
||||
$stmt = $con->prepare("SELECT SUM(amount) as diff FROM payments WHERE captain_id = :driverID FOR UPDATE");
|
||||
$stmt->execute([':driverID' => $driverID]);
|
||||
$sumRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$totalBudget = floatval($sumRow['diff']);
|
||||
|
||||
if ($totalBudget < $amount) {
|
||||
$con->rollBack();
|
||||
echo json_encode(['status' => 'error', 'message' => 'Insufficient budget']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. Generate unique tokens
|
||||
$paymentID1 = "budget2pt_" . time() . bin2hex(random_bytes(4));
|
||||
$paymentID2 = "pt2budget_" . time() . bin2hex(random_bytes(4));
|
||||
$token1 = bin2hex(random_bytes(32));
|
||||
$token2 = bin2hex(random_bytes(32));
|
||||
|
||||
// 3. Deduct from budget (payments)
|
||||
$deductAmount = -$amount;
|
||||
$stmt = $con->prepare("INSERT INTO payments (captain_id, amount, rideId, payment_method, passengerID, token)
|
||||
VALUES (:driverID, :amount, :rideId, 'myBudget', 'myBudgetToPoint', :token)");
|
||||
$stmt->execute([
|
||||
':driverID' => $driverID,
|
||||
':amount' => $deductAmount,
|
||||
':rideId' => $paymentID1,
|
||||
':token' => $token1
|
||||
]);
|
||||
|
||||
// 4. Add to points (paymentsDriverPoints)
|
||||
$stmt = $con->prepare("INSERT INTO paymentsDriverPoints (captain_id, paymentID, amount, token, paymentMethod)
|
||||
VALUES (:driverID, :paymentID, :amount, :token, 'fromBudget')");
|
||||
$stmt->execute([
|
||||
':driverID' => $driverID,
|
||||
':paymentID' => $paymentID2,
|
||||
':amount' => $amount,
|
||||
':token' => $token2
|
||||
]);
|
||||
|
||||
// Commit Transaction
|
||||
$con->commit();
|
||||
|
||||
echo json_encode(['status' => 'success', 'message' => 'Budget converted to points successfully']);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$con->rollBack();
|
||||
error_log('[convertBudgetToPoints] Error: ' . $e->getMessage());
|
||||
echo json_encode(['status' => 'error', 'message' => 'An internal error occurred.']);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// ==========================================
|
||||
// Cron Job: Remove Duplicate Records Daily
|
||||
// Tables: driverWallet, paymentsDriverPoints
|
||||
// ==========================================
|
||||
|
||||
// Load DB Connection
|
||||
include "../../jwtconnect.php";
|
||||
|
||||
// Function to run cleanup query
|
||||
function runCleanup($con, $deleteQuery, $tableName) {
|
||||
try {
|
||||
$stmt = $con->prepare($deleteQuery);
|
||||
$stmt->execute();
|
||||
|
||||
echo "Cleanup completed for table: $tableName\n";
|
||||
echo "Rows affected: " . $stmt->rowCount() . "\n\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error cleaning $tableName\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// DELETE DUPLICATES FOR driverWallet
|
||||
// ==========================================
|
||||
|
||||
$deleteDriverWallet = "
|
||||
DELETE FROM driverWallet
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT
|
||||
id,
|
||||
ROW_NUMBER() OVER(PARTITION BY driverID ORDER BY dateCreated DESC) AS rn
|
||||
FROM driverWallet
|
||||
) AS subquery
|
||||
WHERE rn = 1
|
||||
);";
|
||||
|
||||
runCleanup($con, $deleteDriverWallet, "driverWallet");
|
||||
|
||||
|
||||
// ==========================================
|
||||
// DELETE DUPLICATES FOR paymentsDriverPoints
|
||||
// ==========================================
|
||||
|
||||
$deletePaymentsPoints = "
|
||||
DELETE FROM paymentsDriverPoints
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT
|
||||
id,
|
||||
ROW_NUMBER() OVER(PARTITION BY driverID ORDER BY created_at DESC) AS rn
|
||||
FROM paymentsDriverPoints
|
||||
) AS subquery
|
||||
WHERE rn = 1
|
||||
);";
|
||||
|
||||
runCleanup($con, $deletePaymentsPoints, "paymentsDriverPoints");
|
||||
|
||||
echo "Cron job completed successfully.\n";
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
$sql = "SELECT
|
||||
YEAR(`driver_orders`.`created_at`) AS `year`,
|
||||
MONTH(`driver_orders`.`created_at`) AS `month`,
|
||||
COUNT(*) AS `total_orders`,
|
||||
SUM(CASE WHEN `ride`.`status` = 'Finished' THEN 1 ELSE 0 END) AS `completed_orders`,
|
||||
SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) AS `pending_orders`,
|
||||
SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) AS `canceled_orders`,
|
||||
ROUND(SUM(CASE WHEN `ride`.`status` = 'Finished' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_completed`,
|
||||
ROUND(SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_pending`,
|
||||
ROUND(SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_canceled`,
|
||||
SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) AS `rejected_orders`,
|
||||
ROUND(SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_rejected`
|
||||
FROM
|
||||
`driver_orders`
|
||||
LEFT JOIN `ride` ON `ride`.`id` = `driver_orders`.`order_id`
|
||||
WHERE
|
||||
`driver_orders`.`driver_id` = '$driverID'
|
||||
AND YEAR(`driver_orders`.`created_at`) = YEAR(CURDATE())
|
||||
AND MONTH(`driver_orders`.`created_at`) = MONTH(CURDATE())
|
||||
GROUP BY
|
||||
YEAR(`driver_orders`.`created_at`),
|
||||
MONTH(`driver_orders`.`created_at`)
|
||||
ORDER BY
|
||||
`year`,
|
||||
`month`;
|
||||
|
||||
";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Fetch the record
|
||||
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
printSuccess( $row);
|
||||
|
||||
}
|
||||
else{
|
||||
// Print a failure message
|
||||
printFailure($message = "No wallet record found");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
$sql = "SELECT
|
||||
COALESCE(dw.id, 0) AS id,
|
||||
COALESCE(dw.driverID, '0') AS driverID,
|
||||
COALESCE(dw.paymentID, '0') AS paymentID,
|
||||
COALESCE(dw.dateCreated, '1970-01-01 00:00:00') AS dateCreated,
|
||||
COALESCE(dw.amount, 0) AS amount,
|
||||
COALESCE(dw.paymentMethod, '0') AS paymentMethod,
|
||||
COALESCE(dw.dateUpdated, '1970-01-01 00:00:00') AS dateUpdated,
|
||||
COALESCE((SELECT SUM(amount) FROM driverWallet WHERE driverID = '$driverID'), 0) AS total_amount
|
||||
FROM
|
||||
driverWallet dw
|
||||
WHERE
|
||||
dw.driverID = '$driverID'
|
||||
GROUP BY
|
||||
dw.id,
|
||||
dw.driverID,
|
||||
dw.paymentID,
|
||||
dw.dateCreated,
|
||||
dw.amount,
|
||||
dw.paymentMethod,
|
||||
dw.dateUpdated
|
||||
|
||||
";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Fetch the record
|
||||
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
printSuccess( $row);
|
||||
|
||||
}
|
||||
else{
|
||||
// Print a failure message
|
||||
printFailure($message = "No wallet record found");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_phone = filterRequest("driver_phone");
|
||||
|
||||
$sql = "SELECT
|
||||
`driverToken`.`token`,
|
||||
`driver`.`id`,
|
||||
`driver`.`phone`,
|
||||
`driver`.`name_arabic`as name,
|
||||
driver.national_number
|
||||
FROM
|
||||
`driverToken`
|
||||
LEFT JOIN `driver` ON `driver`.`id` = `driverToken`.`captain_id`
|
||||
WHERE
|
||||
`driver`.`phone` = '$driver_phone'";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data) {
|
||||
// Print the car location data as JSON
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
|
||||
'data' => $data
|
||||
]);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
$sql = "SELECT
|
||||
`id`,
|
||||
`driverID`,
|
||||
`paymentID`,
|
||||
`dateCreated`,
|
||||
`amount`,
|
||||
`paymentMethod`,
|
||||
`dateUpdated`,
|
||||
(SELECT SUM(`amount`)
|
||||
FROM `driverWallet`
|
||||
WHERE `driverID` = '$driverID'
|
||||
AND `dateCreated` >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
|
||||
) AS totalAmount
|
||||
FROM `driverWallet`
|
||||
WHERE `driverID` = '$driverID'
|
||||
AND `dateCreated` >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
|
||||
ORDER BY `dateCreated` DESC;
|
||||
";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Fetch the record
|
||||
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
printSuccess( $row);
|
||||
|
||||
}
|
||||
else{
|
||||
// Print a failure message
|
||||
printFailure($message = "No wallet record found");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
$sql = "SELECT
|
||||
driverWallet.`id`,
|
||||
driverWallet.amount,
|
||||
driverWallet.dateCreated as created_at
|
||||
FROM
|
||||
`driverWallet`
|
||||
WHERE
|
||||
driverWallet.driverID = '$driverID' AND driverWallet.dateCreated >= DATE_SUB(NOW(), INTERVAL 1 MONTH)
|
||||
ORDER BY
|
||||
`driverWallet`.`id`
|
||||
DESC";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Fetch the record
|
||||
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
printSuccess( $row);
|
||||
|
||||
}
|
||||
else{
|
||||
// Print a failure message
|
||||
printFailure($message = "No wallet record found");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* get_s2s_wallet_dashboard.php — Payment Server Endpoint
|
||||
*
|
||||
* Returns wallet metrics (challenge points, today's earnings) for a driver.
|
||||
* Authenticated via X-S2S-Api-Key header matching the S2S_SHARED_KEY environment variable.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../../jwtconnect.php';
|
||||
|
||||
define('S2S_SHARED_KEY', getenv('S2S_SHARED_KEY'));
|
||||
|
||||
$providedKey = $_SERVER['HTTP_X_S2S_API_KEY'] ?? '';
|
||||
|
||||
if (empty($providedKey) || $providedKey !== S2S_SHARED_KEY) {
|
||||
http_response_code(401);
|
||||
printFailure("Unauthorized: Invalid or missing X-S2S-Api-Key.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
if (empty($driverID)) {
|
||||
printFailure("Missing required parameter: driverID");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. Calculate Sum of claimed challenge points
|
||||
$stmtChallengePoints = $con->prepare("
|
||||
SELECT COALESCE(SUM(amount), 0)
|
||||
FROM `paymentsDriverPoints`
|
||||
WHERE driverID = :driver_id
|
||||
AND (payment_method LIKE 'daily_%' OR payment_method LIKE 'weekly_%')
|
||||
");
|
||||
$stmtChallengePoints->execute([':driver_id' => $driverID]);
|
||||
$challengePoints = (int)($stmtChallengePoints->fetchColumn() ?: 0);
|
||||
|
||||
// 2. Calculate Today's Earnings
|
||||
$stmtTodayEarnings = $con->prepare("
|
||||
SELECT COALESCE(SUM(amount), 0)
|
||||
FROM payments
|
||||
WHERE driverID = :driver_id
|
||||
AND DATE(created_at) = CURDATE()
|
||||
");
|
||||
$stmtTodayEarnings->execute([':driver_id' => $driverID]);
|
||||
$todayEarnings = (float)($stmtTodayEarnings->fetchColumn() ?: 0.0);
|
||||
|
||||
// 3. Calculate Total Wallet Balance
|
||||
$stmtTotalWallet = $con->prepare("
|
||||
SELECT COALESCE(SUM(amount), 0)
|
||||
FROM `driverWallet`
|
||||
WHERE driverID = :driver_id
|
||||
");
|
||||
$stmtTotalWallet->execute([':driver_id' => $driverID]);
|
||||
$totalWallet = (float)($stmtTotalWallet->fetchColumn() ?: 0.0);
|
||||
|
||||
printSuccess([
|
||||
"challengePoints" => $challengePoints,
|
||||
"todayEarnings" => $todayEarnings,
|
||||
"totalWallet" => $totalWallet
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("[get_s2s_wallet_dashboard] " . $e->getMessage());
|
||||
printFailure("An error occurred");
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
// Include the database connection file
|
||||
include "../../connect.php";
|
||||
|
||||
// Get the request parameters
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$payment_amount = filterRequest("payment_amount");
|
||||
$timePromo = filterRequest("timePromo"); // Example: 'morning' or 'afternoon'
|
||||
//$createdAt = date("Y-m-d H:i:s"); // Get the current date and time
|
||||
$currentDate = date("Y-m-d"); // Current date for comparison
|
||||
|
||||
// Check if a promotion record for the same driver already exists today
|
||||
$sqlCheck = "SELECT COUNT(*) FROM `driver_promotions` WHERE `driver_id` = :driver_id AND DATE(`created_at`) = :current_date
|
||||
and timePromo=:timePromo
|
||||
";
|
||||
$stmtCheck = $con->prepare($sqlCheck);
|
||||
$stmtCheck->execute(array(
|
||||
':driver_id' => $driver_id,
|
||||
':current_date' => $currentDate
|
||||
':timePromo' =>$timePromo
|
||||
));
|
||||
|
||||
$count = $stmtCheck->fetchColumn();
|
||||
|
||||
if ($count > 0) {
|
||||
// A record exists for today, so prevent the insertion
|
||||
printFailure("A promotion record for this driver already exists for today.");
|
||||
} else {
|
||||
// No record exists for today, so insert the new promotion
|
||||
$sqlInsert = "INSERT INTO `driver_promotions` (
|
||||
`driver_id`,
|
||||
`payment_amount`,
|
||||
`timePromo`
|
||||
) VALUES (
|
||||
:driver_id,
|
||||
:payment_amount,
|
||||
:timePromo
|
||||
);";
|
||||
|
||||
// Prepare the insert statement
|
||||
$stmtInsert = $con->prepare($sqlInsert);
|
||||
$stmtInsert->execute(array(
|
||||
':driver_id' => $driver_id,
|
||||
':payment_amount' => $payment_amount,
|
||||
':timePromo' => $timePromo,
|
||||
':createdAt' => $createdAt
|
||||
));
|
||||
|
||||
// Check if the query was successful
|
||||
if ($stmtInsert->rowCount() > 0) {
|
||||
// Print a success message
|
||||
printSuccess("Promotion record saved successfully");
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure("Failed to save promotion record");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
// Connect to database
|
||||
include '../../connect.php';
|
||||
|
||||
// Get trip details
|
||||
$driverName = filterRequest('name');
|
||||
$driverEmail = filterRequest('email');
|
||||
$driverPhone = filterRequest('phone');
|
||||
$amount = filterRequest('amount');
|
||||
$newDriverName = filterRequest('newDriver');
|
||||
$newEmail=filterRequest('newEmail');
|
||||
|
||||
// Get language preference from database or user input
|
||||
$language = 'en'; // Default to English
|
||||
// Email content
|
||||
if ($language === 'ar') {
|
||||
$bodyEmail = "<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f5f8fa;
|
||||
color: #14171a;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #1da1f2;
|
||||
margin-top: 0;
|
||||
}
|
||||
p {
|
||||
line-height: 1.5;
|
||||
}
|
||||
a {
|
||||
color: #1da1f2;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='container'>
|
||||
<h1>تفاصيل نقلك على سفر</h1>
|
||||
<p>شكراً لاستخدام خدمتنا. نتمنى لك يوماً رائعاً!</p>
|
||||
<p>نريد إعلامك أن مبلغ $amount تم نقله من حسابك إلى السائق الجديد، $newDriverName (هاتف: $driverPhone).</p>
|
||||
<p>مع خالص التحية،<br> فريق سفر</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
} else {
|
||||
$bodyEmail = "<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f5f8fa;
|
||||
color: #14171a;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #1da1f2;
|
||||
margin-top: 0;
|
||||
}
|
||||
p {
|
||||
line-height: 1.5;
|
||||
}
|
||||
a {
|
||||
color: #1da1f2;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='container'>
|
||||
<img src='https://lh3.googleusercontent.com/a/ACg8ocLe5TgvmTjoFx7KjIoWGxX0G2ryKBTzUZi2-mBYb9DI1dsKQ0WEYh5ZPdnA3WeFbp9VnaTNzJuA0w8S4RiQ7042AKrOwXo3=s576-c-no' alt='SIRO App Logo' style='width: 150px; margin: 20px auto; display: block;'>
|
||||
|
||||
<h1>Your SIRO Transfer Details</h1>
|
||||
<p>Thank you for using our service. We hope you have a great day!</p>
|
||||
<p>We want to inform you that an amount of $amount has been transferred from your account to the new driver: $newDriverName (Phone: $driverPhone).</p>
|
||||
<p>Regards,<br> SIRO Team</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
}
|
||||
|
||||
// Email headers
|
||||
$supportEmail = 'siroteam@siro.live';
|
||||
$headers = "MIME-Version: 1.0\r\n";
|
||||
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
$headers .= "From: $supportEmail\r\n";
|
||||
|
||||
// Send email
|
||||
if (!empty($driverEmail)) {
|
||||
if (mail($driverEmail, "Your SIRO Transfer Details", $bodyEmail, $headers)) {
|
||||
|
||||
mail($newEmail, "Your SIRO Transfer Details", $bodyEmail, $headers);
|
||||
echo "Email sent successfully.";
|
||||
} else {
|
||||
echo "Email sending failed.";
|
||||
}
|
||||
} else {
|
||||
echo "Invalid email address: $driverEmail";
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
include '../../jwtconnect.php';
|
||||
|
||||
// Disable error reporting output for production API
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
// Set header
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$senderID = filterRequest('senderID');
|
||||
$receiverID = filterRequest('receiverID'); // Now receiving the ID directly from Main Server
|
||||
$amount = floatval(filterRequest('amount'));
|
||||
$country = filterRequest('country'); // e.g. Egypt, Syria, Jordan
|
||||
|
||||
if (empty($senderID) || empty($receiverID) || empty($amount) || empty($country)) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Missing required fields']);
|
||||
exit;
|
||||
}
|
||||
// --- Payment Key Authentication ---
|
||||
$expectedKey = getenv('PAYMENT_KEY');
|
||||
$providedKey = $_SERVER['HTTP_PAYMENT_KEY'] ?? '';
|
||||
|
||||
if (empty($expectedKey) || $providedKey !== $expectedKey) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Unauthorized Payment Server Access (Invalid Key)']);
|
||||
exit;
|
||||
}
|
||||
// 1. Determine Fee based on Country
|
||||
$fee = 0;
|
||||
if (strtolower($country) === 'egypt') {
|
||||
$fee = 5;
|
||||
if ($amount < 10) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Minimum transfer amount in Egypt is 10']);
|
||||
exit;
|
||||
}
|
||||
} elseif (strtolower($country) === 'syria') {
|
||||
$fee = 10;
|
||||
if ($amount < 100) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Minimum transfer amount in Syria is 100']);
|
||||
exit;
|
||||
}
|
||||
} elseif (strtolower($country) === 'jordan') {
|
||||
$fee = 0.25;
|
||||
if ($amount < 1) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Minimum transfer amount in Jordan is 1']);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
// Default fee if unknown
|
||||
$fee = 5;
|
||||
}
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
if ($receiverID == $senderID) {
|
||||
$con->rollBack();
|
||||
echo json_encode(['status' => 'error', 'message' => 'Cannot transfer to yourself']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. Fetch Sender Budget (with FOR UPDATE to lock rows)
|
||||
$stmt = $con->prepare("SELECT SUM(amount) as diff FROM payments WHERE captain_id = :senderID FOR UPDATE");
|
||||
$stmt->execute([':senderID' => $senderID]);
|
||||
$sumRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$totalBudget = floatval($sumRow['diff']);
|
||||
|
||||
if ($totalBudget < $amount) {
|
||||
$con->rollBack();
|
||||
echo json_encode(['status' => 'error', 'message' => 'Insufficient budget']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$amountForReceiver = $amount - $fee;
|
||||
if ($amountForReceiver <= 0) {
|
||||
$con->rollBack();
|
||||
echo json_encode(['status' => 'error', 'message' => 'Transfer amount must be greater than the fee']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 3. Generate unique Tokens and paymentIDs
|
||||
$paymentID1 = "transfer_" . time() . bin2hex(random_bytes(4));
|
||||
$paymentID2 = "transfer_recv_" . time() . bin2hex(random_bytes(4));
|
||||
$token1 = bin2hex(random_bytes(32));
|
||||
$token2 = bin2hex(random_bytes(32));
|
||||
$siroToken = bin2hex(random_bytes(32));
|
||||
|
||||
// 4. Deduct from Sender (payments table)
|
||||
$deductAmount = -$amount;
|
||||
$stmt = $con->prepare("INSERT INTO payments (captain_id, amount, rideId, payment_method, passengerID, token)
|
||||
VALUES (:senderID, :amount, :rideId, 'cash_transfer', :receiverRef, :token)");
|
||||
$stmt->execute([
|
||||
':senderID' => $senderID,
|
||||
':amount' => $deductAmount,
|
||||
':rideId' => $paymentID1,
|
||||
':receiverRef' => 'To ' . $receiverID,
|
||||
':token' => $token1
|
||||
]);
|
||||
|
||||
// 5. Add to Receiver Points (paymentsDriverPoints table)
|
||||
$stmt = $con->prepare("INSERT INTO paymentsDriverPoints (captain_id, paymentID, amount, token, paymentMethod)
|
||||
VALUES (:receiverID, :paymentID, :amount, :token, 'Transfer')");
|
||||
$stmt->execute([
|
||||
':receiverID' => $receiverID,
|
||||
':paymentID' => $paymentID2,
|
||||
':amount' => $amountForReceiver,
|
||||
':token' => $token2
|
||||
]);
|
||||
|
||||
// 6. Add Fee to Siro Wallet
|
||||
$stmt = $con->prepare("INSERT INTO siroWallet (amount, paymentMethod, passengerId, token, driverId)
|
||||
VALUES (:fee, 'payout fee', 'driver', :token, :senderID)");
|
||||
$stmt->execute([
|
||||
':fee' => $fee,
|
||||
':token' => $siroToken,
|
||||
':senderID' => $senderID
|
||||
]);
|
||||
|
||||
// Commit Transaction
|
||||
$con->commit();
|
||||
|
||||
echo json_encode(['status' => 'success', 'message' => 'Transfer completed successfully on payment server']);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$con->rollBack();
|
||||
error_log('[transfer] Error: ' . $e->getMessage());
|
||||
echo json_encode(['status' => 'error', 'message' => 'An internal error occurred.']);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user