Jump to content

White screen during checkout using gateway


jasehead

Recommended Posts

This is a problem that gets reported occasionally for different reasons (white screen during checkout), but I couldn't find a solution for my specific experience using CubeCart 6.1.14.

The process:

  • Start as a guest customer, not logged in
  • Add an item to the basket
  • Checkout - fill all fields, tick all boxes (including subscribe to mailing list)
  • Select either Card Capture or PayPal Standard as the gateway
  • Click Secure Checkout
  • Screen updates address details and postage - there is another subscribe to mailing list checkbox on this screen between the address and the comments field
  • Select either Card Capture or PayPal Standard as the gateway (again) - Click Secure Checkout (again)
  • Blank white screen

Nothing in the CubeCart errors, but in the site error log there is an issue with the MailChimp plugin:
PHP Fatal error:  Call to a member function is() on null in /home2/mysite/public_html/storefolder/modules/plugins/SFWS_Mailchimp/hooks/class.newsletter.subscribe.php on line 11

PLEASE RESIST saying that it's a 3rd party problem and to update the plugin or contact SemperFi, keep reading.

If I uncheck the second subscribe checkbox then proceed to payment, there is no white screen and the checkout works OK.

If I refresh the page or (like a frustrated customer) click elsewhere and come back to the checkout, the second subscribe checkbox isn't there at all.

So my questions are:

  • Why IS there a second subscribe to newsletter checkbox when the postage has been updated? (between address and comment field)
  • Is it responsible for the PHP error (possibly no email address this time, so value could be null)?
  • Is it necessary and can I safely remove it? (or modify something to make sure an email address is actually being submitted)
Link to comment
Share on other sites

it's a failure in the module SFWS_MailChimp, from the error it's checking if the user is logged in, but isn't able to find the required information to function.  The error has been thrown from that module so needs the dev to review in more detail using your steps to reproduce.

I've triggered these a few times in my own code from time to time, so have seen it before. without knowing the code being called I can't give any more details

Link to comment
Share on other sites

I'm not interested in the plugin.  I'll handle the plugin outside of the forums by speaking directly to the developer (waiting for a response).

What I'm interested in is the core CubeCart itself: why the subscribe checkbox appears twice in content.checkout.confirm.php and whether it needs to, or if the second appearance is unnecessary and I can just remove it.  If it serves no purpose and is part of the problem (eg. responsible for null data), then removing it may be a simple workaround.  Or maybe a code hook is available in the original checkout page but not after the address has been confirmed.  There are other stores where customers occasionally experience a blank screen during checkout for different reasons, so any workaround that solves my checkout problem could be a useful road sign to others.

Link to comment
Share on other sites

These templates will frequently have several specific blocks of code that will only appear in the final compiled output if certain conditions exist.

Of the code you are referring to, the first occurrence is in a block (lines 13-43) that makes it to the output if CubeCart determines the visitor is logged in (line 12). Otherwise, the second occurrence is in a block (lines 45-223) that makes it to the output via {else} (line 44).

So, actually only one of those two statements in the template makes it to the compiled output - irrespective of how many times you see it during the checkout process.

Link to comment
Share on other sites

I end up seeing the subscription checkbox twice.  The first time is when the guest customer is filling out their details (they can subscribe to the newsletter and create an account with the store).  The second time is when the address has been checked and postage rates updated and the customer is now logged in.

So why (if they already ticked the subscription box) does another subscription box appear?  If the customer is logged in and HAS subscribed then they shouldn't be presented with a subscription box during checkout - there are unsubscribe links in the footer and via their account (Newsletter Subscriptions).

Link to comment
Share on other sites

Here's the thing - if I manually refresh the checkout page the green notice about new shipping options disappears and so does the subscribe checkbox that was between the address and comments field.  If I click Secure Checkout after I refresh the page then the gateway works OK.

Link to comment
Share on other sites

I found that if I comment out the subscribe checkbox in content.checkout.confirm.php (in 6.1.14 lines 37-43) then the checkout works OK and there is no PHP Fatal Error from the MailChimp plugin in the site error log.  Disabling the mailchimp plugin altogether also allows the gateways to function OK, but that's not the point of this discussion.

This subscription checkbox had been appearing (after address/shipping refresh) because the guest customer was not properly identified by CubeCart as subscribed to the newsletter when the checkbox was ticked as the customer filled in their address details.  Manually refreshing the page made the {if !$USER_SUBSCRIBED} checkbox vanish - so something changed from doing a manual page reload - but only 6 MailChimp signups over the past 8 weeks shows there is something amiss.

