Call to a member function on a non-object
Permalink Browser Info Environment
We're seeing an error on our server logs, "PHP Fatal error: Call to a member function getAddress2() on a non-object in /Users/domain/Sites/Packages/core_commerce/models/payment/methods/authorize_net_aim/controller.php on line 87"
From what I can gather, this has been happening sporadically, but at least once a week. Our client is getting duplicate orders. We suspect there is an error after the order is placed and payment is processed, but the customer never sees the confirmation page. (This may be totally wrong.)
The other scenario is a customer tries to place an order, get the fatal error message and never places an order.
Both situations result in lost time and revenue as the duplicate charges have to be reversed or the order is never placed.
Line 87 is:
$addr2 = $o->getAttribute('billing_address')->getAddress2();
What I'm wondering is if something is returning a null value and throwing the error. Is it possible to put that statement is a try/catch block?
Also, the address2 calls are the only ones assigned to a variable ($addr2) which is never initially declared. All the other calls are put directly into the $fields array.
The same type of code (for shipping address) is on line 103.
From what I can gather, this has been happening sporadically, but at least once a week. Our client is getting duplicate orders. We suspect there is an error after the order is placed and payment is processed, but the customer never sees the confirmation page. (This may be totally wrong.)
The other scenario is a customer tries to place an order, get the fatal error message and never places an order.
Both situations result in lost time and revenue as the duplicate charges have to be reversed or the order is never placed.
Line 87 is:
$addr2 = $o->getAttribute('billing_address')->getAddress2();
What I'm wondering is if something is returning a null value and throwing the error. Is it possible to put that statement is a try/catch block?
Also, the address2 calls are the only ones assigned to a variable ($addr2) which is never initially declared. All the other calls are put directly into the $fields array.
$addr2 = $o->getAttribute('billing_address')->getAddress2(); if (!empty($addr2)) { $fields['x_company'] = $o->getAttribute('billing_address')->getAddress1(); $fields['x_address'] = $addr2; } else { $fields['x_address'] = $o->getAttribute('billing_address')->getAddress1(); }
The same type of code (for shipping address) is on line 103.
Type: | Discussion |
---|---|
Status: | In Progress |
This is the same problem from an older version of eCommerce (2.8.10) which apparently hasn't been addressed. See:https://www.concrete5.org/marketplace/addons/ecommerce/support/error... from April 28, 2014 at 11:32 AM.
Hi Thehawkeye,
This is tricky because this does not happen with any other ecommerce install that we know of and it doesn't make much sense that the attribute would be conditionally available.
The only way I can see that this could happen is if your session is being lost. It sounds like - from the old thread - this is exacerbated by server load, that sounds to me like your server is not retaining the session files for whatever reason. That said, it'd be nice if we failed with a "Uh oh, your order looks lost" message instead of a fatal error.
To potentially fix this, I would suggest moving your session to the database.
https://www.concrete5.org/documentation/how-tos/developers/handle-se...
This is tricky because this does not happen with any other ecommerce install that we know of and it doesn't make much sense that the attribute would be conditionally available.
The only way I can see that this could happen is if your session is being lost. It sounds like - from the old thread - this is exacerbated by server load, that sounds to me like your server is not retaining the session files for whatever reason. That said, it'd be nice if we failed with a "Uh oh, your order looks lost" message instead of a fatal error.
To potentially fix this, I would suggest moving your session to the database.
https://www.concrete5.org/documentation/how-tos/developers/handle-se...
We've been concerned about server load too, so we cut down on the server logs and disabled ssh except for our internal IP address. (We noticed IP addresses we didn't recognize trying to continually ssh which was consuming bursts up to 80% of server cpu.)
So far two days without any duplicate orders or php errors.
We had an error this morning @ 10:12:28am. I modified the controller.php and set it up as an override. If we get another error, it will give me an idea of where the code is failing. (If we get no orders, I can just delete the override to go back to default code.)
Last night we had an error on ->getAddress1(). This is mixed news. The process got through the ->getAddress2() patch which is processed first. I made added some more code to check for a null on ->getAddress1(). Instead of assigning address1 to an empty string like address2 (which is optional) I assigned it to an error message. We'll keep monitoring...
I'm not sure there's really much more we can do in an add-on support capacity at this point.
Authorized.net is making a change in the authentication URL, and now offering three.
"Using Akamai network technology will help decrease latency and improve the reliability of our payment gateway."
Search for "authorized.net akamai"
h t t p s ://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Important-Authorize-Net-Networking-Change/ba-p/51272
"Using Akamai network technology will help decrease latency and improve the reliability of our payment gateway."
Search for "authorized.net akamai"
h t t p s ://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Important-Authorize-Net-Networking-Change/ba-p/51272
If we get no more errors, it could be the change to Akamai or the changes in code. I will share the code if we've had no failures after a week. (I don't want to share what doesn't work.)
We had another error on getCity() for billing. I've now isolated all the ->get() functions within a null check for both billing_address and shipping_address.
No errors over the weekend after putting in the null check...
The problem appears to be caused when $o->getAttribute('billing_address'); or $o->getAttribute('shipping_address'); return null.
I've made the following changes in packages/core_commerce/models/payment/methods/authorize_net_aim/controller.php
Replace all code after:
$fields['x_first_name'] = $o->getAttribute('billing_first_name');
$fields['x_last_name'] = $o->getAttribute('billing_last_name');
and before:
$post_data = "";
foreach($fields as $key => $value) {
$post_data .= "$key=" . urlencode($value) . "&";
}// end foreach
$post_data = rtrim($post_data, "& ");
With:
------------------------------------------------------------------------------------------
I've made the following changes in packages/core_commerce/controllers/checkout/shipping/address.php
Replace:
if ($o->getAttribute('shipping_first_name') == $o->getAttribute('billing_first_name')
&& $o->getAttribute('shipping_last_name') == $o->getAttribute('billing_last_name')
&& $o->getAttribute('shipping_address')->__toString() == $o->getAttribute('billing_address')->__toString()
&& $o->getAttribute('shipping_phone') == $o->getAttribute('billing_phone')
) {
$this->set('useBillingAddressForShipping', true);
}
With:
I've made the following changes in packages/core_commerce/models/payment/methods/authorize_net_aim/controller.php
Replace all code after:
$fields['x_first_name'] = $o->getAttribute('billing_first_name');
$fields['x_last_name'] = $o->getAttribute('billing_last_name');
and before:
$post_data = "";
foreach($fields as $key => $value) {
$post_data .= "$key=" . urlencode($value) . "&";
}// end foreach
$post_data = rtrim($post_data, "& ");
With:
/* below added to test for null billing_address /dka */ $addr_test = $o->getAttribute('billing_address'); if (!is_null($addr_test)) { $addr1 = $o->getAttribute('billing_address')->getAddress1(); $addr2 = $o->getAttribute('billing_address')->getAddress2(); $fields['x_city'] = $o->getAttribute('billing_address')->getCity(); $fields['x_state'] = $o->getAttribute('billing_address')->getStateProvince(); $fields['x_zip'] = $o->getAttribute('billing_address')->getPostalCode(); $fields['x_country'] = $o->getAttribute('billing_address')->getCountry(); } else { $addr1 = "Error: Billing address Not Found"; $addr2 = ""; $fields['x_city'] = "Error: Billing address Not Found"; $fields['x_state'] = "Error: Billing address Not Found"; $fields['x_zip'] = "Error: Billing address Not Found";
Viewing 15 lines of 55 lines. View entire code block.
------------------------------------------------------------------------------------------
I've made the following changes in packages/core_commerce/controllers/checkout/shipping/address.php
Replace:
if ($o->getAttribute('shipping_first_name') == $o->getAttribute('billing_first_name')
&& $o->getAttribute('shipping_last_name') == $o->getAttribute('billing_last_name')
&& $o->getAttribute('shipping_address')->__toString() == $o->getAttribute('billing_address')->__toString()
&& $o->getAttribute('shipping_phone') == $o->getAttribute('billing_phone')
) {
$this->set('useBillingAddressForShipping', true);
}
With:
/* below added to test for null shipping_address & billing_address /dka */ $shipping_addr_test = $o->getAttribute('shipping_address'); $billing_addr_test = $o->getAttribute('billing_address'); if ( (!is_null($shipping_addr_test)) && (!is_null($billing_addr_test)) ) { if ($o->getAttribute('shipping_first_name') == $o->getAttribute('billing_first_name') && $o->getAttribute('shipping_last_name') == $o->getAttribute('billing_last_name') && $o->getAttribute('shipping_address')->__toString() == $o->getAttribute('billing_address')->__toString() && $o->getAttribute('shipping_phone') == $o->getAttribute('billing_phone') ) { $this->set('useBillingAddressForShipping', true); } } /* above added to test for null shipping_address & billing_address /dka */
Did this fix your problem with the fatal error? I've run into this exact same problem and couldn't figure out if it was a coding issue or payment gateway issue. I've got dozens of ecommerce installs, but for some reason this issue only seems to be happening on just one site.
Any clue what you guys are doing that'd cause the shipping attribute or the billing attribute to return null?
Thanks,
Korvin
Thanks,
Korvin
The strange thing for this is that the error popped up randomly. A user could submit the order and get the error, hit the back button on their browser and resubmit again and the order would go through. Exact same data submitted both times. I never found an obvious pattern for when the error would come up, because not everyone would get the error.
The fix that hawkeye offers seems a little bit sketchy if that is the case. I'd recommend playing around with disabling mysql query cache and any aggressive PHP opcode cache and see if that helps.