How to selectively update payment method on one-page checkout

  • Posts: 195
  • Thank you received: 13
  • Hikashop Business
5 years 9 months ago #294791

-- HikaShop version -- : 3.4.1
-- Joomla version -- : 3.8.10
-- PHP version -- : 5.6.36

I'm working to resolve an issue with my payment plugin. I have two payment methods active, mine and PayPal for example, and want the customer to be able to SWITCH between the two. When I switch from mine to PayPal, I hide the card input fields for mine. When I switch from PayPal to mine, I show the card input fields.

However, the onHikashopBeforeDisplayView method is called multiple times to update various parts of the one-page checkout. When showing two payment methods, this triggered method is called twice with the show_block_payment layout. However, there is nothing I can find to differentiate one call or block from the other. I would suspect that one is for my payment method and the other is for PayPal. But I cannot find anything in the $view that differentiates the two. It seems the $view->ajax field is set when the page is being updated via ajax.

I could really use some help. I need to only update my payment method on the checkout page. So I need to only let the onHikashopBeforeDisplayView respond once, and only for my payment method. Currently it responds twice, once for each payment method and that's causing some issues with code to the payment gateway.

Is there something I'm missing in $view or that could be referenced by something in $view that will tell me which of these two calls is for which payment method? Maybe there is some helper method that could tell me?

Thanks for any help.


3by400, Inc.
3by400.com
Websites that Work, Marketing that Matters

Please Log in or Create an account to join the conversation.

  • Posts: 81478
  • Thank you received: 13062
  • MODERATOR
5 years 9 months ago #294809

Hi,

Is there a reason why you don't want to use the built-in credit card form ?
You actually don't need to do any display with it.
You just implement the "needCC" function and then, in the onBeforeOrderCreate or onAfterOrderCreate or onAfterOrderConfirm functions, you can call $this->ccLoad(); to get the credit card information that you then have in $this, like for example $this->cc_number or $this->cc_month, etc.
That way, the credit card form display/hide is handled completely automatically by HikaShop's checkout and you don't need to mess with onHikashopBeforeDisplayView.

Now, regarding your question, onHikashopBeforeDisplayView is called when a view is displayed. So it will be called once for the display of the show_block_payment view, regardless of whether one or the other payment method is selected.
But it will also be called for other view files. If you activate the "Display view files" setting of the HikaShop configuration, you can see which view file is called.
And if you want to know which payment method is selected, you want to use such code:

$cart = $view->checkoutHelper->getCart();
echo $cart->payment->payment_id;

Please Log in or Create an account to join the conversation.

  • Posts: 195
  • Thank you received: 13
  • Hikashop Business
5 years 9 months ago #294831

I wasn't aware of the needCC function, but the gateway I'm implementing (Braintree) needs its own embedded hosted fields or drop-in form in order to secure the CC contents.

I'm aware that onHikashopBeforeDisplayView is called on all views (painfully so :) ). But I've narrowed it down to just the show_block_payment views. I also know about the $cart->payment->payment_id and am using it as needed. But my problem is still that of the two payment views that are rendered I cannot differentiate which payment method is targeted for which view. There must be something that knows because the content is always displayed appropriately. When the checkout page is first displayed, it works fine when my payment method is selected by default.

But when a customer switches from one payment method to the other (can't make up their mind) or when the 'other' payment method is selected by default and the customer then switches, this event causes the onHikashopBeforeDisplayView to be triggered. And the $view object does not (that I've found as yet) have anything that tells me what payment_type or payment_id is rendered in that view. Not whether it is selected because that's a cart value, but which is rendered in the view. It tells me the workflow (block, task, etc.) and I've got that. I just need it to have something like a $rendered_payment_id value for each of the payment methods displayed. For example the $view->block_position for all payment methods (in my particular one-page configuration) is '3'. $view->workflow_step = 0. $view->step = 1. So the show_block_payment view triggers to onHikashopBeforeDisplayView all appear the same.

Thanks for your timely help.


3by400, Inc.
3by400.com
Websites that Work, Marketing that Matters

Please Log in or Create an account to join the conversation.

  • Posts: 81478
  • Thank you received: 13062
  • MODERATOR
5 years 9 months ago #294854

Hi,

I still don't understand what is the problem you're having.
In the show_block_payment view, all the payment methods are rendered. The one selected, but also all the other available ones.
So I don't understand what you mean by "which is rendered in the view" since all of them are rendered in the view.
That's why I thought you were asking about the selected one since there is only one selected.
So I still don't know what I can say to help you.

Please Log in or Create an account to join the conversation.

  • Posts: 195
  • Thank you received: 13
  • Hikashop Business
5 years 9 months ago #294875

Apologies for more confusion. I'll try it again. I realize I have to get my point across and I appreciate your trying to help.

Yes, both (in my case) payment methods are rendered/displayed. When one is selected and the customer changes their mind and selects the other one, then the onHikashopBeforeDisplayView function is triggered multiple times, via AJAX, to refresh the various blocks (status, payment method a, payment method b, etc.). I need to only call my layout once, in this case my braintree_pay.php since it has to build a one-use, customer-specific nonce for this payment activity. Now it is being called twice, once for each displayed payment method since I can't differentiate the two triggered events.