The MailChimp plugin was working OK during 2016 and 2017 (throwing the same error but subscribing people) - shows how long it took to identify it was blocking checkout.  This year we moved servers and upgraded the store from 6.0.12 to 6.1.14 - so CubeCart code changes, PHP version or extensions could be a factor.  I'm in conversation with SemperFi about the MailChimp plugin, but I'm interested in any helpful suggestions specific to CubeCart 6.1.14 or the server environment/PHP requirements.

Link to comment
Share on other sites

"So why (if they already ticked the subscription box) does another subscription box appear?"

Short answer: When the delivery address has been deemed to have changed between page loads, CubeCart stops processing the remainder of the Checkout form elements and resends the Confirm page with the green Notice. When submitting this form, once the address no longer changes, CubeCart proceeds to process the remainder of the form elements - including the checkbox for newsletter subscription.

It could be argued that this form element could be processed far earlier in this sequence of events.

"Is [the checkbox] responsible for the PHP error?"

The subscribe checkbox is a vector to the actual problem. Remove the vector and the problem is never reached.

"Is [the checkbox] necessary and can I safely remove it?"

You can safely remove it. The customer will not be able to subscribe via this method, but there are two other places a customer can subscribe: the Subscribe box in the general page's common area, and the customer's Account/Profile page. These, however, are also vectors to the actual problem causing PHP to crash.

Link to comment
Share on other sites

I am still getting a few MailChimp signups with the plugin, so I have to assume that parts of it are working (either general Subscribe box, register outside of checkout or profile changes).

I wonder if the plugin is looking for data before CubeCart has finished processing the checkout form.  Like Noodleman indicated, the "Call to a member function is() on null" sounds like it's looking for the customer to be logged in.  I'm guessing any fatal error at this point is what blocks the gateways from working - meaning frustrated customers and lost sales.

I'll also test using a new MailChimp API key and change the mailing list to see if that has any impact.

Link to comment
Share on other sites

I've seen this specific error and similar errors:
"Call to a member function is() on null"

There are is() functions in the Admin and User classes. They answer back the logged-in state of the admin or user. (The User->is() function can also exit out to the login page.)

When PHP crashes, there is an orderly shutdown which includes working through instantiated classes and killing them. A null class object has been dis-instantiated, and whatever is causing the problem is trying to be shutdown in an orderly fashion, but it's __destruct() function (or something else) is calling the User class after PHP has already nulled it.

So, I believe the module file hooks/class.newsletter.subscribe.php, line 11, could be a class __destruct() function that makes a call to User->is(), but, as has been mentioned, is believed to have already been nulled.

Link to comment
Share on other sites

Line 11 is something like:

if ($GLOBALS['user']->is() && !isset($email))

So that's the check for the user being logged in.  I can't see any __destruct() function in the plugin itself, but there are CubeCart instances in cart.class, request.class, session.class and user.class.php that could play a role.

I guess any plugin needs a safe way to check for a null value so that it can fail quietly at checkout (or use a stored variable from the page) without breaking the gateway.

I think that CubeCart's guest customer signup process during checkout could be reviewed - even moving a code hook to another point.

Link to comment
Share on other sites

TESTING GUEST CHECKOUT - CCv6.1.14 with MailChimp 5.1.2 plugin enabled/disabled

Refresh MailChimp connections first in plugin setup:

  • Create new MailChimp API key (done at MailChimp)
  • Paste API into plugin setup & save
  • Change list and save
  • Change list back to main list then save

 

CHECKOUT TEST 1 - all boxes ticked, guest sign up during checkout, mailchimp plugin enabled

  • Logout first
  • Add test product
  • Click Secure Checkout in Mini Basket
  • Fill all details, all checkboxes selected
  • Card Capture as gateway
  • Secure Checkout button
    • Green banner - address updated, shipping options, logged in at top of screen, subscribe checkbox visible
  • Secure Checkout button (again)
    • WSOD - White Screen of Death (customer may abandon cart at this point)
    • Site error log shows PHP fatal error is() on null
  • Click browser back button
  • Click browser reload page (if customer did not give up)
    • Subscribe checkbox not visible
  • Secure Checkout button
    • Card Capture gateway displayed
    • Order email received by admin
    • Site error log still shows the PHP fatal error
    • Subscriber IS added to CubeCart mailing list
    • NO subscriber added to MailChimp list
 
CHECKOUT TEST 2 - subscribe to newsletter but do not make store account
  • Logout first
  • Add test product
  • Click Secure Checkout in Mini Basket
  • Fill all details, but DO NOT create store account (stay as guest)
  • Card Capture as gateway
  • Secure Checkout button
    • Green banner - address updated, shipping options, NOT logged in, NO subscribe box visible
  • Secure Checkout button (again)
    • Card Capture gateway displayed
    • Order email received by admin
    • NO error in site error log
    • NO subscriber added to CubeCart mailing list
    • NO subscriber added to MailChimp list
 
