Jump to content
Jack_mcs

Gift Vouchers Secure

Recommended Posts

Don't laugh, I'm trying: Looking at checkout_process.php around line 87 it goes:

  $payment_modules->update_status();

  if ( ($payment_modules->selected_module != $payment) || ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
    tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
  }

  require(DIR_WS_CLASSES . 'order_total.php');
  $order_total_modules = new order_total;

  $order_totals = $order_total_modules->process();

// load the before_process function from the payment modules
  $payment_modules->before_process();

I'm thinking that's where the logic to refuse total = $0 orders is. What if I was to modify it to something like this (but, you know, with proper syntax and such):

  if ($order->info['total'] > 0) {
            $payment_modules->update_status();
    }
  

  if ( ($payment_modules->selected_module != $payment) || ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
    if ($order->info['total'] > 0) {
       tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
    }
  }

  require(DIR_WS_CLASSES . 'order_total.php');
  $order_total_modules = new order_total;

  $order_totals = $order_total_modules->process();

// load the before_process function from the payment modules
   if ($order->info['total'] > 0) {
      $payment_modules->before_process();
   }

First suppressing the redirect, and then adding IFs everywhere to prevent the payment part from being invoked when the order total is $0?

I'm not sure if ($order->info['total'] > 0) is valid syntax here... I'm not sure how to get the new order total after the Gift Voucher balance has been applied.

Share this post


Link to post
Share on other sites

@cinolasI'm sorry but this is beyond the scope of this support thread. You can read through some of these to see if they help. If not,, you can create a new post in the general forum.

Share this post


Link to post
Share on other sites

@Jack_mcs I could not agree more, this is definitely beyond the scope of support. I just thought I'd ask in case it was obvious and easy to answer. I already posted in the general thread as well.

You've already been very helpful (for years!). Is there somewhere I can send you some $ as tip? NOT to get you to help me with these future modifications, but for your past help.

Share this post


Link to post
Share on other sites
12 hours ago, cinolas said:

Is there somewhere I can send you some $ as tip?

Thank you for the offer. That is very thoughtful. and I truly appreciate it but it is not necessary.  You're thanks is enough. :)

Share this post


Link to post
Share on other sites

@Jack_mcs You spend so much time providing free support for countless contributions + Phoenix etc... You should have a PayPal donate button, or a BitCoin address, so that grateful newbs like me can thank you for your time and dedication. If you do setup something, please let me know.

In the meantime, ALL THE THANKS TO YOU!

Share this post


Link to post
Share on other sites

@Jack_mcs!

So I've been working on making this work for my purpose, and I think I (we, with the help of ecartz) found a process that would work even better for your contribution as a whole:

I've modified my files so that the "Apply Gift Voucher Balance" checkbox only shows up on checkout_payment.php if there's not enough to pay for the entire order. If there IS enough to pay for the entire order, a modified version of the Free payment module shows up instead, but the label reads "Pay with my Gift Voucher balance".

To the user, the Gift Voucher balance shows up as a payment method (that allows $0 orders) if they have enough to cover the order. Or as an additional checkbox, so that they can both apply their Gift Voucher balance AND select a payment method for the remainder. Slick!

Wouldn't this be a nice addition to the next version?

Share this post


Link to post
Share on other sites
3 hours ago, cinolas said:

Wouldn't this be a nice addition to the next version?

It sounds like it might be a good solution. Please post a link to the free payment module you are using so I can add a link to it in the addon. 

Share this post


Link to post
Share on other sites

I'm using this one: https://apps.oscommerce.com/Get&xy0S8&JuIEu

But I changed the bottom half of the update_status() function. On line 55 of /includes/modules/payment/free.php:

    // Enable the module if the order total is equal or less than the Gift Voucher balance
    // Added test to see if there's enough Gift Voucher balance to cover the entire order. If so, hide the Gift Voucher checkbox, if not hide the Free payment module and show the checkbox
    if (tep_session_is_registered('customer_id')) {
        $gv_query = tep_db_query("select amount from coupon_gv_customer where customer_id = '" . tep_db_input($_SESSION['customer_id']) . "'");
        $gv_result = tep_db_fetch_array($gv_query);
    }													      
  
    if ($order->info['total'] > $gv_result['amount']) {
        $this->enabled = false;
    }

