prepare( "SELECT payment_id, user_id, booking_id, description FROM payments WHERE payment_id = ? LIMIT 1" ); if ($stmt) { $stmt->bind_param('s', $externalTransactionID); $stmt->execute(); $res = $stmt->get_result(); if ($row = $res->fetch_assoc()) { $localPaymentId = $row['payment_id']; $booking_id = $row['booking_id']; $user_id = $row['user_id']; $description = $row['description']; } $stmt->close(); } } if (!$localPaymentId && $providerPaymentId) { $stmt = $conn->prepare( "SELECT payment_id, user_id, booking_id, description FROM payments WHERE provider_payment_id = ? LIMIT 1" ); if ($stmt) { $stmt->bind_param('s', $providerPaymentId); $stmt->execute(); $res = $stmt->get_result(); if ($row = $res->fetch_assoc()) { $localPaymentId = $row['payment_id']; $booking_id = $row['booking_id']; $user_id = $row['user_id']; $description = $row['description']; } $stmt->close(); } } if (!$localPaymentId) { http_response_code(404); progress_log('iKhokha webhook: payment not found'); progress_log(json_encode([$externalTransactionID, $providerPaymentId])); exit('Payment not found'); } /** * ========================================================== * Persist provider response * ========================================================== */ $update = $conn->prepare( "UPDATE payments SET provider_payment_id = ?, provider_status = ?, provider_response = ? WHERE payment_id = ?" ); if ($update) { $update->bind_param( 'ssss', $providerPaymentId, $providerStatus, $raw, $localPaymentId ); $update->execute(); $update->close(); } /** * ========================================================== * Normalize status and apply business logic * ========================================================== */ $normalized = strtoupper(trim((string)$providerStatus)); if (in_array($normalized, ['PAID', 'SUCCESS', 'COMPLETED', 'SETTLED'], true)) { // Mark payment as PAID $setPaid = $conn->prepare( "UPDATE payments SET status = 'PAID' WHERE payment_id = ?" ); if ($setPaid) { $setPaid->bind_param('s', $localPaymentId); $setPaid->execute(); $setPaid->close(); } // Booking or membership update if (!empty($booking_id)) { $upd = $conn->prepare( "UPDATE bookings SET status = 'PAID' WHERE booking_id = ?" ); if ($upd) { $upd->bind_param('i', $booking_id); $upd->execute(); $upd->close(); sendAdminNotification('4WDCSA.co.za - New Booking - '.getFullName($user_id) , 'We have received a payment for a new booking for '.$description.' from '.getFullName($user_id)); } } else { $upd = $conn->prepare( "UPDATE membership_fees SET payment_status = 'PAID' WHERE payment_id = ?" ); if ($upd) { $upd->bind_param('s', $localPaymentId); $upd->execute(); $upd->close(); sendAdminNotification('4WDCSA.co.za - Membership Payment Received - '.getFullName($user_id) , 'A Membership Payment has been received from '.getFullName($user_id)); } } // Send confirmation email if (!empty($user_id)) { sendPaymentConfirmation( getEmail($user_id), getFullName($user_id), $description ); } } /** * ========================================================== * Acknowledge webhook * ========================================================== */ http_response_code(200); echo 'OK';