It’s all working. Thank you so much for the help l just needed to interchange the resultUrl and returnUrl position. the code is here <?php
// initiate_transaction.php - Displays order summary and initiates Paynow transaction
ini_set(‘display_errors’, 1);
ini_set(‘display_startup_errors’, 1);
error_reporting(E_ALL);
require_once DIR . ‘/…/vendor/autoload.php’;
require_once DIR . ‘/db_connection.php’; // Your DB connection
// — Check if DB connection is valid —
if (!$db) {
error_log(“Initiate Transaction: Database connection failed. Check db_connection.php.”);
echo “Database connection error. Please try again later.”;
exit();
}
// Load environment variables
try {
$dotenv = Dotenv\Dotenv::createImmutable(DIR . ‘/…’);
$dotenv->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
error_log("Initiate Transaction: Dotenv Error: " . $e->getMessage());
echo “Error loading environment configuration. Please try again later.”;
exit();
}
$integrationId = $_ENV[‘PAYNOW_INTEGRATION_ID’] ?? null;
$integrationKey = $_ENV[‘PAYNOW_INTEGRATION_KEY’] ?? null;
if (!$integrationId || !$integrationKey) {
error_log(‘Initiate Transaction: Paynow credentials missing.’);
echo ‘Paynow credentials not configured.’;
exit();
}
// 1. Get order_reference from GET parameter
$order_reference = $_GET[‘order_reference’] ?? null;
if (!$order_reference) {
error_log(“Initiate Transaction: Error: Order reference is missing from URL.”);
echo “Error: Order reference is missing.”;
exit();
}
// 2. Fetch order details from your database using the order_reference
$stmt = $db->prepare(“SELECT customer_email, total_amount, status FROM orders WHERE order_reference = ?”);
// — ERROR CHECKING FOR PREPARE STATEMENT —
if ($stmt === false) {
error_log("Initiate Transaction: Database prepare error for SELECT order details: " . $db->error);
echo “Database error fetching order details. Please try again later.”;
exit();
}
// — END ERROR CHECKING —
$stmt->bind_param(“s”, $order_reference);
$stmt->execute();
$result = $stmt->get_result();
$order = $result->fetch_assoc();
$stmt->close();
if (!$order) {
error_log(“Initiate Transaction: Error: Order not found for reference: " . $order_reference . " in DB.”);
echo "Error: Order not found for reference: " . htmlspecialchars($order_reference);
exit();
}
// Ensure the order status is still pending before initiating payment
if ($order[‘status’] !== ‘PENDING’) {
error_log("Initiate Transaction: Order " . $order_reference . " is not in PENDING status. Current status: " . $order[‘status’]);
echo “This order has already been processed or is not in a pending state.”;
exit();
}
$customer_email = $order[‘customer_email’];
$cart_total = $order[‘total_amount’]; // Use total_amount from DB
// Set your resultUrl and returnUrl (browserUrl)
// IMPORTANT: Adjust these to your live domain
$resultUrl = ‘https://xxx.co.zw/xxx/public/paynow_update.php?order_reference=’ . urlencode($order_reference);
$returnUrl = ‘https://xxx.co.zw/xxx/public/order_complete.php?order_reference=’ . urlencode($order_reference); // Optional: add order_reference for display
// Check if the form was submitted to initiate payment
if (isset($_POST[‘initiate_payment’])) {
try {
$paynow = new Paynow\Payments\Paynow(
$integrationId,
$integrationKey,
$returnUrl,// Interchange these 2 with resultUrl ontop then followed by resultUrl
$resultUrl
);
$payment = $paynow->createPayment($order_reference, $customer_email);
$payment->add($order_reference, $cart_total); // Add item (you might want to add more specific items here)
$response = $paynow->send($payment);
if ($response->success()) {
$pollUrl = $response->pollUrl(); // Get the pollUrl from Paynow's response
$paynowReference = null;
// --- NEW LOGIC: Extract guid from pollUrl ---
$parsedUrl = parse_url($pollUrl);
if (isset($parsedUrl['query'])) {
parse_str($parsedUrl['query'], $query_params);
if (isset($query_params['guid'])) {
$paynowReference = $query_params['guid'];
error_log("Initiate Transaction: DEBUG: Extracted Paynow Reference (GUID) from pollUrl: " . $paynowReference);
}
}
// --- END NEW LOGIC ---
if (empty($paynowReference)) {
error_log("Initiate Transaction: Critical Error: Could not obtain Paynow Reference for order " . $order_reference . ". Full response object: " . print_r($response, true));
echo "Critical error: Could not obtain Paynow Reference.";
exit();
}
// Crucially: Store the pollUrl and PaynowReference in your database
// so paynow_update.php can retrieve it later using order_reference
// CHANGED: paynow_pollurl to paynow_poll_url to match DB column name
$update_stmt = $db->prepare("UPDATE orders SET paynow_poll_url = ?, paynow_reference = ?, status = 'INITIATED' WHERE order_reference = ?");
// --- ERROR CHECKING FOR PREPARE STATEMENT ---
if ($update_stmt === false) {
error_log("Initiate Transaction: Database prepare error for UPDATE pollUrl: " . $db->error);
echo "Database error preparing order for payment.";
exit();
}
// --- END ERROR CHECKING ---
if ($update_stmt) {
$update_stmt->bind_param("sss", $pollUrl, $paynowReference, $order_reference);
$update_stmt->execute();
$update_stmt->close();
error_log("Initiate Transaction: Paynow transaction initiated for order " . $order_reference . ". Poll URL stored: " . $pollUrl);
} else {
error_log("Initiate Transaction: Error preparing DB statement to save pollUrl for order " . $order_reference . ": " . $db->error);
echo "Error preparing order for payment.";
exit();
}
// Redirect the user to Paynow's payment page
header("Location: " . $response->redirectUrl());
exit();
} else {
$error_message = "Initiate Transaction: Paynow initiation failed: " . print_r($response->errors(), true);
error_log($error_message);
echo "Error initiating payment. Please try again. " . implode(", ", $response->errors());
exit();
}
} catch (\Exception $e) {
error_log("Initiate Transaction: Exception during Paynow initiation for order " . $order_reference . ": " . $e->getMessage());
echo "An unexpected error occurred during payment initiation.";
exit();
}
}
// — Now include header.php after all potential redirects —
include ‘header.php’;
?>
<style>
/* Styles copied directly from cart.php for consistency */
body {
font-family: 'Georgia', serif;
line-height: 1.6;
color: #333;
}
.page-section {
padding: 60px 0;
}
.classic-container {
background-color: #f8f8f8;
border: 1px solid #ddd;
padding: 40px;
margin-top: 30px;
margin-bottom: 30px;
box-shadow: 5px 5px 15px rgba(0,0,0,0.1);
max-width: 900px;
margin-left: auto;
margin-right: auto;
}
.classic-container h1,
.classic-container h2,
.classic-container h3 {
font-family: 'Times New Roman', serif;
color: #555;
margin-bottom: 20px;
}
.classic-container p {
margin-bottom: 15px;
}
.classic-container ul {
list-style: disc;
margin-left: 20px;
margin-bottom: 15px;
}
.classic-container ul li {
margin-bottom: 5px;
}
.classic-container .table {
margin-top: 20px;
border-collapse: collapse;
width: 100%;
}
.classic-container .table th,
.classic-container .table td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
.classic-container .table th {
background-color: #e9e9e9;
font-weight: bold;
}
.classic-container .table tfoot td {
font-weight: bold;
}
.classic-container .btn-paynow {
background-color: #1a73e8;
border-color: #1a73e8;
color: white;
font-size: 1.2rem;
padding: 10px 20px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.classic-container .btn-paynow:hover {
background-color: #0f5ac9;
border-color: #0f5ac9;
}
/* Style for the SVG image button (if used) */
.classic-container .paynow-image-button {
display: inline-block; /* Allows margin/padding if needed */
border: none; /* No border for the image */
padding: 0; /* No padding for the image */
cursor: pointer; /* Indicate it's clickable */
max-width: 250px; /* Adjust max width as needed for your SVG */
height: auto; /* Maintain aspect ratio */
margin-top: 20px; /* Example margin */
}
.page-section.bg-light.text-dark h2,
.page-section.bg-light.text-dark h3,
.page-section.bg-light.text-dark p,
.page-section.bg-light.text-dark a,
.page-section.bg-light.text-dark ul,
.page-section.bg-light.text-dark li {
color: #212529 !important;
}
.page-section.bg-light.text-dark .text-muted {
color: #6c757d !important;
}
</style>
<section class="page-section py-5 bg-light text-dark">
<div class="container classic-container">
<h1 class="text-center">Confirm Your Order</h1>
<p>Order Reference: <strong><?php echo htmlspecialchars($order_reference); ?></strong></p>
<p>Total Amount: <strong>ZWL$<?php echo htmlspecialchars(number_format($cart_total, 2)); ?></strong></p>
<p>Customer Email: <strong><?php echo htmlspecialchars($customer_email); ?></strong></p>
<form action="" method="POST">
<button type="submit" name="initiate_payment" class="btn btn-primary btn-xl">Proceed to Pay with Paynow</button>
</form>
<p class="text-center mt-3"><a href="cart.php" class="btn btn-outline-primary">Back to Cart</a></p>
</div>
</section>
<section class="page-section py-5 text-white text-center" style="background: rgba(0, 0, 0, 0.7);">
<div class="container">
<h2 class="mt-0">Need Assistance with Your Order?</h2>
<hr class="divider bg-light my-4">
<p class="mb-5">
If you have any questions about your order or need help with the payment process, please contact us.
</p>
<button class="btn btn-primary btn-xl" title="Get Help with Order" aria-label="Get Help with Order" data-toggle="modal" data-target="#quoteModal">Get Help</button>
</div>
</section>
<?php
include 'quote_modal.php';
include 'footer.php';
?>