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

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

Understood, I will.

I just thought that part would be instrumental to the next version of this contrib working well with the Free payment module mod. But yeah, I get it. I'll post here when I have a solution.

I did follow the link and read the threads, but none of them actually come up with an answer. The closest they get is with the same Free payment module, when used with a different coupon contrib that applies the coupon on the shopping cart page, so it's all about bypassing the payment page. I need the payment page because that's where the gift vouchers are applied :)

Will post in General.

Cheers!

Share this post


Link to post
Share on other sites

Well, I've found a solution to my problem, so I'm posting it here too, in case others are trying to achieve something similar. If you are using the Gift Voucher Secure contrib with a payment module such as the Free payment module linked above, you simply need to comment out line 64 of checkout_process.php, like so:

//Begin Gift Vouchers Secure
   //if ($credit_covers) $payment=''; 
//End Gift Vouchers Secure

$payment does not need to be emptied since we are using a payment method (the modified Free module).

Share this post


Link to post
Share on other sites

@Jack_mcs I'm going to bug you once more, about something that is far, FAR, beyond the scope of support :)

I'm trying to move the gift voucher code redeem field. I don't want it on checkout_payment.php but on a page of it's own (redeem_gv.php) accessed from My Account. Is that a customization that I could hire you to do? PM me.

I looked into it, and it looks like I would have to split the credit_selection() function into 2 different functions, one for the checkbox, one for the redeem code field. And then somehow build a form on redeem_gv.php that stands alone and calls the order_total classes. I just need a field to type in the gv code, and then run the verification and add the amount to the user's account. It sounds simple, but I'm not sure I can manage that myself in a timely manner.

The reason is that Gift Voucher doesn't work well with Pay Without Account (obviously, since the balance must be stored in the user's account), I've modified account_pwa.php to prevent guest checkout when there's a gift voucher in the cart. If I can move the redeem process to a page accessed from My Account then I believe that covers me and guest users won't be able to buy or redeem gift vouchers.

Let me know!

Share this post


Link to post
Share on other sites

@cinolasI'm not sure I understand what you want to do. If it is moved as you suggest, the way I understand it,  the customer would have to enter the code in their account and still go through the checkout process. Adding extra steps to the checkout process isn't a good idea, in my opinion. Also, I don't understand the reference to PWA. Are you saying that the customer can checkout with the GV code if they are logged in? If that is the case, then all you need to do is edit the GV order total module so that it is not active when on the account_pwa page.

Share this post


Link to post
Share on other sites

@Jack_mcs I think I may have figured out a better way. The idea was to remove the redeem field from the payment page so that "Guests" (from the PWA guest checkout contrib) can't redeem gift vouchers. I'm going to use javascript to hide the field instead.

Share this post


Link to post
Share on other sites

@Jack_mcs I'm back! <sigh>

I know that what I'm doing with Gift Voucher is FAR beyond regular support, but I'm having one last problem and I'm hoping you may have insights: After all the modifications I've done, when I try checking out with my regular CC payment method (Moneris) no Gift Voucher involved, the CC#, CC Expiration, and CVS gets blanked out as described here: Thanks! 

 

Share this post


Link to post
Share on other sites

@cinolasUnfortunately, due to all of the changes you've made, there's no way for me to follow-along and make any suggestions on where the problem might be.

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

×