And then I changed line 27 of /includes/modules/order_total/ot_gv.php from:

$this->checkbox = $this->user_prompt . '<input type="checkbox" onClick="submitFunction()" name="' . 'c' . $this->code . '">';

to:

// Added test to see if there's enough Gift Voucher balance to cover the entire order. If so, hide the Gift Voucher checkbox, if not hide the Free payment module and show the checkbox
      if (tep_session_is_registered('customer_id')) {
          $gv_query = tep_db_query("select amount from coupon_gv_customer where customer_id = '" . tep_db_input($_SESSION['customer_id']) . "'");
          $gv_result = tep_db_fetch_array($gv_query);
      }
	  If ($order->info['total'] > $gv_result['amount']) {
		 $this->user_prompt = MODULE_ORDER_TOTAL_GV_USER_PROMPT;
         $this->checkbox = $this->user_prompt . ' (' . $currencies->format($gv_result['amount']) . ')&nbsp;<input type="checkbox" onClick="submitFunction()" name="' . 'c' . $this->code . '">';
	  } else {
		 $this->user_prompt = '';
		 $this->checkbox = $this->user_prompt . '<input type="hidden" value="0" name="' . 'c' . $this->code . '">';
	  }

 

Share this post


Link to post
Share on other sites

Now, the only thing left to do for this to work, is to change the JS so it sets the value of the hidden Gift Vouher checkbox to 1 when the Free payment method is selected... or otherwise cause the gift voucher balance to be applied just as if the customer had checked the Gift Voucher checkbox.

That JS, after the Gift Voucher modifications, looks like this:

function javascript_validation() {
      $js = '';
      if (is_array($this->modules)) {
        $js = '<script><!-- ' . "\n" .
              'function check_form() {' . "\n" .
              '  var error = 0;' . "\n" .
              '  var error_message = "' . JS_ERROR . '";' . "\n" .
              '  var payment_value = null;' . "\n" .
              '  if (document.checkout_payment.payment.length) {' . "\n" .
              '    for (var i=0; i<document.checkout_payment.payment.length; i++) {' . "\n" .
              '      if (document.checkout_payment.payment[i].checked) {' . "\n" .
              '        payment_value = document.checkout_payment.payment[i].value;' . "\n" .
              '      }' . "\n" .
              '    }' . "\n" .
              '  } else if (document.checkout_payment.payment.checked) {' . "\n" .
              '    payment_value = document.checkout_payment.payment.value;' . "\n" .
              '  } else if (document.checkout_payment.payment.value) {' . "\n" .
              '    payment_value = document.checkout_payment.payment.value;' . "\n" .
              '  }' . "\n\n";

        reset($this->modules);
        while (list(, $value) = each($this->modules)) {
          $class = substr($value, 0, strrpos($value, '.'));
          if ($GLOBALS[$class]->enabled) {
            $js .= $GLOBALS[$class]->javascript_validation();
          }
        }

        //$js .= "\n" . '  if (payment_value == null) {' . "\n" .
        //       '    error_message = error_message + "' . JS_ERROR_NO_PAYMENT_MODULE_SELECTED . '";' . "\n" .
        //       '    error = 1;' . "\n" .
        //       '  }' . "\n\n" .
        //       '  if (error == 1) {' . "\n" .
        //       '    alert(error_message);' . "\n" .
        //       '    return false;' . "\n" .
        //       '  } else {' . "\n" .
        //       '    return true;' . "\n" .
        //       '  }' . "\n" .
        //       '}' . "\n" .
        //       '//--></script>' . "\n";
		// Begin Gift Vouchers Secure

        $js .= "\n" . '  if (payment_value == null && submitter != 1) {' . "\n" . 
               '    error_message = error_message + "' . JS_ERROR_NO_PAYMENT_MODULE_SELECTED . '";' . "\n" .
               '    error = 1;' . "\n" .
               '  }' . "\n\n" .
               '  if (error == 1 && submitter != 1) {' . "\n" . 
               '    alert(error_message);' . "\n" .
               '    return false;' . "\n" .
               '  } else {' . "\n" .
               '    return true;' . "\n" .
               '  }' . "\n" .
               '}' . "\n" .
               '//--></script>' . "\n";
        // End Gift Vouchers Secure
      }
      return $js;
    }