I can avoid calling my layout when the layout is not show_block_payment. But because all the payment methods are shown in a show_block_payment layout and in the same block (3 my case) and they are in the same place in the workflow, then the two onHikashopBeforeDisplayView events appear identical and my braintree_pay.php is called twice within 1.02 seconds. This results in an error in the braintree code's generation of their hosted fields (duplicate) which results in the payment failing. Somehow I have to make sure I call my layout file only once when the user switches payment methods. I just can't find a way to differentiate the two ajax refresh events of the two payment method views. Everything is the same (view, layout, block, workflow, task, cart_payment_id, etc.) for both events. I was hoping there was some way that the $view object would tell me which payment method view was being refreshed. But there is nothing to say this onHikashopBeforeDisplayView event is for my braintree payment method and that one is for the PayPal payment method.

Maybe I'm missing something obvious. Maybe I'm using the wrong event. I want to call my payment method's layout file only once any time the page refreshes or is loaded regardless of how many payment methods are published and displayed. Is there a more appropriate event than onHikashopBeforeDisplayView?

What I was looking for, hoping for, was a variable in the $view that referred to the payment_id of the payment method for each payment method shown. It currently tells me which payment method is selected, but when my payment method is selected there are still two onHikashopBeforeDisplayView events for show_block_payment and nothing indicates that one is for the braintree payment method and the other is for the PayPal method. I want to load my layout for the braintree refresh, but I want to NOT load my layout for all the other payment methods that are displayed. I was hoping that these events would include a variable in $view that would indicate it was for payment_id = 1 or payment_id = 2. But I haven't found anything like that so far.

Thanks again. I've been working on this a long time. Your help is invaluable and I really appreciate your time.


3by400, Inc.
3by400.com
Websites that Work, Marketing that Matters

Please Log in or Create an account to join the conversation.

  • Posts: 81478
  • Thank you received: 13062
  • MODERATOR
5 years 9 months ago #294877

Hi,

The onHikashopBeforeDisplayView is not called once for each payment method.
It is called once for each block which is being refreshed. And so it is called for show_block_payment once regardless of how many payment methods you have available or configured.
That's why there is no information on whether it's one payment method being displayed or the other because both are being displayed at the same time, each time.
I also don't see why onHikashopBeforeDisplayView would be be called several times for the same view.
I would recommend to activate the "display view files" option to see which view is used where, and add some debug output in your trigger so that you can see which view file calls your trigger.
Also I would recommend to check with the "network" tab of the developer tools of your browser to see which views are being refreshed. It's possible that the show_block_payment view file is being rendered once when the payment method change is submitted and a second time to refresh the view. Or something like that.

Please Log in or Create an account to join the conversation.

  • Posts: 195
  • Thank you received: 13
  • Hikashop Business
5 years 9 months ago #294900

Interesting info that onHikashopBeforeDisplayView is only called once for each block being refreshed.

Does the PayPal payment method block get refreshed when it goes from selected to not selected? It doesn't seem so.

There are a total of 8 calls to onHikashopBeforeDisplay view every time I switch from PayPal to Braintree payment method. All within a span of 1.3 seconds. In my case Hikashop is configured with Login, address, shipping, payment, confirm, coupon, cart, status, fields all in one 'page' and end in the next page. In my case all the payment methods are in block 3.

The 1st call is for block 3, but the layout is show_block, not show_block_payment.
The 2nd call is for block 3 and is show_block_payment (this causes my code to load my braintree_pay.php layout).
The 3rd call is for block 7 (status) and is show_block.
The 4th call is for block 7 (status) and is show_block.
The 5th call is for block 7 (status) and is show_block_status.
The 6th call is for block 3 and is show_block.
The 7th call is for block 3 and is show_block_payment (this causes my code to load my braintree_pay.php layout).
The 8th call is for block 7 and is show_block_status.

I'm going to disable the PayPal payment and see if the number of calls drops from 8 to 4 or to some other number. I have a log of logging going on in my plugin for debugging. I'll also activate those you've recommended. And I'll report back as to what I find out.

Is there a variable in the $view object that indicates whether the event was triggered for a payment method change or refresh as you commented? If there is I haven't found it as yet.

Thanks again for taking the time to response so quickly. Very much appreciated.


3by400, Inc.
3by400.com
Websites that Work, Marketing that Matters

Please Log in or Create an account to join the conversation.

  • Posts: 81478
  • Thank you received: 13062
  • MODERATOR
5 years 9 months ago #294913

Hi,

There is no PayPal payment method block. There is only a payment method selection block which encompass all the payment methods.

You need to understand how the checkout works:
Each block registers to "change" events so that they can refresh themselves when something changes which affect them.
For example, the status block registers to the payment method "change" event so that if something about the payment methods changes, it will refresh itself. And the payment block will do the same (because if you have two payment method selection block, when you change one, you want the other one to refresh too to be consistent. That could happen with one payment block for the selection and a second one in read only mode to display the selected payment method).

Regarding "show_block", there is no such block and probably no refresh done for that. I suppose that it's just that the onHikashopBeforeDisplayView trigger is called for it before it is again called for the sub view which is the real view being displayed. So I would say you could ignore all the "show_block" calls.

To distinguish the 2nd call and the 7th call, I would suggest to look at

$_REQUEST['task']
. I suppose that the 2nd call will have the value "submitblock" while the 7th will have the value "showblock".

Please Log in or Create an account to join the conversation.

Time to create page: 0.070 seconds
Powered by Kunena Forum