April 26, 2017

Magento Prevent Different Shipping Address On Some Products

A few years ago, we wrote a module that would monitor checkout activity ( article) on checkouts and then apply certain business rules based on observations (ie: ban the session after x attempts of a credit card checkout).

Another fit of fraudulent activity has started, but for some reason it only affects one particular product line. The fraudster purchases the product, passes EXACT matches on the CVV/billing address, but then ships the product to a separate location. Even though our Magento Admin screens force the warehouse to double-check the order (big red warning on shipping/billing address being different), we would still get the charge-back from the credit card company because the order would still go through.

99% of the customer shipped to the billing address already, while the others were all fraudulent. To prevent this from happening, we modified our custom overridden OnepageController.php’s “saveBillingAction()” function, to check if the customer has one of our fraud products in the cart. If it detects the “special” product, it disables the ability to change the shipping address. After you save the billing address, it immediately goes to the Shipping Method. So a fraudster would be forced to ship the product to the correct billing address, rather than their intended place to pick it up. Granted, they can still place the order, but it will do them no good and they will never receive the product they intended to steal.

//SNIPPET of OnepageController.php
  //Stop shipping actions for specific reasons
    // There are certain items we don't want to allow shipping to different addresses, due to fraud.
    public function saveBillingAction()
        //1106 = target product id
        foreach ($quote->getAllItems() as $item) {
            $id = $item->getProduct()->getId();
            if(in_array($id, $no_sep_ship_products)){
        if ($this->_expireAjax()) {
        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost('billing', array());
            $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
            if (isset($data['email'])) {
                $data['email'] = trim($data['email']);
            $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
            //override our desire for ship to different address...force it...
                $data['use_for_shipping'] =1;
            if (!isset($result['error'])) {
                if ($this->getOnepage()->getQuote()->isVirtual()) {
                    $result['goto_section'] = 'payment';
                    $result['update_section'] = array(
                        'name' => 'payment-method',
                        'html' => $this->_getPaymentMethodsHtml()
                } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
                    $result['goto_section'] = 'shipping_method';
                    $result['update_section'] = array(
                        'name' => 'shipping-method',
                        'html' => $this->_getShippingMethodsHtml()
                    //allow sep shipping for NON fraud potential orders
                    if($NO_SEP_SHIPPING_ADDRESS_ALLOWED != true){
                        $result['allow_sections'] = array('shipping');
                        $result['duplicateBillingInfo'] = 'true';
                } else {
                    $result['goto_section'] = 'shipping';

Fatal error: Uncaught Error: [] operator not supported for strings in /home/silvatec/public_html/wp-content/themes/layerswp/core/helpers/post.php:62 Stack trace: #0 /home/silvatec/public_html/wp-content/themes/layerswp/partials/content-single.php(81): layers_post_meta(1560) #1 /home/silvatec/public_html/wp-includes/template.php(690): require('/home/silvatec/...') #2 /home/silvatec/public_html/wp-includes/template.php(647): load_template('/home/silvatec/...', false) #3 /home/silvatec/public_html/wp-includes/general-template.php(167): locate_template(Array, true, false) #4 /home/silvatec/public_html/wp-content/themes/layerswp/single.php(20): get_template_part('partials/conten...', 'single') #5 /home/silvatec/public_html/wp-includes/template-loader.php(74): include('/home/silvatec/...') #6 /home/silvatec/public_html/wp-blog-header.php(19): require_once('/home/silvatec/...') #7 /home/silvatec/public_html/index.php(17): require('/home/silvatec/...') #8 {main} thrown in /home/silvatec/public_html/wp-content/themes/layerswp/core/helpers/post.php on line 62