I'm no better at JS than I am at php... though it looks like the "payment_value" should contain which payment module is selected.

"Submitter" is set to 1 by javascript when the user clicks the gift voucher checkbox. But I don't think submitter=1 means the checkbox is checked, because it's not a toggle behavior:

var submitter = null;
function submitFunction() {
  submitter = 1;
}

I probably don't understand what it's doing :) I will post on stackexchange or something. I'll let you know if I find a solution.

Cheers!

Share this post


Link to post
Share on other sites

Ok, so it wasn't that difficult after all.

I added an ID to the hidden checkbox. In the __construct() function of /includes/modules/order_total/ot_gv.php to this:

function __construct() {
      global $order, $currencies;	
      $this->code = 'ot_gv';
      $this->title = MODULE_ORDER_TOTAL_GV_TITLE;
      $this->header = MODULE_ORDER_TOTAL_GV_HEADER;
      $this->description = MODULE_ORDER_TOTAL_GV_DESCRIPTION;
      $this->enabled = MODULE_ORDER_TOTAL_GV_STATUS;
      $this->sort_order = MODULE_ORDER_TOTAL_GV_SORT_ORDER;
      $this->include_shipping = MODULE_ORDER_TOTAL_GV_INC_SHIPPING;
      $this->include_tax = MODULE_ORDER_TOTAL_GV_INC_TAX;
      $this->calculate_tax = MODULE_ORDER_TOTAL_GV_CALC_TAX;
      $this->credit_tax = MODULE_ORDER_TOTAL_GV_CREDIT_TAX;
      $this->tax_class  = MODULE_ORDER_TOTAL_GV_TAX_CLASS;
      $this->show_redeem_box = MODULE_ORDER_TOTAL_GV_REDEEM_BOX;
      $this->credit_class = true;
      // Added test to see if there's enough Gift Certificate balance to cover the entire order. If so, hide the Gift Certificate checkbox, if not hide the Free payment module and show the checkbox
      if (tep_session_is_registered('customer_id')) {
          $gv_query = tep_db_query("select amount from coupon_gv_customer where customer_id = '" . tep_db_input($_SESSION['customer_id']) . "'");
          $gv_result = tep_db_fetch_array($gv_query);
      }
      If ($order->info['total'] > $gv_result['amount']) {
            $this->user_prompt = MODULE_ORDER_TOTAL_GV_USER_PROMPT;
            $this->checkbox = $this->user_prompt . ' (' . $currencies->format($gv_result['amount']) . ') <input type="checkbox" onClick="submitFunction()" id="GiftCertBox" name="' . 'c' . $this->code . '">';
      } else {
            $this->user_prompt = '';
            $this->checkbox = $this->user_prompt . '<input type="hidden" value="0" id="GiftCertBox "name="' . 'c' . $this->code . '">';
      }
      $this->output = array();
    }

Then I modified the javascript_validation() function of /includes/classes/payment.php, line 76:

