337 lines
11 KiB
PHP
337 lines
11 KiB
PHP
<?php
|
|
// $pfHost = 'www.payfast.co.za';
|
|
function getOrderTotal($conn, $payment_id)
|
|
{
|
|
// Prepare the SQL statement
|
|
$sql = "SELECT amount FROM payments WHERE payment_id = ?";
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt) {
|
|
// Bind the parameter
|
|
$stmt->bind_param("s", $payment_id); // Assuming order_id is a string (UUID)
|
|
|
|
// Execute the statement
|
|
$stmt->execute();
|
|
|
|
// Get the result
|
|
$result = $stmt->get_result();
|
|
|
|
// Fetch the order total
|
|
if ($row = $result->fetch_assoc()) {
|
|
return $row['amount'];
|
|
} else {
|
|
return 9999.00; // Order not found
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt->close();
|
|
} else {
|
|
// Handle the error (you might want to log this or throw an exception)
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function getOrderDesc($conn, $payment_id)
|
|
{
|
|
// Prepare the SQL statement
|
|
$sql = "SELECT description FROM payments WHERE payment_id = ?";
|
|
$stmt = $conn->prepare($sql);
|
|
|
|
if ($stmt) {
|
|
// Bind the parameter
|
|
$stmt->bind_param("s", $payment_id); // Assuming order_id is a string (UUID)
|
|
|
|
// Execute the statement
|
|
$stmt->execute();
|
|
|
|
// Get the result
|
|
$result = $stmt->get_result();
|
|
|
|
// Fetch the order total
|
|
if ($row = $result->fetch_assoc()) {
|
|
return $row['description'];
|
|
} else {
|
|
return null; // Order not found
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt->close();
|
|
} else {
|
|
// Handle the error (you might want to log this or throw an exception)
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function getUserIdByPaymentId($payment_id, $conn)
|
|
{
|
|
// Prepare the SQL query to fetch user_id from payments table
|
|
$query = "SELECT user_id FROM payments WHERE payment_id = ?";
|
|
$user_id = "0";
|
|
// Prepare the statement
|
|
if ($stmt = $conn->prepare($query)) {
|
|
// Bind the payment_id parameter to the query
|
|
$stmt->bind_param("s", $payment_id);
|
|
|
|
// Execute the query
|
|
$stmt->execute();
|
|
|
|
// Bind the result to a variable
|
|
$stmt->bind_result($user_id);
|
|
|
|
// Fetch the result
|
|
if ($stmt->fetch()) {
|
|
// Return the user_id
|
|
return $user_id;
|
|
} else {
|
|
// Return null if no user is found
|
|
return null;
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt->close();
|
|
} else {
|
|
// Handle query preparation failure
|
|
throw new Exception("Query preparation failed: " . $conn->error);
|
|
}
|
|
}
|
|
|
|
function setMemberStatus($user_id, $conn)
|
|
{
|
|
// Prepare the SQL query to update the member status
|
|
$query = "UPDATE users SET member = 1 WHERE user_id = ?";
|
|
|
|
// Prepare the statement
|
|
if ($stmt = $conn->prepare($query)) {
|
|
// Bind the user_id parameter to the query
|
|
$stmt->bind_param("i", $user_id);
|
|
|
|
// Execute the query
|
|
if ($stmt->execute()) {
|
|
// Check if any rows were affected
|
|
if ($stmt->affected_rows > 0) {
|
|
return true; // Success
|
|
} else {
|
|
return false; // No rows updated, possibly no such user_id
|
|
}
|
|
} else {
|
|
// Handle query execution failure
|
|
throw new Exception("Failed to execute the query: " . $stmt->error);
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt->close();
|
|
} else {
|
|
// Handle query preparation failure
|
|
throw new Exception("Query preparation failed: " . $conn->error);
|
|
}
|
|
}
|
|
|
|
function pfValidSignature($pfData, $pfParamString, $pfPassphrase = 'SheSells7Shells')
|
|
{
|
|
$tempParamString = $pfPassphrase === null ? $pfParamString : $pfParamString . '&passphrase=' . urlencode($pfPassphrase);
|
|
$signature = md5($tempParamString);
|
|
return ($pfData['signature'] === $signature);
|
|
}
|
|
|
|
function pfValidIP()
|
|
{
|
|
$validHosts = [
|
|
'www.payfast.co.za',
|
|
'sandbox.payfast.co.za',
|
|
'w1w.payfast.co.za',
|
|
'w2w.payfast.co.za',
|
|
];
|
|
|
|
$validIps = [];
|
|
foreach ($validHosts as $pfHostname) {
|
|
$ips = gethostbynamel($pfHostname);
|
|
if ($ips !== false) {
|
|
$validIps = array_merge($validIps, $ips);
|
|
}
|
|
}
|
|
|
|
$validIps = array_unique($validIps);
|
|
$referrerIp = gethostbyname(parse_url($_SERVER['HTTP_REFERER'])['host']);
|
|
return in_array($referrerIp, $validIps, true);
|
|
}
|
|
|
|
function pfValidPaymentData($cartTotal, $pfData)
|
|
{
|
|
return !(abs((float)$cartTotal - (float)$pfData['amount_gross']) > 0.01);
|
|
}
|
|
|
|
function pfValidServerConfirmation($pfParamString, $pfHost, $pfProxy = null)
|
|
{
|
|
if (in_array('curl', get_loaded_extensions(), true)) {
|
|
$url = 'https://' . $pfHost . '/eng/query/validate';
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_USERAGENT, NULL);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_HEADER, false);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $pfParamString);
|
|
if (!empty($pfProxy)) curl_setopt($ch, CURLOPT_PROXY, $pfProxy);
|
|
|
|
$response = curl_exec($ch);
|
|
curl_close($ch);
|
|
return $response === 'VALID';
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
// Tell Payfast that this page is reachable by triggering a header 200
|
|
header('HTTP/1.0 200 OK');
|
|
flush();
|
|
|
|
$dbhost = "localhost";
|
|
$dbuser = "aqmqeocm_4wdcsa";
|
|
$dbpass = "Toxicbuny1!";
|
|
$dbname = "aqmqeocm_4wdcsa";
|
|
|
|
if (!$conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname)) {
|
|
die("Failed to connect: " . mysqli_connect_error());
|
|
}
|
|
|
|
define('SANDBOX_MODE', true);
|
|
$pfHost = SANDBOX_MODE ? 'sandbox.payfast.co.za' : 'www.payfast.co.za';
|
|
// Posted variables from ITN
|
|
$pfData = $_POST;
|
|
$payment_id = $pfData['m_payment_id'];
|
|
$pfstatus = $pfData['payment_status'];
|
|
$orderTotal = getOrderTotal($conn, $payment_id);
|
|
$description = getOrderDesc($conn, $payment_id);
|
|
$user_id = getUserIdByPaymentId($payment_id, $conn);
|
|
|
|
// Strip any slashes in data
|
|
foreach ($pfData as $key => $val) {
|
|
$pfData[$key] = stripslashes($val);
|
|
}
|
|
|
|
// Convert posted variables to a string
|
|
$pfParamString = '';
|
|
foreach ($pfData as $key => $val) {
|
|
if ($key !== 'signature') {
|
|
$pfParamString .= $key . '=' . urlencode($val) . '&';
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
$pfParamString = rtrim($pfParamString, '&');
|
|
|
|
// Initialize check results
|
|
$checkResults = [];
|
|
|
|
// Perform checks
|
|
if (!pfValidSignature($pfData, $pfParamString)) {
|
|
$checkResults[] = "Signature check failed.";
|
|
}
|
|
if (!pfValidIP()) {
|
|
$checkResults[] = "IP check failed.";
|
|
}
|
|
if (!pfValidPaymentData($orderTotal, $pfData)) {
|
|
$checkResults[] = "Payment data check failed. order= " . $payment_id . " 4WDCSA_Total=" . $orderTotal . " PFtotal=" . $pfData['amount_gross'];
|
|
}
|
|
if (!pfValidServerConfirmation($pfParamString, $pfHost)) {
|
|
$checkResults[] = "Server confirmation check failed.";
|
|
}
|
|
|
|
// Log results to the file
|
|
$myfile = fopen($payment_id . ".txt", "w") or die("Unable to open file!");
|
|
if (empty($checkResults)) {
|
|
fwrite($myfile, "Starting database update process for payment ID: $payment_id\n");
|
|
fwrite($myfile, "Payment status: $pfstatus\n");
|
|
|
|
// Begin database transaction
|
|
$conn->begin_transaction();
|
|
fwrite($myfile, "Transaction started.\n");
|
|
|
|
try {
|
|
// Step 1: Update payments table
|
|
fwrite($myfile, "Preparing to update payments table...\n");
|
|
$stmt = $conn->prepare("UPDATE payments SET status = ? WHERE payment_id = ?");
|
|
if (!$stmt) {
|
|
throw new Exception("Failed to prepare statement for payments table: " . $conn->error);
|
|
}
|
|
|
|
fwrite($myfile, "Prepared statement for payments table.\n");
|
|
$status = "PAID"; // Explicitly set the status to "PAID"
|
|
$stmt->bind_param("ss", $status, $payment_id);
|
|
fwrite($myfile, "Bound parameters for payments table update.\n");
|
|
|
|
if (!$stmt->execute()) {
|
|
throw new Exception("Failed to execute update for payments table: " . $stmt->error);
|
|
}
|
|
fwrite($myfile, "Payments table updated successfully.\n");
|
|
$stmt->close();
|
|
fwrite($myfile, "Closed statement for payments table update.\n");
|
|
|
|
// Step 2: Update membership_fees table
|
|
fwrite($myfile, "Preparing to update membership_fees table...\n");
|
|
$stmt = $conn->prepare("UPDATE membership_fees SET payment_status = ? WHERE payment_id = ?");
|
|
if (!$stmt) {
|
|
throw new Exception("Failed to prepare statement for membership_fees table: " . $conn->error);
|
|
}
|
|
|
|
fwrite($myfile, "Prepared statement for membership_fees table.\n");
|
|
$status = "PAID"; // Explicitly set the status to "PAID"
|
|
$stmt->bind_param("ss", $status, $payment_id);
|
|
fwrite($myfile, "Bound parameters for membership_fees table update.\n");
|
|
|
|
if (!$stmt->execute()) {
|
|
throw new Exception("Failed to execute update for membership_fees table: " . $stmt->error);
|
|
}
|
|
fwrite($myfile, "Membership_fees table updated successfully.\n");
|
|
$stmt->close();
|
|
fwrite($myfile, "Closed statement for membership_fees table update.\n");
|
|
|
|
// Step 3: Set member status
|
|
fwrite($myfile, "Calling setMemberStatus()...\n");
|
|
setMemberStatus($user_id, $conn);
|
|
fwrite($myfile, "setMemberStatus() executed successfully.\n");
|
|
|
|
// Commit transaction
|
|
$conn->commit();
|
|
fwrite($myfile, "Transaction committed successfully. Database updates complete.\n");
|
|
} catch (Exception $e) {
|
|
// Rollback transaction in case of error
|
|
$conn->rollback();
|
|
fwrite($myfile, "Transaction rolled back due to error: " . $e->getMessage() . "\n");
|
|
}
|
|
} else {
|
|
fwrite($myfile, $pfstatus . "\n");
|
|
foreach ($checkResults as $result) {
|
|
fwrite($myfile, $result . "\n");
|
|
}
|
|
|
|
$conn->begin_transaction();
|
|
|
|
try {
|
|
// Update payments table with 'FAILED CHECKS' status
|
|
$stmt = $conn->prepare("UPDATE payments SET status = 'FAILED CHECKS' WHERE payment_id = ?");
|
|
$stmt->bind_param("i", $payment_id);
|
|
|
|
if (!$stmt->execute()) {
|
|
throw new Exception("Failed to update payments table.");
|
|
}
|
|
|
|
|
|
// Commit transaction
|
|
$conn->commit();
|
|
fwrite($myfile, "Database updated successfully.\n");
|
|
} catch (Exception $e) {
|
|
// Rollback transaction in case of error
|
|
$conn->rollback();
|
|
fwrite($myfile, "Database update failed: " . $e->getMessage() . "\n");
|
|
}
|
|
|
|
$stmt->close();
|
|
}
|
|
|
|
fclose($myfile);
|
|
$conn->close();
|