CHECKOUT TEST 3 - mailchimp plugin DISABLED - all boxes ticked, guest sign up during checkout
  • Required because of admin setting change (plugin disabled)
    • Clear CubeCart caches except for image cache
  • and if customer logged in (and depending on browser)
    • Clear browser caches
    • Reload page from origin
       
  • Add test product
  • Click Secure Checkout in Mini Basket
  • Fill all details, all checkboxes selected
  • Card Capture as gateway
  • Secure Checkout button
    • Green banner - address updated, shipping options, logged in at top of screen, subscribe checkbox visible
  • Secure Checkout button (again)
    • Card Capture gateway displayed
    • Order email received by admin
    • Subscriber IS added to CubeCart mailing list
 
OTHER TESTS - try other subscribe methods - mailchimp plugin enabled
  • Unsubscribe/Subscribe in Your Account/Newsletter Subscriptions
    • CubeCart and MailChimp lists updated
  • Subscribe using standard subscribe box on page
    • CubeCart and MailChimp lists updated
 
MY THOUGHTS
  1. The MailChimp plugin works for other subscribe methods, but not during checkout.
  2. The customer is added to the CubeCart mailing list during checkout if they select NEWSLETTER + ACCOUNT but not if they only select NEWSLETTER by itself - surely if they want newsletters but no store account that should be possible.
  3. Clicking the back button after WSOD and reloading the page (a) makes the {if !$USER_SUBSCRIBED} subscribe checkbox disappear and (b) allows the payment gateway to work, even though the plugin still seems to generate the same PHP Fatal Error. 
  4. I could not get any subscription to the MailChimp list during checkout starting as a guest.  I have also tried the 6.0.0 version of the plugin without luck.

 

I've sent this to the developer as well - the plugin is simply not working for me.  Just interested here in any comments specific to anything CubeCart is doing during checkout that may be contributing to the issue.  Or if there's a very simple fix that's obvious to someone (not me).

 
Link to comment
Share on other sites

Good news - I've tracked part of my problem to me making the newsletter subscription checked by default (based on this thread).  Still, I have a new issue of no first name or surname being added to the CubeCart mailing list OR the MailChimp list.
 
I changed the following lines back to their original.
 
content.checkout.confirm.php (2 occurrences)
MINE - <input type="checkbox" id="mailing_list" name="mailing_list" value="0" checked="checked"><label for="mailing_list">{$LANG.account.register_mailing}</label>
ORIG - <input type="checkbox" id="mailing_list" name="mailing_list" value="1"><label for="mailing_list">{$LANG.account.register_mailing}</label>

MINE - <input type="checkbox" id="mailing_list" name="mailing_list" value="0" checked="checked" {$MAILING_LIST_SUBSCRIBE}><label for="mailing_list">{$LANG.account.register_mailing}</label>
ORIG - <input type="checkbox" id="mailing_list" name="mailing_list" value="1" {$MAILING_LIST_SUBSCRIBE}><label for="mailing_list">{$LANG.account.register_mailing}</label>

 

content.register.php

MINE - <input type="checkbox" id="mailing" name="mailing_list" value="0" checked="checked" {if isset($DATA.mailing_list) && $DATA.mailing_list == 1}checked{/if}><label for="mailing">{$LANG.account.register_mailing}</label>
ORIG - <input type="checkbox" id="mailing" name="mailing_list" value="1" {if isset($DATA.mailing_list) && $DATA.mailing_list == 1}checked{/if}><label for="mailing">{$LANG.account.register_mailing}</label>

(Yes, I see that my code just above would say "checked" twice, but the problem was more likely to have been with content.checkout.confirm.php)

So, if my code is breaking things, is it because of the VALUE = 0 or because the checkbox has been CHECKED (maybe there is some script that fires on the check action)?

Is there a better way to make the subscription checked by default?  No European customers, so no GDPR.

 

BTW - here is another thread about newsletter subscription not working:

 

Link to comment
Share on other sites

In your statements, the checked="checked" is a better way of coding than simply checked. This is because earlier versions of browsers did not understand a simple checked (HTML5?). Even so, note that the template original code will include checked if CubeCart had been told it was checked earlier. (The browser may issue a complaint if it sees checked="checked" checked but CubeCart would not be aware of it.)

This makes the form element "active" such that the value will be passed in the POST payload - that value being "0".

Of the three places in CubeCart's core code that processes $_POST['mailing_list'], only CubeCart->_checkout() actually tests for that value being ==1.

You can test to see if the Mailchimp plugin no longer causes the Fatal Error if the value is "1".

Regarding the BTW, I am confident that issue was resolved in some later version shortly after 6.1.7.

Link to comment
Share on other sites

I thought that the 0 or 1 value meant checked or unchecked. I understand now that the element contains a 1 value, and that value is stored if the box is checked (am I right)?