function javascript_validation() {
      $js = '';
      if (is_array($this->modules)) {
        $js = '<script><!-- ' . "\n" .
              'function check_form() {' . "\n" .
              '  var error = 0;' . "\n" .
              '  var error_message = "' . JS_ERROR . '";' . "\n" .
              '  var payment_value = null;' . "\n" .
              '  var gc_box = document.getElementById("GiftCertBox");' . "\n" .
              '  if (document.checkout_payment.payment.length) {' . "\n" .
              '    for (var i=0; i<document.checkout_payment.payment.length; i++) {' . "\n" .
              '      if (document.checkout_payment.payment[i].checked) {' . "\n" .
              '        payment_value = document.checkout_payment.payment[i].value;' . "\n" .
              '      }' . "\n" .
              '    }' . "\n" .
              '  } else if (document.checkout_payment.payment.checked) {' . "\n" .
              '    payment_value = document.checkout_payment.payment.value;' . "\n" .
              '  } else if (document.checkout_payment.payment.value) {' . "\n" .
              '    payment_value = document.checkout_payment.payment.value;' . "\n" .
              '  }' . "\n\n";

        reset($this->modules);
        while (list(, $value) = each($this->modules)) {
          $class = substr($value, 0, strrpos($value, '.'));
          if ($GLOBALS[$class]->enabled) {
            $js .= $GLOBALS[$class]->javascript_validation();
          }
        }

        //$js .= "\n" . '  if (payment_value == null) {' . "\n" .
        //       '    error_message = error_message + "' . JS_ERROR_NO_PAYMENT_MODULE_SELECTED . '";' . "\n" .
        //       '    error = 1;' . "\n" .
        //       '  }' . "\n\n" .
        //       '  if (error == 1) {' . "\n" .
        //       '    alert(error_message);' . "\n" .
        //       '    return false;' . "\n" .
        //       '  } else {' . "\n" .
        //       '    return true;' . "\n" .
        //       '  }' . "\n" .
        //       '}' . "\n" .
        //       '//--></script>' . "\n";
		// Begin Gift Vouchers Secure

        $js .= "\n" . '  if (payment_value == null && submitter != 1) {' . "\n" . 
               '    error_message = error_message + "' . JS_ERROR_NO_PAYMENT_MODULE_SELECTED . '";' . "\n" .
               '    error = 1;' . "\n" .
               '  }' . "\n\n" .
			   '  if (payment_value == "free") {' . "\n" .
			   '      	gc_box.value = 1;' . "\n" .
			   '   }' . "\n\n" .
               '  if (error == 1 && submitter != 1) {' . "\n" . 
               '    alert(error_message);' . "\n" .
               '    return false;' . "\n" .
               '  } else {' . "\n" .
               '    return true;' . "\n" .
               '  }' . "\n" .
               '}' . "\n" .
               '//--></script>' . "\n";
        // End Gift Vouchers Secure

Basically just adding:

var gc_box = document.getElementById("GiftCertBox");

At the top, and at the bottom before the return:

if (payment_value == "free") {
   gc_box.value = 1;
}

And that properly changes the value of the hidden checkbox! So on the checkout_confirmation.php page it shows Gift Voucher amount being removed, and the total is $0, and the selected payment method is the Free payment method as it all should be!

Share this post


Link to post
Share on other sites

BUT it still won't let me checkout with an order total of $0 !!!

DOH.... I guess I should've tested that Free payment module before doing all that...

Sigh. two steps forward...

Edited by cinolas

Share this post


Link to post
Share on other sites

SO CLOSE! :D

Debugging this led me to line 90 of checkout_process.php where this IF sends me back to checkout_payment.php with the error:

if ( ($payment_modules->selected_module != $payment) || ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
    tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
  }

Specifically this part returns TRUE:

!is_object($$payment)

$payment = 'free' so $$payment = $free, and if I put a var_dump on checkout_confirmation.php I see:

["free"]=>
    object(free)#19 (5) {
      ["code"]=>
      string(4) "free"
      ["title"]=>
      string(36) "Pay with my Gift Certificate balance"
      ["description"]=>
      string(12) "Free Product"
      ["enabled"]=>
      bool(true)
      ["sort_order"]=>
      string(1) "1"
    }

It looks like an object to me. But I admittedly don't know much about php objects... I'll keep on kicking it until it works, I'm so close.

Share this post


Link to post
Share on other sites

As mentioned. this is an issue with the shops code, not this addon so you should post in the general section. But did you read through the threads I mentioned? As I recall. at least one had a way to get around the problem.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×