Blank Screen on Step 2 of the Checkout Process in my PLAINTCART project !
checkout.php

<?php
require_once 'library/config.php';
require_once 'library/cart-functions.php';
require_once 'library/checkout-functions.php';
if (isCartEmpty()) {
   // the shopping cart is still empty
   // so checkout is not allowed
   header('Location: cart.php');
} else if (isset($_GET['step'])
           && (int)$_GET['step'] > 0
           && (int)$_GET['step'] <= 3) {
   $step = (int)$_GET['step'];
   $includeFile = '';
   if ($step == 1){
      $includeFile = 'shippingAndPaymentInfo.php';
      $pageTitle = 'Checkout - Step 1 of 2';
   } else if ($step == 2) {
      $includeFile = 'checkoutConfirmation.php';
      $pageTitle = 'Checkout - Step 2 of 2';
   } else if ($step == 3) {
      $orderId = saveOrder();
      $orderAmount = getOrderAmount($orderId);
     $_SESSION['orderId'] = $orderId;
      // our next action depends on the payment method
      // if the payment method is COD then show the
      // success page but when paypal is selected
      // send the order details to paypal
      if ($_POST['hidPaymentMethod'] == 'cod') {
         header('Location: success.php');
         exit;
      } else {
         $includeFile = 'paypal/payment.php';
      }
   }
} else {
   // missing or invalid step number, just redirect
   header('Location: index.php');
}
require_once 'include/header.php';
?>
<script language="JavaScript" type="text/javascript" src="library/checkout.js"></script>
<?php
require_once "include/$includeFile";
require_once 'include/footer.php';
?>

shippingAndPaymentInfo

<?php
if (!defined('WEB_ROOT')
    || !isset($_GET['step']) || (int)$_GET['step'] != 1) {
	exit;
}

$errorMessage = '&nbsp;';
?>
<script language="JavaScript" type="text/javascript" src="library/checkout.js"></script>
<table width="550" border="0" align="center" cellpadding="10" cellspacing="0">
    <tr> 
        <td>Hapi 1 nga 3 : Vendosi informacionet e Transportit dhe pages&euml;s</td>
    </tr>
</table>
<p id="errorMessage"><?php echo $errorMessage; ?></p>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?step=2" method="post" name="frmCheckout" id="frmCheckout" onSubmit="return checkShippingAndPaymentInfo();">
    <table width="550" border="0" align="center" cellpadding="5" cellspacing="1" class="entryTable">
        <tr class="entryTableHeader"> 
            <td colspan="2">Informacionet e Transportit</td>
        </tr>
        <tr> 
            <td width="150" class="label">Emri</td>
            <td class="content"><input name="txtShippingFirstName" type="text" class="box" id="txtShippingFirstName" size="30" maxlength="50"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Mbiemri</td>
            <td class="content"><input name="txtShippingLastName" type="text" class="box" id="txtShippingLastName" size="30" maxlength="50"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Adresa 1</td>
            <td class="content"><input name="txtShippingAddress1" type="text" class="box" id="txtShippingAddress1" size="50" maxlength="100"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Adresa 2</td>
            <td class="content"><input name="txtShippingAddress2" type="text" class="box" id="txtShippingAddress2" size="50" maxlength="100"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Numri i telefonit</td>
            <td class="content"><input name="txtShippingPhone" type="text" class="box" id="txtShippingPhone" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Shteti</td>
            <td class="content"><input name="txtShippingState" type="text" class="box" id="txtShippingState" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Qyteti</td>
            <td class="content"><input name="txtShippingCity" type="text" class="box" id="txtShippingCity" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Kodi postal</td>
            <td class="content"><input name="txtShippingPostalCode" type="text" class="box" id="txtShippingPostalCode" size="10" maxlength="10"></td>
        </tr>
    </table>
  <p>&nbsp;</p>
    <table width="550" border="0" align="center" cellpadding="5" cellspacing="1" class="entryTable">
        <tr class="entryTableHeader"> 
            <td width="150">Informacionet e pages&euml;s</td>
            <td><input type="checkbox" name="chkSame" id="chkSame" value="checkbox" onClick="setPaymentInfo(this.checked);"> 
                <label for="chkSame" style="cursor:pointer">T&euml; njejtat ashtu sic tek transporti</label></td>
        </tr>
        <tr> 
            <td width="150" class="label">Emri</td>
            <td class="content"><input name="txtPaymentFirstName" type="text" class="box" id="txtPaymentFirstName" size="30" maxlength="50"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Mbiemri</td>
            <td class="content"><input name="txtPaymentLastName" type="text" class="box" id="txtPaymentLastName" size="30" maxlength="50"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Adresa 1</td>
            <td class="content"><input name="txtPaymentAddress1" type="text" class="box" id="txtPaymentAddress1" size="50" maxlength="100"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Adresa 2 </td>
            <td class="content"><input name="txtPaymentAddress2" type="text" class="box" id="txtPaymentAddress2" size="50" maxlength="100"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Numri i telefonit</td>
            <td class="content"><input name="txtPaymentPhone" type="text" class="box" id="txtPaymentPhone" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Shteti</td>
            <td class="content"><input name="txtPaymentState" type="text" class="box" id="txtPaymentState" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Qyteti</td>
            <td class="content"><input name="txtPaymentCity" type="text" class="box" id="txtPaymentCity" size="30" maxlength="32"></td>
        </tr>
        <tr> 
            <td width="150" class="label">Kodi postal</td>
            <td class="content"><input name="txtPaymentPostalCode" type="text" class="box" id="txtPaymentPostalCode" size="10" maxlength="10"></td>
        </tr>
    </table>
    <p>&nbsp;</p>
    <table width="550" border="0" align="center" cellpadding="5" cellspacing="1" class="entryTable">
      <tr>
        <td width="150" class="entryTableHeader">M&euml;nyra e pages&euml;s</td>
        <td class="content">
        <input name="optPayment" type="radio" id="optPaypal" value="paypal" checked="checked" />
        <label for="optPaypal" style="cursor:pointer">Paypal</label>
        <input name="optPayment" type="radio" value="cod" id="optCod" />
        <label for="optCod" style="cursor:pointer"><span id="result_box" lang="sq" xml:lang="sq">Pages&euml; pas dor&euml;zimit t&euml; mallit</span></label></td>
      </tr>
    </table>
    <p>&nbsp;</p>
    <p align="center"> 
        <input class="box" name="btnStep1" type="submit" id="btnStep1" value="Vazhdo &gt;&gt;">
    </p>
