Files
intaleq_driver/plans/process_ride_payments.php

142 lines
5.3 KiB
PHP

<?php
/**
* process_ride_payments.php — Payment Processing Server
*
* Receives S2S (Server-to-Server) requests from finish_ride_updates.php.
* Authenticated via X-S2S-Api-Key header matching a shared secret.
*
* Flow:
* 1. Validate X-S2S-Api-Key header
* 2. BEGIN TRANSACTION
* 3. Insert payment record
* 4. Deduct from passenger wallet (if walletChecked)
* 5. Settle passenger debt (if negative balance)
* 6. Deduct driver points (8%)
* 7. COMMIT / ROLLBACK on failure
*/
// Adjust path as needed for your payment server structure
require_once __DIR__ . '/../../jwtconnect.php';
// === Secure S2S Configuration ===
define('S2S_SHARED_KEY', getenv('S2S_SHARED_KEY'));
// ============================================================
// 1. API Key Authentication (X-S2S-Api-Key header)
// ============================================================
$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;
}
// ============================================================
// 2. Receive All Required Parameters
// ============================================================
$rideId = filterRequest("rideId");
$driverId = filterRequest("driverId");
$passengerId = filterRequest("passengerId");
$paymentAmount = filterRequest("paymentAmount");
$paymentMethod = filterRequest("paymentMethod");
$walletChecked = filterRequest("walletChecked"); // 'true' or 'false'
$passengerWalletBurc = filterRequest("passengerWalletBurc"); // passenger balance before operation
$authToken = filterRequest("authToken"); // kept for logging/audit, not used for auth
// --- Validate required fields ---
if (empty($rideId) || empty($driverId) || empty($passengerId) ||
!isset($paymentAmount) || empty($paymentMethod) ||
!isset($walletChecked) || !isset($passengerWalletBurc)) {
printFailure("Missing required parameters for payment processing.");
exit;
}
// ============================================================
// 3. Atomic Payment Processing
// ============================================================
try {
// --- Begin Transaction ---
$con->beginTransaction();
// 3a. Insert main payment record
$finalPaymentMethod = ($walletChecked === 'true') ? $paymentMethod . "Ride" : $paymentMethod;
$stmtPayment = $con->prepare(
"INSERT INTO payments (id, amount, payment_method, passengerID, rideId, driverID)
VALUES (UUID_SHORT(), :amount, :payment_method, :passengerID, :rideId, :driverID)"
);
$stmtPayment->execute([
':amount' => $paymentAmount,
':payment_method' => $finalPaymentMethod,
':passengerID' => $passengerId,
':rideId' => $rideId,
':driverID' => $driverId,
]);
if ($stmtPayment->rowCount() <= 0) {
throw new Exception("Failed to create payment record.");
}
// 3b. Deduct from passenger wallet (if wallet payment)
if ($walletChecked === 'true') {
$stmtPassengerWallet = $con->prepare(
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
VALUES (:passenger_id, :balance)"
);
$stmtPassengerWallet->execute([
':passenger_id' => $passengerId,
':balance' => (-1) * floatval($paymentAmount),
]);
if ($stmtPassengerWallet->rowCount() <= 0) {
throw new Exception("Failed to deduct from passenger wallet.");
}
}
// 3c. Settle existing passenger debt (if balance was negative)
if (floatval($passengerWalletBurc) < 0) {
$stmtPassengerDebt = $con->prepare(
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
VALUES (:passenger_id, :balance)"
);
$stmtPassengerDebt->execute([
':passenger_id' => $passengerId,
':balance' => (-1) * floatval($passengerWalletBurc),
]);
if ($stmtPassengerDebt->rowCount() <= 0) {
throw new Exception("Failed to settle passenger debt.");
}
}
// 3d. Deduct driver points (8% of payment amount)
$pointsSubtraction = floatval($paymentAmount) * (-0.08);
$stmtDriverPoints = $con->prepare(
"INSERT INTO `driverWallet` (`driverID`, `paymentID`, `amount`, `paymentMethod`)
VALUES (:driverID, :paymentID, :amount, :paymentMethod)"
);
$stmtDriverPoints->execute([
':driverID' => $driverId,
':paymentID' => 'rideId' . $rideId,
':amount' => number_format($pointsSubtraction, 0, '', ''),
':paymentMethod' => $paymentMethod,
]);
if ($stmtDriverPoints->rowCount() <= 0) {
throw new Exception("Failed to update driver wallet points.");
}
// --- All operations succeeded → Commit ---
$con->commit();
printSuccess("Payment processed successfully for ride $rideId.");
} catch (Exception $e) {
// --- Any failure → Rollback all changes ---
if (isset($con) && $con->inTransaction()) {
$con->rollBack();
}
error_log("[process_ride_payments] Transaction FAILED for ride $rideId: " . $e->getMessage());
printFailure("Transaction failed: " . $e->getMessage());
}