So, if the value is 1 and the code contains checked="checked", that will result in the customer actually being signed up to the mailing list (ie. the value doesn't need to change because a ticked box is not just cosmetic).

Also, what would be the best way to make the checkbox ticked by default for guest signup during checkout, but to show the correct stored value for an existing (logged-in) customer?

===

Any clue as to why first name and surname might not be making it to the CubeCart mailing list? I've upgraded Card Capture gateway from 1.0.5 to 1.0.6 and PayPal Standard gateway from 1.0.4 to 1.0.8, and the mailing list checkbox code changes above - but that's all.  Previously, when I was able to get a subscription during guest signup to work, the names carried through to the list.

If I unsubscribe and resubscribe from admin or logged in as the customer then the names carry through to the list OK, just not during checkout.

===

According to https://www.w3schools.com/tags/att_input_checked.asp , checked is fine.

<input type="checkbox" name="vehicle" value="Car" checked>

No difference between HTML 4 and 5, only XHTML.

Quote

In XHTML, attribute minimization is forbidden, and the checked attribute must be defined as <input checked="checked" />.

 

Link to comment
Share on other sites

I think that no name is recorded in the mailing list if the only subscription checkbox is the first one shown when the guest is filling out their address details - in that instance only the email address is recorded in the mailing list. The name is not recorded because at that point the customer is not logged in.

If the second subscription checkbox shows after the address has been updated and the new customer has been logged in, then their first name and surname are included in the mailing list. However, if I force the second checkbox to show then I end up with the gateway white screen of death and the PHP error from the MailChimp plugin.

So how do I fix this and ensure that a new customer's name is recorded in the mailing list (not just their email)?

Maybe referenced here:

 

Link to comment
Share on other sites

I've managed to break a clean 6.2.1 store with MailChimp plugin enabled and reproduce my problem (my store is 6.1.14).
                
- Add test product to basket
- Click Checkout in Mini Basket
- Fill all details, all checkboxes selected EXCEPT DO NOT SUBSCRIBE TO MAILING LIST
- Card Capture as gateway
- Secure Checkout button
- Green banner - address updated, shipping options, logged in at top of screen, SUBSCRIBE CHECKBOX VISIBLE
- Click Subscribe checkbox on this screen
- Secure Checkout button (again)
- Gateway fails - white screen of death (on Safari, 500 error on some browsers)
                
So the problem seems to be if the first subscription box is empty and the second subscription box is checked. (If the first box is checked then the other should not appear.) Commenting out one checkbox seems to cause the same problem.

 

Testing my 6.1.14 store using the same method:

  • The first name and surname are included in the CubeCart mailing list (but no information sent to MailChimp list via the plugin)
  • Error in the site error log :
    PHP Fatal error:  Call to a member function is() on null in /home2/mysite/public_html/mystore/modules/plugins/SFWS_Mailchimp/hooks/class.newsletter.subscribe.php on line 11
  • If the MailChimp plugin is disabled then the gateway works OK

 

My clumsy workaround was to add "disabled" to the input for the second checkbox and to comment out the label. I'm sure there's a more elegant solution that will keep the mailing_list input visible to CubeCart but invisible to the customer.

{if !$USER_SUBSCRIBED}
<div class="row">
   <div class="small-12 large-8 columns">
      <input type="checkbox" id="mailing_list" name="mailing_list" value="1" disabled ><!--label for="mailing_list">{$LANG.account.register_mailing}</label-->
   </div>
</div>
{/if}

If a guest customer unchecks the subscription checkbox on during signup at checkout, then when address/shipping is updated another subscription checkbox will appear but no label text and not clickable - it looks like a small glitch and easily ignored.  What it does is preserve the unsubscribe state from the original signup and so allows the gateway to function without error.

Link to comment
Share on other sites

5  if(!defined('CC_DS')) die('Access Denied');
6  
7  $mailchimp_status  = $GLOBALS['config']->get('sfws_mailchimp', 'status');
8  $mailchimp_api_key = $GLOBALS['config']->get('sfws_mailchimp', 'mailchimp_api_key');
9  $mailchimp_list_id = $GLOBALS['config']->get('sfws_mailchimp', 'mailchimp_list_id');
10
11 if ($GLOBALS['user']->is() && !isset($email)) {

 

Link to comment
Share on other sites

Try this. Change line 11:

From:

if ($GLOBALS['user']->is() && !isset($email)) {



To:

if (isset($GLOBALS['user']) && $GLOBALS['user']->is() && !isset($email)) {

This makes sure the User class is instantiated, as well as the other things.

However, the User could be logged in, but CubeCart has not yet determined that (User class not yet instantiated).

So, another experiment would be:

if (User::getInstance()->is() && !isset($email)) {

This will instantiate the User class which will determine the logged in status of the customer. Then the test on the response to the request for that status.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...