Custom Shipping Method (DHL API) causes endless spinner on checkout
-
Hi,
I am midway developing a plugin that retrieves the Shipping Cost (via DHL XML Services) of package during the checkout, from the vendor to the customer. Due to the project’s requirements, the cheaper one is selected and charged to the customer.
When the checkout page loads and populates all the billing/delivery fields (if you are logged in), all the correct cost is pulled through to the Cart Totals table, then everything is fine. After a fraction of a second, for some reason I wasn’t able to identify yet, the spinner comes back and stays there for ever.
Both JS and PHP error consoles are clean.
During my debugging, I have hardcoded the cost (in $rate) and commented out all the API related code – That test worked like a charm.
However, I need to pull the real DHL quote… I have been on this issue for days. I, literally, can’t think anything new to try out.
Plugin code (with hardcoded&tested API request):
<?php /** * Plugin Name: [HWG] DHL * Description: Custom Shipping Method for WooCommerce */ if(!defined('WPINC')) { die; } /** * Check if WooCommerce is active */ if(in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { function hwg_dhl_shipping_method_init() { if(!class_exists('HWG_DHL_Shipping_Method')) { class HWG_DHL_Shipping_Method extends WC_Shipping_Method { /** * Constructor for your shipping class * * @access public * @return void */ public function __construct() { $this->id = 'hwg_dhl'; $this->method_title = __('DHL Shipment - DHL XML Services', 'hwg_dhl'); $this->method_description = __('Custom Shipping Method for DHL XML Services', 'hwg_dhl'); $this->enabled = isset($this->settings['enabled']) ? $this->settings['enabled'] : 'yes'; $this->title = isset($this->settings['title']) ? $this->settings['title'] : __('DHL Shipment', 'hwg_dhl'); $this->init(); } /** * Init your settings * * @access public * @return void */ function init() { // Load the settings API $this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings $this->init_settings(); // This is part of the settings API. Loads settings you previously init. // Save settings in admin if you have any defined add_action('woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' )); } /** * Define settings field for this shipping * @return void */ function init_form_fields() { $this->form_fields = array( 'enabled' => array( 'title' => __('Enable', 'hwg_dhl'), 'type' => 'checkbox', 'description' => __('Enable this shipping.', 'hwg_dhl'), 'default' => 'yes' ), 'title' => array( 'title' => __('Title', 'hwg_dhl'), 'type' => 'text', 'description' => __('Title to be display on site', 'hwg_dhl'), 'default' => __('DHL', 'hwg_dhl') ) ); } /** * This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters. * * @access public * @param mixed $package * @return void */ public function calculate_shipping($package = array()) { $cost = get_lower_rate(get_dhl_quote($package)); $rate = array( 'id' => $this->id, 'label' => $this->title, 'cost' => $cost ); $this->add_rate($rate); } } } } add_action('woocommerce_shipping_init', 'hwg_dhl_shipping_method_init'); function add_hwg_dhl_shipping_method($methods) { $methods['hwg_dhl'] = 'HWG_DHL_Shipping_Method'; return $methods; } add_filter('woocommerce_shipping_methods', 'add_hwg_dhl_shipping_method'); } function round_up($value, $precision) { $pow = pow(10, $precision); return (ceil($pow * $value) + ceil($pow * $value - ceil($pow * $value))) / $pow; } function get_dhl_quote($package) { $webservice_url = 'https://xmlpitest-ea.dhl.com/XMLShippingServlet'; // (...) Tested API request $request_param = ' <!--?xml version="1.0" encoding="UTF-8"?--> <p:DCTRequest xmlns:p="https://www.dhl.com" xmlns:p1="https://www.dhl.com/datatypes" xmlns:p2="https://www.dhl.com/DCTRequestdatatypes" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="https://www.dhl.com DCT-req.xsd "> <GetQuote> <Request> <ServiceHeader> <MessageTime>2017-07-31T13:30:50+01:00</MessageTime> <MessageReference>1234567890123456789012345678901</MessageReference> <SiteID>CIMGBTest</SiteID> <Password>DLUntOcJma</Password> </ServiceHeader> </Request> <From> <CountryCode>US</CountryCode> <Postalcode>90047</Postalcode> <City>Los Angeles</City> </From> <BkgDetails> <PaymentCountryCode>GB</PaymentCountryCode> <Date>2017-07-31</Date> <ReadyTime>PT23H59M</ReadyTime> <ReadyTimeGMTOffset>+01:00</ReadyTimeGMTOffset> <DimensionUnit>CM</DimensionUnit> <WeightUnit>KG</WeightUnit> <Pieces> <Piece> <PieceID>1</PieceID> <Height>6</Height> <Depth>15</Depth> <Width>15</Width> <Weight>0.6</Weight> </Piece> </Pieces> <IsDutiable>Y</IsDutiable> <NetworkTypeCode>AL</NetworkTypeCode> </BkgDetails> <To> <CountryCode>JP</CountryCode> <Postalcode>150-0047</Postalcode> <City>Tokyo</City> </To> <Dutiable> <DeclaredCurrency>USD</DeclaredCurrency> <DeclaredValue>999</DeclaredValue> </Dutiable> </GetQuote> </p:DCTRequest> '; var_dump($request_param); $ch = curl_init($webservice_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $request_param); //curl_setopt($ch, CURLOPT_TIMEOUT, 120); // time allowed to connect to server curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); // time allowed to process curl call curl_setopt($ch, CURLOPT_TIMEOUT, 120); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verbose); // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_USERPWD, 'CIMGBTest:DLUntOcJma'); /* ** Alternative way to set username and password ** */ // $headers = array( // 'Content-Type:application/xml', // 'Authorization: Basic '. base64_encode("CIMGBTest:DLUntOcJma") // ); // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); $xml_string = curl_exec($ch); if($result === FALSE) { printf("cUrl error(#%d): %s<br>\n", curl_errno($ch), htmlspecialchars(curl_error($ch))); } curl_close($ch); return $xml_string; } function get_lower_rate($xml_string) { $xml_xml = new SimpleXMLElement($xml_string); $shipping_service = array(); $min_rate = 999999; foreach($xml_xml->GetQuoteResponse->BkgDetails->QtdShp as $dhl_service) { if(strlen($dhl_service->ShippingCharge) > 0) { // print '<pre style="display:block!important;">'; // print_r($dhl_service->ShippingCharge); // print '</pre>'; if($dhl_service->ShippingCharge < $min_rate) { $shipping_service = array( 'GlobalProductCode' => $dhl_service->GlobalProductCode, 'TotalTransitDays' => $dhl_service->TotalTransitDays, 'DeliveryDate' => $dhl_service->DeliveryDate, 'DeliveryTime' => $dhl_service->DeliveryTime, 'ShippingCharge' => $dhl_service->ShippingCharge ); } } } return round_up(floatval($shipping_service['ShippingCharge']), 2); }
Just mention that this is my first plugin within WooCommerce. I reckon the code can be optimised, I will get to that when it works.
Any idea is welcome, cheers guys.
- The topic ‘Custom Shipping Method (DHL API) causes endless spinner on checkout’ is closed to new replies.