</form>

Dani AI

Generated

posted the key files; the most likely reason step 2 renders “blank” is the strict referer check inside the confirmation include. Relying on an exact match of $_SERVER['HTTP_REFERER'] is brittle: browsers or proxies can omit or alter that header, HTTPS vs HTTP or www vs non‑www differences will break an exact string comparison, and the include will simply call exit — which looks like a blank page even though the header was already sent.

Recommended troubleshooting (safe, non‑destructive):

  • Temporarily enable full error reporting and check the server error log to reveal hidden warnings/fatals:

    ini_set('display_errors', 1);
    error_reporting(E_ALL);
  • Inspect the network request in browser DevTools to see what Referer is actually being sent (if any).

  • As a quick test, comment out or relax the referer check; if the confirmation displays, the referer guard is the culprit.

Suggested fixes (more robust and secure):

  • Stop using HTTP_REFERER for flow control. Adopt POST/Redirect/GET and store validated step‑1 data in the session, then redirect to step 2. Example pattern:

    if ($_SERVER['REQUEST_METHOD'] === 'POST' && (int)$_GET['step'] === 1) {
        $_SESSION['checkout'] = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
        header('Location: checkout.php?step=2');
        exit;
    }
  • Alternatively, require a hidden token or check $_SERVER['REQUEST_METHOD'] === 'POST' on the confirmation include instead of comparing referer:

    if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['step_token'])) { exit; }

Other gotchas spotted in the thread: the payment input name used in the form (optPayment) does not match the name later read (hidPaymentMethod). Normalize names or read both to avoid missing values:

$payment = isset($_POST['optPayment']) ? $_POST['optPayment'] : (isset($_POST['hidPaymentMethod']) ? $_POST['hidPaymentMethod'] : 'paypal');

This approach removes fragile referer checks, prevents accidental blank pages, and makes the flow safer and easier to debug. 's remark about verbosity is fair, but a few targeted tests above will pinpoint the failure quickly.

Recommended Answers

All 2 Replies

too much detailed information is posted.

i think here is a problem ! checkoutconfirmation.php

/*
Line 1 : Make sure this file is included instead of requested directly
Line 2 : Check if step is defined and the value is two
Line 3 : The POST request must come from this page but the value of step is one
*/
if (!defined('WEB_ROOT')
    || !isset($_GET['step']) || (int)$_GET['step'] != 2
	|| $_SERVER['HTTP_REFERER'] != 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?step=1'){
	exit;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.