0

edit #1:As you can see below I have multiple $db->query 's and I am wondering if this issue could be cause by too many calls to the database on slower connections? cause the page itself works the database calls just don't go through sometimes. IF this is the issue what would be a good solution for that?

I've been having a really hard time with this one. Some reason the database code only works 2/3rds of the time for customers. I have been unable to find a reason why it would not work for them either.

When some customers use my sight everything works fine up until the final page where the payment gateway sends me a transaction ID and a confirmation on whether or not the payment was successful(1 for yes 0 for no). But for some reason my database line that adds the transaction is not working

$db->query("UPDATE transactions 
            SET charge_id = '{$trans_id}' 
            WHERE cart_id = '{$cart_id}'");

$cart_id is from a cookie (issue does not lie with users having cookies blocked.) Now I had previously thought that the issue lied within safari and IE (since customers with issue had these browsers) but after some testing both browsers work on my computer and a friends (just in case). So now I really do not know what the issue could be. Without the transaction ID being set the transaction will not be marked as complete which means it doesn't get registered in an admin panel inventory systems and the quantity of the item does not get updated. The ordered and items are going through and processing So the issue has to be on this page.

Current possible ideas(not sure how to fix either):

Too many db query causing issues for people with slower interenet.

Auto cycle side bar causing an issue (2nd code block)

Code:

<?php require_once 'system/init.php'; include 'includes/head.php'; include 'includes/navigation.php'; include 'includes/headerpartial.php'; include 'includes/leftbar.php'; ?>

<div id="maincontent" class="col-md-8">

<?php

if ($_GET['response_code'] == 1) { $trans_id = $_GET['transaction_id'];

$db->query("UPDATE transactions SET charge_id = '{$trans_id}' WHERE cart_id = '{$cart_id}'");
$db->query("UPDATE cart SET paid = 1 WHERE id = '{$cart_id}'");
$tsql = $db->query("SELECT * FROM transactions WHERE charge_id = '$trans_id' ");
$tran = mysqli_fetch_assoc($tsql);
$domain = '.'.$_SERVER['HTTP_HOST'];
setcookie(CART_COOKIE,'',1,"/",$domain,false);

?> <h1 id="reciept">Thank you for your support!</h1><hr> <p id="reciept"> On behalf of LettuceHeadsFarm <?=$tran['full_name']?> we thank you for your purchase and hope you enjoy it! </p>

<p id="reciept"> You have selected <b>"<?=$tran['pickup-location']?>"</b> as your pickup point. </p>

<table id="nav-button" class="table table-bordered table-auto"> <tbody> <tr> <td>Transaction ID : <?=$tran['charge_id']?></td> </tr> <?php $a = 1; $it = 1; $string = $tran['items']; $itemar = explode(',', $string); $num = 1;

$istr = $tran['inventory'];
$stri = explode(',', $istr);

if ($tran['status'] != "Complete") {

    foreach (array_slice($stri, $num) as $inve ){
        $exploded = explode('.', $inve);
        $itname = $exploded['0'];
        $itquan = $exploded['1'];

        $db->query("UPDATE products 
                     SET `quantity` = `quantity` - '$itquan' 
                    WHERE title = '$itname'");
        $db->query("UPDATE products 
                      SET `Sold` = `Sold` + '$itquan' 
                    WHERE title = '$itname'");
        $it++;
   } 
   $compl = "Complete";
   $db->query("UPDATE transactions 
                 SET `status` = '$compl' 
               WHERE charge_id = '$trans_id'");
}

foreach (array_slice($itemar, $num) as $itemr ){

?> <tr> <td><?=$itemr?></td> </tr>

<?php $a++; } ?>

<tr> <td> Total: <?=money($tran['grand_total']);?> </td> </tr> </tbody>

</table> <?php }else { echo "Sorry, an error occurred: ".htmlentities($_GET['response_reason_text']); } ?> </div>

<?php include 'includes/rightbar.php'; include 'includes/footer.php'; ?>

Sidebar Code:

<!-- right side bar-->
<div id="sidebar" class="col-md-2" >
  <div class="col-md-12" style="font-size: 75%;">
    <ul id="tabs" class="nav nav-pills" role="toolbar">
          <li role="presentation">
              <a  href="#insta"></a>
          </li>
          <li role="presentation">
              <a  href="#WHoF"></a>
          </li>
          <li role="presentation">
              <a  href="#veggie"></a>
          </li>
          <li role="presentation">
              <a  href="#social"></a>
          </li>
      </ul>
  </div>
<br />
<br />
<div class="tabContent" id="insta">
        <div class="contentText" id="aboutContent">
          <!-- LightWidget WIDGET --> -info removed instagram widget-
        </div>

    </div>
    <div class="tabContent" id="WHoF">
        <div id="whoof">

            <?php
              $sql = "SELECT * from happening ORDER BY post_date desc limit 3 offset 0;";
              $result = $db->query($sql);
              ?>
              <?php while($post = mysqli_fetch_assoc($result)) :  ?>

              <p><b><?=$post['title'];?></b></p>
              <hr>
                <p ><?= $post['entry']; ?></p>
                <hr>

                  <?php  endwhile; ?>

        </div>
    </div>
    <div class="tabContent" id="veggie">
        <div>
            <p><a href="veggie.php">
<img border="0" alt="Veggie_crate" src="../images/header/veg.png" style="width: 100%; height: 100%;" >
</a></p>

        </div>
    </div>

    <div class="tabContent" id="social">
        <div>
           -info removed. facebook widget-
        </div>
    </div>




<script>
$(document).ready(function () {
         var timeInterval, tabCount = 0, currnetIndex = 1;
         tabCount = $('ul#tabs').find('li a').length;
         var tabContentObj = $('.tabContent');
         changeTabIndex();
         timeInterval = setInterval(function () { changeTabIndex(); }, 6 * 1000);

         function changeTabIndex() {
             if (currnetIndex > tabCount) {
                 currnetIndex = 1;
             }
             tabContentObj.hide();
            $('ul#tabs').find('li.selected').removeClass('active');
             $('ul#tabs').find('li.selected').removeClass('selected');
             var currentAncorObj = $('ul#tabs').find('li a').eq(currnetIndex - 1);
             currentAncorObj.parent().addClass('selected');
              currentAncorObj.parent().addClass('active');
             $(currentAncorObj.attr('href')).show();
             currnetIndex++;
         };

         $('#tabs li').mouseenter(function () {
             clearInterval(timeInterval);
         }).mouseleave(function () {
             timeInterval = setInterval(function () { changeTabIndex(); }, 4 * 1000);
         });

         $('#tabs li a').click(function () {
             tabContentObj.hide();
              $('ul#tabs').find('li.selected').removeClass('active');
             $('ul#tabs').find('li.selected').removeClass('selected');
             var currentAncorObj = $(this);
             currnetIndex = $('ul#tabs').find('li a').index($(this)) + 1;
             currentAncorObj.parent().addClass('active');
             currentAncorObj.parent().addClass('selected');
             $(currentAncorObj.attr('href')).show();
             currnetIndex++;

             //return false;
         });
     });
</script>







</div>
Cjfidler
  • 5
  • 5
  • Crank up some error reporting and have a look at the logs – Jeff Puckett May 26 '16 at 17:35
  • How would I go about doing that? – Cjfidler May 26 '16 at 17:36
  • What web server are you running? – Jeff Puckett May 26 '16 at 17:37
  • I'm not entirely sure what you are asking would the web server be the host? (sorry! I'm still learning. ) – Cjfidler May 26 '16 at 17:41
  • It looks like the `$cart_id` and other cart information is stored in the cookie. Sounds like a corrupted cookie or cookie rejection issue. I strongly urge you to look into `prepared sql statements` – Will B. May 26 '16 at 17:42
  • Yes, this would be something like apache or nginx or iis – Jeff Puckett May 26 '16 at 17:42
  • Give me a moment Jeff I'm checking. (also to Fyrye I know. I tended to use them I just have changed this page so much trying to get it to work. I'll fix that though. thanks!) – Cjfidler May 26 '16 at 17:49
  • @JeffPuckettII I got into the SSH (from what I read I need to go there to find out) but I don't know much about SSH atm. I mostly only ever used it for connecting to cisco devices in college. It says blackboard upon login. Is that a web server or do I need to dig a little deeper? – Cjfidler May 26 '16 at 18:10
  • you might find [this answer](http://superuser.com/a/120789/571125) useful for determining which web server it's running. then you can google for where the error logs are stored. it should be specified in the virtual host configuration, although it seems like you're on a hosted service, so you might not have access or need to request it. [read this](http://stackoverflow.com/questions/845021/how-to-get-useful-error-messages-in-php) for how to enable more robust error reporting. – Jeff Puckett May 26 '16 at 18:21
  • Yeah, the person who asked me to do this for them is using dreamhost which I know little about. I'll look over those links now thanks! – Cjfidler May 26 '16 at 18:22
  • @JeffPuckettII Nameserver ns1.dreamhost.com DNS admin hostmaster@dreamhost.com Reverse DNS apache2-udder.blackboard.dreamhost.com So I assume its running apache – Cjfidler May 26 '16 at 18:26
  • You can go to a page on your site in your browser (e.g. Chrome) and press `F12` to open the developer tools. Refresh the page and view the `Response Headers` in the network tab for the page. http://imgur.com/AjWg7H7 Unless the server config has been altered to not display the Server response heder. – Will B. May 26 '16 at 19:35
  • Server:Apache. Thanks for that tip. I am pretty sure I even seen that before just never paid attention – Cjfidler May 26 '16 at 19:41

1 Answers1

0

Try to generate a log of the user request and see what's going on.

$error_code = uniqid(mt_rand(), true);

file_put_contents(__DIR__ . '/cookie_' . $error_code  . '.log', print_r($_REQUEST, 1), FILE_APPEND);

This will let you see what information is being supplied by the user during cart submission in order to troubleshoot. $_REQUEST includes $_GET, $_POST, and $_COOKIE data.

If you haven't already, you should also test for the existence of the $cart_id instead of expecting it to have been submitted with the user's request.

if (!empty($cart_id) && $_GET['response_code'] == 1) { 
    $trans_id = (int) $_GET['transaction_id'];

   ...//
}else{
   echo "Sorry, an error occurred (Error Code: " . $error_code . "): ".htmlentities($_GET['response_reason_text']);
}
Will B.
  • 17,883
  • 4
  • 67
  • 69
  • Well cart_id isn't submitted. It's in the Init file. – Cjfidler May 26 '16 at 17:59
  • Would the best place to use this error code be in the init since it is available on every page? – Cjfidler May 26 '16 at 18:04
  • You can place it anywhere you would like a log file generated of a page request and a potential error message displayed to the user. – Will B. May 26 '16 at 18:05
  • Ok thanks, I will add that now. at the very least it won't hurt to have more info – Cjfidler May 26 '16 at 18:11
  • Be sure to show the `$error_code` to the client, so that you can easily find the associated log file(s). – Will B. May 26 '16 at 18:12
  • Also always assume `$_COOKIE` is submitted/supplied by the user, just like `$_GET` or `$_POST` and never trust that what you programmed the values to be are what you are going to get. This is because all `$_REQUEST` data is accessible to and editable by the client prior to submitting a request to the server. – Will B. May 26 '16 at 18:14
  • Not sure how to show it to the client (or at least what that means) and currently that cookie just adds in the users item id ,quantity, and gives that cart and id based on the database entries ID. So in the end its just a number for what order is theirs. Not sure what good it would do to edit that – Cjfidler May 26 '16 at 18:29
  • The client (user, hacker, browser, virus) could change the data to something like `0' OR IS NOT NULL;'` Resulting in your query executing `UPDATE cart SET paid = 1 WHERE id = '0' OR IS NOT NULL;''` Just an example http://ideone.com/XXkfoB , but can be changed to anything including using anti-escaping methods. You can echo out the error_code as something useful for the user, like you have on the trans processing script (see the snippet in the answer I provided). Like `if($error) { die('Oops an error occurred!
    Error Code: ' . $error_code . '
    Please contact support@example.com'); }`
    – Will B. May 26 '16 at 19:28
  • Ah, that makes a lot of sense. Thank you for that explanation, it helped a ton. Just a quick question. Will the code provided in your original code add the data to $error on its own or do I need to set $error to equal the file_put_contents? – Cjfidler May 26 '16 at 19:36
  • You would need to set what determines an error to occur, for when you want the error message to be displayed to the client. Something like `if (true == empty($cart_id) || false === is_numeric($cart_id) || $cart_id <= 0 /* ... */){ $error = true; }` etc. – Will B. May 26 '16 at 19:40
  • Oh, I thought for some reason at first it was a pre existing error system. My bad. I do have a question in case you know, would making so many update calls to the servers database like I am cause issues with people with say slower networks? – Cjfidler May 26 '16 at 19:46
  • No, once a client makes a request to your web server (Apache), the server processes the request to determine how it is handled. In the case of PHP, there is a rule that tells Apache to execute php on the requested file. then processes it on the server-side, including all database queries, and is not affected by the client. However, downloading the response is reliant on the client, this includes the HTML code and cookie header information. Additionally JavaScript is also reliant on the client's connectivity and CPU/GPU performance. – Will B. May 26 '16 at 19:59
  • There are however rules that validate client connectivity with the web-server and will halt the running PHP process in the event of a disconnection. Additionally forcibly outputting the running script as it is being processed can impact slower connections, it is best to use `ob_start()` and `while(ob_get_level() > 0) { ob_end_flush(); }` to ensure nothing is output to the browser until it has finished processing the script. http://php.net/manual/en/book.outcontrol.php You can use `ignore_user_abort(true);` to prevent the process from halting. – Will B. May 26 '16 at 20:02
  • I have op_start loading in my helpers. which is loaded with init. But the other part of the code does not appear to be anywhere. Should I place that in the footer? ignore_user_abort(true); ? what does that do and where would it be best to place that? – Cjfidler May 26 '16 at 20:07
  • Just leave those out since the data is output upon script completion. You do not want your script to continue processing if a client aborts the connection, unless you specifically know you need it to complete, normally only needed for stateful applications like chat rooms. In general the `while... ob_end_flush` example I provided should be at the very end of your script, which would completely output the response buffer back to your client. – Will B. May 26 '16 at 20:32
  • Ok, another question based on stuff I'm reading. If mysql is failing silently there is supposed to be a line or two of code to display all sql issues. Would that be applicable here? Also thanks for taking the time to help me. Sorry about all the questions. – Cjfidler May 26 '16 at 20:38
  • It shouldn't be failing silently, but yes it could throw an exception that is not being sent to the user due to your error reporting configuration. `ini_set('error_reporting', -1); ini_set('display_errors', 'on');` to output the PHP errors to the browser or to save the errors someplace, `ini_set('log_errors', 1); ini_set('error_log', '/path/you/want/to/put/error_logs.log');` See: http://php.net/manual/en/errorfunc.configuration.php – Will B. May 26 '16 at 22:01
  • Additionally you can wrap your database queries in a `try/catch` block. See: http://php.net/manual/en/language.exceptions.php and http://php.net/manual/en/pdo.transactions.php – Will B. May 26 '16 at 22:05
  • Ok, i will try that when I can get back to my computer. Hopefully I can figure this out. – Cjfidler May 26 '16 at 22:36
  • Well its not giving me any errors in the error log. :/ That being said I can never get it to break for me in the first place! – Cjfidler May 27 '16 at 18:48
  • That's odd, did you set `ini_set('error_reporting', -1)` along with the `ini_set('log_errors', 1)` ? From what I see you should be receiving `Undefined Variable` notices at least. – Will B. May 27 '16 at 19:18
  • Oh, i mean it works. I just can't recreate the issue myself. So I'm hoping that someone will encounter the issue soon. – Cjfidler May 27 '16 at 22:15