function cw_shipper_AP($weight, $customer_id, $address, $debug, $cart)
{
    global $config, $tables;
    if ($config['Company']['country'] != 'AU' || !is_array($allowed_shipping_methods) || empty($allowed_shipping_methods)) {
        return false;
    }
    $stypes = array(1001 => "STANDARD", 1002 => "EXPRESS", 1003 => "AIR", 1005 => "SEA", 1006 => "ECI_D", 1007 => "ECI_M", 1008 => "EPI");
    $ap_host = "drc.edeliver.com.au";
    $ap_url = "/ratecalc.asp";
    $zipcode = preg_replace("|[^\\d\\w]|i", "", $address['zipcode']);
    $post = "Pickup_Postcode=" . $config['Company']['zipcode'] . "&Destination_Postcode=" . $zipcode . "&Country=" . $address['country'] . "&Weight=" . cw_weight_in_grams($weight) . "&Length=" . $options['param00'] . "&Width=" . $options['param01'] . "&Height=" . $options['param02'] . "&Quantity=1";
    if ($debug == "Y") {
        # Display debug info (header)
        print "<h1>Australia Post Debug Information</h1>";
        $is_display_debug = false;
    }
    foreach ($allowed_shipping_methods as $value) {
        if ($value['code'] != "APOST" || !isset($stypes[$value['service_code']])) {
            continue;
        }
        if ($address['country'] != 'AU' && $value['destination'] == "L" || $address['country'] == 'AU' && $value['destination'] == "I") {
            continue;
        }
        $md5_request = md5($post . $stypes[$value['service_code']]);
        if (!cw_is_shipping_result_in_cache($md5_request) || $debug == "Y") {
            list($header, $result) = cw_http_get_request($ap_host, $ap_url, $post . "&Service_type=" . $stypes[$value['service_code']]);
            if (empty($result)) {
                continue;
            }
            $return = array();
            if (preg_match_all("/^([^=]+)=(.*)\$/Sm", $result, $preg)) {
                foreach ($preg[1] as $k => $v) {
                    $return[$v] = trim($preg[2][$k]);
                }
            }
            if ($return['err_msg'] == "OK") {
                $rates[$value['subcode']] = array("methodid" => $value['subcode'], "rate" => $return['charge'], "shipping_time" => $return['days']);
                $cached_value = array("methodid" => $value['subcode'], "rate" => $return['charge'], "shipping_time" => $return['days']);
                if ($debug != "Y") {
                    cw_save_shipping_result_to_cache($md5_request, $cached_value);
                }
            }
        } else {
            $rates[] = cw_get_shipping_result_from_cache($md5_request);
        }
    }
}
function cw_shipper($weight, $address, $debug = "N", $cart = false)
{
    global $allowed_shipping_methods, $rates;
    global $tables;
    global $config;
    $__intershipper_userinfo = $address;
    $rates = array();
    $intershipper_countries = array('IE' => 'IR', 'VA' => 'IT', 'FX' => 'FR', 'PR' => 'US');
    #
    # Intershipper depends on XML parser (EXPAT extension)
    #
    if (test_expat() == "") {
        return;
    }
    if (empty($address)) {
        if ($config['General']['apply_default_country'] == "Y" || $debug == "Y") {
            $__intershipper_userinfo = cw_user_get_default_address();
        } else {
            return array();
        }
    }
    $pounds = cw_weight_in_grams($weight) / 453;
    $pounds = sprintf("%.2f", round((double) $pounds + 9.999999999999999E-12, 2));
    if ($pounds < 0.1) {
        $pounds = 0.1;
    }
    $servername = "www.intershipper.com";
    $scriptname = "/Shipping/Intershipper/XML/v2.0/HTTP.jsp";
    $username = $config['Shipping']['intershipper_username'];
    $password = $config['Shipping']['intershipper_password'];
    $delivery = $params['param00'];
    $shipmethod = $params['param01'];
    $CO = $config['Company']['country'];
    $ZO = urlencode($config['Company']['zipcode']);
    $CD = $__intershipper_userinfo['country'];
    $ZD = urlencode($__intershipper_userinfo['zipcode']);
    if (!empty($intershipper_countries[$CD])) {
        $CD = $intershipper_countries[$CD];
    }
    if (!empty($intershipper_countries[$CO])) {
        $CO = $intershipper_countries[$CO];
    }
    $__intershipper_userinfo['country'] = $CD;
    $config['Company']['country'] = $CO;
    $length = (double) $params['param02'];
    $width = (double) $params['param03'];
    $height = (double) $params['param04'];
    $dunit = $params['param05'];
    $packaging = $params['param06'];
    $contents = $params['param07'];
    $codvalue = (double) $params['param08'];
    $insvalue = (double) $params['param09'];
    $queryid = substr(uniqid(rand()), 0, 15);
    $wunit = strtoupper(trim($config['General']['weight_symbol']));
    if (strlen($wunit) > 2) {
        $wunit = substr($wunit, 0, 2);
    }
    $allowed_shipping_methods = cw_query("SELECT * FROM {$tables['shipping']} WHERE active=1");
    $carriers = cw_query_column("SELECT DISTINCT(code) FROM {$tables['shipping']} WHERE code<>'' AND intershipper_code!='' AND active=1");
    if (!$carriers || !$username || !$password) {
        return array();
    }
    $post[] = "Version=2.0.0.0";
    $post[] = "ShipmentID=1";
    $post[] = "QueryID=1";
    $post[] = "Username={$username}";
    $post[] = "Password={$password}";
    $post[] = "TotalClasses=4";
    $post[] = "ClassCode1=GND";
    $post[] = "ClassCode2=1DY";
    $post[] = "ClassCode3=2DY";
    $post[] = "ClassCode4=3DY";
    $post[] = "DeliveryType={$delivery}";
    $post[] = "ShipMethod={$shipmethod}";
    $post[] = "OriginationPostal={$ZO}";
    $post[] = "OriginationCountry={$CO}";
    $post[] = "DestinationPostal={$ZD}";
    $post[] = "DestinationCountry={$CD}";
    $post[] = "Currency=USD";
    // Currently, supported only "USD". maxlen=3
    $post[] = "TotalPackages=1";
    $post[] = "BoxID1=box1";
    $post[] = "Weight1={$pounds}";
    $post[] = "WeightUnit1=LB";
    $post[] = "Length1={$length}";
    $post[] = "Width1={$width}";
    $post[] = "Height1={$height}";
    $post[] = "DimensionalUnit1={$dunit}";
    // DimensionalUnit	::= CM | IN
    $post[] = "Packaging1={$packaging}";
    // Packaging		::= BOX | ENV | LTR | TUB
    $post[] = "Contents1={$contents}";
    $post[] = "Cod1={$codvalue}";
    $post[] = "Insurance1={$insvalue}";
    $post[] = "TotalCarriers=" . count($carriers);
    foreach ($carriers as $k => $v) {
        if ($v == 'CPC') {
            $v = 'CAN';
        }
        $post[] = "CarrierCode" . ($k + 1) . "=" . $v;
    }
    $query = join('&', $post);
    $md5_request = md5($query);
    if (cw_is_shipping_result_in_cache($md5_request) && $debug != "Y") {
        return cw_get_shipping_result_from_cache($md5_request);
    }
    list($header, $result) = cw_http_get_request($servername, $scriptname, $query);
    $result = preg_replace("/^<\\?xml\\s+[^>]+>/s", "", trim($result));
    $parse_errors = false;
    $options = array('XML_OPTION_CASE_FOLDING' => 1, 'XML_OPTION_TARGET_ENCODING' => 'ISO-8859-1');
    $parsed = cw_xml_parse($result, $parse_errors, $options);
    $destination = $__intershipper_userinfo['country'] == $config['Company']['country'] ? "L" : "I";
    $packages =& cw_array_path($parsed, 'SHIPMENT/PACKAGE');
    if (is_array($packages)) {
        $rates = array();
        foreach ($packages as $pkginfo) {
            if (empty($pkginfo['#']) || !is_array($pkginfo['#'])) {
                continue;
            }
            foreach ($pkginfo['#']['QUOTE'] as $quote) {
                $carrier = cw_array_path($quote, 'CARRIER/CODE/0/#');
                if ($carrier == 'USP') {
                    $carrier = 'USPS';
                }
                $service = cw_array_path($quote, 'SERVICE/NAME/0/#');
                $sn = cw_array_path($quote, 'SERVICE/CODE/0/#');
                $rate = cw_array_path($quote, 'RATE/AMOUNT/0/#') / 100.0;
                if (!$carrier || !($service || $sn) || !$rate) {
                    continue;
                }
                $saved = -1;
                foreach ($allowed_shipping_methods as $sk => $sv) {
                    if ($sv['code'] != $carrier || $sv['destination'] != $destination) {
                        continue;
                    }
                    if ($sv['intershipper_code'] == 'CPC') {
                        $sv['intershipper_code'] = 'CAN';
                    }
                    if ((!$sn || $sv['intershipper_code'] != $sn) && (!$service || !stristr($sv['shipping'], $service))) {
                        continue;
                    }
                    # Suppressing duplicates
                    if ($saved < 0 || strlen($allowed_shipping_methods[$saved]['shipping']) > strlen($sv['shipping'])) {
                        $saved = $sk;
                    }
                }
                if ($saved >= 0) {
                    $rates[$allowed_shipping_methods[$saved]['subcode']] = $rate;
                }
            }
        }
        if (!empty($rates)) {
            foreach ($rates as $k => $v) {
                $rates[$k] = array("methodid" => $k, "rate" => $v);
            }
            if ($debug != "Y") {
                cw_save_shipping_result_to_cache($md5_request, $rates);
            }
        }
    }
    return $rates;
}
function cw_fedex_prepare_xml_query($packages, $weight, $fedex_options, $to_address, $from_address)
{
    global $config;
    $fedex_weight = cw_units_convert(cw_weight_in_grams($weight), "g", "lbs", 1);
    if ($fedex_weight < 1) {
        $fedex_weight = 1;
    }
    $_time = time() + $config['Appearance']['timezone_offset'] + intval($fedex_options['ship_date']) * 24 * 3600;
    $fedex_options['ship_date_ready'] = date("Y-m-d", $_time) . "T" . date("H:i:s", $_time);
    $fedex_options['original_country_code'] = $from_address["country"];
    if (in_array($fedex_options['original_country_code'], array('US', 'CA'))) {
        $fedex_options['original_postal_code'] = preg_replace("/[^A-Za-z0-9]/", "", $from_address["zipcode"]);
        $fedex_options['original_state_code'] = $from_address["state"];
    } else {
        $fedex_options['original_postal_code'] = preg_replace("/[^A-Za-z0-9]/", "", $from_address["zipcode"]);
        $fedex_options['original_state_code'] = '';
    }
    $fedex_options['destination_country_code'] = $to_address["country"];
    $fedex_options['destination_postal_code'] = preg_replace("/[^A-Za-z0-9]/", "", $to_address["zipcode"]);
    if (in_array($fedex_options['destination_country_code'], array('US', 'CA'))) {
        $fedex_options['destination_state_code'] = $to_address["state"];
    }
    /*
        $return_transit_and_commit = <<<OUT
        <q0:ReturnTransitAndCommit>true</q0:ReturnTransitAndCommit>
    OUT;
    */
    // Carrier codes
    $carriers_xml = '';
    foreach ($fedex_options['carrier_codes'] as $carrier) {
        $carriers_xml .= <<<OUT
    <q0:CarrierCodes>{$carrier}</q0:CarrierCodes>
OUT;
    }
    // Special services
    $special_services_types = $special_services = array('package' => array(), 'shipment' => array());
    if (!empty($fedex_options['cod_value']) && doubleval($fedex_options['cod_value']) > 0) {
        $special_services['shipment'][] = <<<OUT
            <q0:CodDetail>
                <q0:CollectionType>{$fedex_options['cod_type']}</q0:CollectionType>
            </q0:CodDetail>
OUT;
        $special_services['shipment'][] = <<<OUT
        <q0:CodCollectionAmount>
            <q0:Currency>{$fedex_options['currency_code']}</q0:Currency>
            <q0:Amount>{$fedex_options['cod_value']}</q0:Amount>
        </q0:CodCollectionAmount>
OUT;
        $special_services_types['shipment'][] = 'COD';
    }
    if ($fedex_options['hold_at_location'] == 'Y') {
        $special_services_types['shipment'][] = 'HOLD_AT_LOCATION';
        $special_services['shipment'][] = "<q0:HoldAtLocationDetail><q0:PhoneNumber>{$to_address['phone']}</q0:PhoneNumber></q0:HoldAtLocationDetail>";
    }
    if (!empty($fedex_options['dg_accessibility'])) {
        $special_services['package'][] = <<<OUT
        <q0:DangerousGoodsDetail>
            <q0:Accessibility>{$fedex_options['dg_accessibility']}</q0:Accessibility>
        </q0:DangerousGoodsDetail>
OUT;
        $special_services_types['package'][] = 'DANGEROUS_GOODS';
    }
    if ($fedex_options['dry_ice'] == 'Y') {
        $special_services['package'][] = <<<OUT
        <q0:DryIceWeight>
            <q0:Units>LB</q0:Units>
            <q0:Value>{$fedex_weight}</q0:Value>
        </q0:DryIceWeight>
OUT;
        $special_services_types['package'][] = 'DRY_ICE';
    }
    if ($fedex_options['inside_pickup'] == 'Y') {
        $special_services_types['shipment'][] = 'INSIDE_PICKUP';
    }
    if ($fedex_options['inside_delivery'] == 'Y') {
        $special_services_types['shipment'][] = 'INSIDE_DELIVERY';
    }
    if ($fedex_options['saturday_pickup'] == 'Y') {
        $special_services_types['shipment'][] = 'SATURDAY_PICKUP';
    }
    if ($fedex_options['saturday_delivery'] == 'Y') {
        $special_services_types['shipment'][] = 'SATURDAY_DELIVERY';
    }
    if ($fedex_options['nonstandard_container'] == "Y") {
        $special_services_types['package'][] = 'NON_STANDARD_CONTAINER';
    }
    if (!empty($fedex_options['signature'])) {
        $special_services['package'][] = <<<OUT
        <q0:SignatureOptionDetail>
            <q0:OptionType>{$fedex_options['signature']}</q0:OptionType>
        </q0:SignatureOptionDetail>
OUT;
    }
    foreach ($special_services_types as $k => $ss_types) {
        if (!empty($ss_types)) {
            foreach ($ss_types as $key => $ss_type) {
                $special_services_types[$k][$key] = "<q0:SpecialServiceTypes>" . $ss_type . "</q0:SpecialServiceTypes>";
            }
        }
        $special_services[$k] = cw_array_merge($special_services_types[$k], $special_services[$k]);
    }
    foreach ($special_services as $k => $ss) {
        if (!empty($ss)) {
            $special_services_xml[$k] = '';
            foreach ($ss as $_service) {
                $special_services_xml[$k] .= "\t\t" . $_service . "\n";
            }
            $special_services_xml[$k] = "<q0:SpecialServicesRequested>" . $special_services_xml[$k] . "</q0:SpecialServicesRequested>";
        } else {
            $special_services_xml[$k] = '';
        }
    }
    // Packages query
    $package_count = count($packages);
    $i = 1;
    $items_xml = '';
    /*
    global $REMOTE_ADDR;
    if ($REMOTE_ADDR == "85.130.76.171") {
        cw_log_add("fedex_shipping_package", array($packages));
    }
    */
    foreach ($packages as $pack) {
        $dimensions_xml = cw_fedex_prepare_dimensions_xml($pack, $fedex_options);
        // Declared value
        $declared_value_xml = '';
        if ($fedex_options['send_insured_value'] == 'Y' && !empty($pack['price']) && doubleval($pack['price']) > 0) {
            $declared_value_xml = <<<OUT
            <q0:InsuredValue>
                <q0:Currency>{$fedex_options['currency_code']}</q0:Currency>
                <q0:Amount>{$pack['price']}</q0:Amount>
            </q0:InsuredValue>
OUT;
        }
        //        $pack['weight'] = cw_units_convert(cw_weight_in_grams($pack[weight]), "g", "lbs", 1);
        //        if (!$pack['weight']) $pack['weight'] = 1;
        $items_xml .= <<<EOT
        <q0:RequestedPackageLineItems>
            <q0:SequenceNumber>{$i}</q0:SequenceNumber>
            {$declared_value_xml}
            <q0:Weight>
                <q0:Units>LB</q0:Units>
                <q0:Value>{$pack[weight]}</q0:Value>
            </q0:Weight>
            {$dimensions_xml}
            {$special_services_xml['package']}
        </q0:RequestedPackageLineItems>
EOT;
        $i++;
    }
    $residential = $fedex_options['residential_delivery'] == 'Y' ? "<q0:Residential>true</q0:Residential>" : "";
    // Handling charges
    if (!empty($fedex_options['handling_charges_amount']) && doubleval($fedex_options['handling_charges_amount']) > 0) {
        $_handling_type = $fedex_options['handling_charges_type'] == "FIXED_AMOUNT" ? "<q0:FixedValue><q0:Currency>{$fedex_options['currency_code']}</q0:Currency><q0:Amount>{$fedex_options['handling_charges_amount']}</q0:Amount></q0:FixedValue>" : "<q0:PercentValue>{$fedex_options['handling_charges_amount']}</q0:PercentValue>";
        $handling_charges_xml = <<<OUT
    <q0:VariableHandlingChargeDetail>
        <q0:VariableHandlingChargeType>{$fedex_options['handling_charges_type']}</q0:VariableHandlingChargeType>
        {$_handling_type}
    </q0:VariableHandlingChargeDetail>
OUT;
    } else {
        $handling_charges_xml = '';
    }
    // Prepare the XML request
    $xml_query = <<<OUT
<?xml version="1.0" encoding="UTF-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://fedex.com/ws/rate/v7" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:RateRequest>
    <q0:WebAuthenticationDetail>
        <q0:UserCredential>
            <q0:Key>{$fedex_options['key']}</q0:Key>
            <q0:Password>{$fedex_options['password']}</q0:Password>
        </q0:UserCredential>
    </q0:WebAuthenticationDetail>

    <q0:ClientDetail>
        <q0:AccountNumber>{$fedex_options['account_number']}</q0:AccountNumber>
        <q0:MeterNumber>{$fedex_options['meter_number']}</q0:MeterNumber>
    </q0:ClientDetail>

    <q0:TransactionDetail>
        <q0:CustomerTransactionId>Basic Rate</q0:CustomerTransactionId>
    </q0:TransactionDetail>

    <q0:Version>
        <q0:ServiceId>crs</q0:ServiceId>
        <q0:Major>7</q0:Major>
        <q0:Intermediate>0</q0:Intermediate>
        <q0:Minor>0</q0:Minor>
    </q0:Version>

    {$return_transit_and_commit}

    {$carriers_xml}
    
    <q0:RequestedShipment>
        <q0:ShipTimestamp>{$fedex_options['ship_date_ready']}</q0:ShipTimestamp>
        <q0:DropoffType>{$fedex_options['dropoff_type']}</q0:DropoffType>
        <q0:PackagingType>{$fedex_options['packaging']}</q0:PackagingType>

        <q0:Shipper>
            <q0:Address>
                <q0:StateOrProvinceCode>{$fedex_options['original_state_code']}</q0:StateOrProvinceCode>
                <q0:PostalCode>{$fedex_options['original_postal_code']}</q0:PostalCode>
                <q0:CountryCode>{$fedex_options['original_country_code']}</q0:CountryCode>
            </q0:Address>
        </q0:Shipper>

        <q0:Recipient>
            <q0:Address>
                <q0:StateOrProvinceCode>{$fedex_options['destination_state_code']}</q0:StateOrProvinceCode>
                <q0:PostalCode>{$fedex_options['destination_postal_code']}</q0:PostalCode>
                <q0:CountryCode>{$fedex_options['destination_country_code']}</q0:CountryCode>
                {$residential}
            </q0:Address>
        </q0:Recipient>

        <q0:ShippingChargesPayment>
            <q0:PaymentType>SENDER</q0:PaymentType>
            <q0:Payor>
                <q0:AccountNumber>{$fedex_options['account_number']}</q0:AccountNumber>
                <q0:CountryCode>{$fedex_options['original_country_code']}</q0:CountryCode>
            </q0:Payor>
        </q0:ShippingChargesPayment>

        {$special_services_xml['shipment']}

        {$handling_charges_xml}

        <q0:RateRequestTypes>ACCOUNT</q0:RateRequestTypes>
        <q0:PackageCount>{$package_count}</q0:PackageCount>
        <q0:PackageDetail>INDIVIDUAL_PACKAGES</q0:PackageDetail>

        {$items_xml}

    </q0:RequestedShipment>
</q0:RateRequest>
</soapenv:Body>
</soapenv:Envelope>
OUT;
    return $xml_query;
}
function cw_ups_shipping_get_rates($params, $return)
{
    global $config;
    global $ups_services;
    if (empty($config['shipping_ups']['username']) || empty($config['shipping_ups']['password']) || empty($config['shipping_ups']['accesskey'])) {
        return $return;
    }
    extract($params);
    $weight_condition = "weight_min<='{$weight}' AND (weight_limit='0' OR weight_limit>='{$weight}')";
    $shipping = cw_func_call('cw_shipping_search', array('data' => array('active' => 1, 'addon' => 'shipping_ups', 'where' => array($weight_condition))));
    if (!$shipping) {
        return $return;
    }
    $ups_parameters = $config['shipping_ups'];
    switch ($ups_parameters['account_type']) {
        case "01":
            $ups_parameters['customer_classification_code'] = "01";
            $ups_parameters['pickup_type'] = "01";
            break;
        case "02":
            $ups_parameters['customer_classification_code'] = "03";
            $ups_parameters['pickup_type'] = "03";
            break;
        case "03":
        default:
            $ups_parameters['customer_classification_code'] = "04";
            $ups_parameters['pickup_type'] = "11";
    }
    $src_country_code = $from_address['country'];
    $src_city = cw_ups_xml_quote($from_address['city']);
    $src_zipcode = $from_address['zipcode'];
    $dest_code = $dst_country_code = $to_address['country'];
    if ($to_address['state'] == "PR" || $to_address['state'] == "VI") {
        $dest_code = $dst_country_code = $to_address['state'];
    }
    $dst_city = cw_ups_xml_quote($to_address['city']);
    $dst_zipcode = $to_address['zipcode'];
    if ($src_country_code == "US" && !empty($ups_parameters['customer_classification_code'])) {
        $customer_classification_code = $ups_parameters['customer_classification_code'];
        $customer_classification_query = <<<EOT
    <CustomerClassification>
        <Code>{$customer_classification_code}</Code>
    </CustomerClassification>
EOT;
    }
    #
    # Pickup Type and Packaging Type
    #
    $pickup_type = $ups_parameters['pickup_type'];
    $packaging_type = $ups_parameters['packaging_type'];
    $insvalue = round(doubleval($ups_parameters['iv_amount']), 2);
    $pkgopt = array();
    if ($insvalue > 0.1) {
        $pkgopt[] = <<<EOT
                <InsuredValue>
                    <CurrencyCode>{$ups_parameters['iv_currency']}</CurrencyCode>
                    <MonetaryValue>{$insvalue}</MonetaryValue>
                </InsuredValue>

EOT;
    }
    $delivery_conf = intval($ups_parameters['delivery_conf']);
    if ($delivery_conf > 0 && $delivery_conf < 4) {
        $pkgopt[] = <<<EOT
                <DeliveryConfirmation>
                    <DCISType>{$delivery_conf}</DCISType>
                </DeliveryConfirmation>

EOT;
    }
    $codvalue = round(doubleval($ups_parameters['codvalue']), 2);
    $cod_is_allowed = false;
    $cod_is_allowed |= ($src_country_code == "US" || $src_country_code == "PR") && ($dst_country_code == "US" || $dst_country_code == "PR");
    $cod_is_allowed |= $src_country_code == "CA" && ($dst_country_code == "US" || $dst_country_code == "CA");
    if ($cod_is_allowed && $codvalue > 0.1) {
        $pkgopt[] = <<<EOT
                <COD>
                    <CODCode>3</CODCode>
                    <CODFundsCode>{$ups_parameters['cod_funds_code']}</CODFundsCode>
                    <CODAmount>
                        <CurrencyCode>{$ups_parameters['cod_currency']}</CurrencyCode>
                        <MonetaryValue>{$codvalue}</MonetaryValue>
                    </CODAmount>
                </COD>

EOT;
    }
    $pkgparams = count($pkgopt) > 0 ? "\t\t\t<PackageServiceOptions>\n" . join("", $pkgopt) . "\t\t\t</PackageServiceOptions>\n" : "";
    $srvopts = array();
    if ($ups_parameters['options']) {
        foreach ($ups_parameters['options'] as $opt) {
            switch ($opt) {
                case "AH":
                    $pkgparams .= "\t\t\t<AdditionalHandling/>";
                    break;
                case "SP":
                    $srvopts[] = "\t\t\t<SaturdayPickupIndicator/>\n";
                    break;
                case "SD":
                    $srvopts[] = "\t\t\t<SaturdayDeliveryIndicator/>\n";
                    break;
            }
        }
    }
    if (!empty($ups_parameters['shipper_number'])) {
        $shipper_number_xml = <<<EOT
            <ShipperNumber>{$ups_parameters['shipper_number']}</ShipperNumber>
EOT;
    } else {
        $shipper_number_xml = "";
    }
    if (count($srvopts) > 0) {
        $shipment_options_xml .= "\t\t<ShipmentServiceOptions>\n" . join("", $srvopts) . "\t\t</ShipmentServiceOptions>";
    }
    $weight = cw_units_convert(cw_weight_in_grams($weight), "g", "lbs", 1);
    if (!$weight) {
        $weight = 0.1;
    }
    // Fill the packages
    $packages_xml = '';
    $packages = cw_call('cw_shipping_get_packages', array($params));
    foreach ($packages as $pack) {
        $packages_xml .= <<<EOT
        <Package>
            <PackagingType>
                <Code>{$packaging_type}</Code>
            </PackagingType>
            <PackageWeight>
                <UnitOfMeasurement>
                    <Code>LBS</Code>
                </UnitOfMeasurement>
                <Weight>{$pack['weight']}</Weight>
            </PackageWeight>
    {$dimensions_query}
    {$pkgparams}
        </Package>

EOT;
    }
    $query = <<<EOT
<?xml version='1.0'?>
<AccessRequest xml:lang='en-US'>
    <AccessLicenseNumber>{$config['shipping_ups']['accesskey']}</AccessLicenseNumber>
    <UserId>{$config['shipping_ups']['username']}</UserId>
    <Password>{$config['shipping_ups']['password']}</Password>
</AccessRequest>
<?xml version='1.0'?>
<RatingServiceSelectionRequest xml:lang='en-US'>
    <Request>
        <TransactionReference>
            <CustomerContext>Rating and Service</CustomerContext>
            <XpciVersion>1.0001</XpciVersion>
        </TransactionReference>
        <RequestAction>Rate</RequestAction>
        <RequestOption>shop</RequestOption>
    </Request>
    <PickupType>
        <Code>{$pickup_type}</Code>
    </PickupType>
{$customer_classification_query}
    <Shipment>
        <Shipper>
{$shipper_number_xml}
            <Address>
                <City>{$src_city}</City>
                <PostalCode>{$src_zipcode}</PostalCode>
                <CountryCode>{$src_country_code}</CountryCode>
            </Address>
        </Shipper>
        <ShipFrom>
            <Address>
                <City>{$src_city}</City>
                <PostalCode>{$src_zipcode}</PostalCode>
                <CountryCode>{$src_country_code}</CountryCode>
            </Address>
        </ShipFrom>
        <ShipTo>
            <Address>
                <City>{$dst_city}</City>
                <PostalCode>{$dst_zipcode}</PostalCode>
                <CountryCode>{$dst_country_code}</CountryCode>
            </Address>
        </ShipTo>
{$packages_xml}
{$shipment_options_xml}       
    </Shipment>
</RatingServiceSelectionRequest>
EOT;
    $parsed = cw_ups_process($query, 'Rate');
    $ups_rates = array();
    $error['code'] = cw_array_path($parsed, 'RATINGSERVICESELECTIONRESPONSE/RESPONSE/ERROR/ERRORCODE/0/#');
    if ($error['code']) {
        $error['msg'] = cw_array_path($parsed, 'RATINGSERVICESELECTIONRESPONSE/RESPONSE/ERROR/ERRORDESCRIPTION/0/#');
    } else {
        $origin_code = cw_ups_get_origin_code($src_country_code);
        $dest_code = cw_ups_get_origin_code($dest_code);
        $entries = cw_array_path($parsed, 'RATINGSERVICESELECTIONRESPONSE/RATEDSHIPMENT');
        if (is_array($entries)) {
            foreach ($entries as $k => $entry) {
                $service_type = intval(cw_array_path($entry, 'SERVICE/CODE/0/#'));
                # kornev, don't use that for now
                //              $estimated_time = cw_array_path($entry, 'GUARANTEEDDAYSTODELIVERY/0/#');
                if ($estimated_time) {
                    $curtime = time();
                    $_time = strtotime($estimated_time);
                    if ($_time > $curtime) {
                        $estimated_time = ceil(($_time - $curtime) / 86400);
                    } else {
                        $estimated_time = 0;
                    }
                } else {
                    $estimated_time = 0;
                }
                $estimated_rate = cw_array_path($entry, 'TOTALCHARGES/MONETARYVALUE/0/#');
                if ($ups_services[$service_type][$origin_code]) {
                    if ($service_type == '11' && $origin_code == 'US' && $dest_code == 'CA') {
                        $service_type = '110';
                    } elseif ($service_type == '65') {
                        if ($origin_code == 'US' || $origin_code == 'PR') {
                            $service_type = '145';
                        } elseif ($origin_code == 'CA' && ($dest_code == 'US' || $dest_code == 'CA') || $origin_code == 'EU' && $dest_code == 'EU') {
                            $service_type = '146';
                        } else {
                            $service_type = '144';
                        }
                        // UPS Worldwide Express Saver (SM)
                    } else {
                        $service_type = $ups_services[$service_type][$origin_code];
                    }
                }
                $ups_rates[$service_type] = array('original_rate' => $estimated_rate, 'shipping_time' => $estimated_time);
            }
        }
    }
    if ($ups_rates) {
        foreach ($shipping as $sh) {
            if (!$ups_rates[$sh['code']]) {
                continue;
            }
            $sh = array_merge($sh, $ups_rates[$sh['code']]);
            $return[$sh['shipping_id']] = $sh;
        }
    }
    return $return;
}
$hash['s_city'] = $order['userinfo']['s_city'];
$hash['s_state'] = $order['userinfo']['s_state'];
$hash['s_zip'] = $order['userinfo']['s_zipcode'];
$hash['s_country'] = $order['userinfo']['s_country'];
$hash['shipmethod'] = $stype;
$hash['insuredvalue'] = $order['order']['total'];
$hash['weight'] = 0;
if (in_array($hash['s_country'], array("DO", "PR", "US"))) {
    $UPS_wunit = "LBS";
} else {
    $UPS_wunit = "KGS";
}
if (!empty($order['products'])) {
    foreach ($order['products'] as $p) {
        $hash['weight'] += $p['weight'] * $p['amount'];
    }
    $hash['weight'] = max(0.1, round(cw_weight_in_grams($hash['weight']) / ($UPS_wunit == "LBS" ? 453.6 : 1000), 1));
}
$strs[] = implode($delimiter, $hash);
# Create header
$header = implode($delimiter, cw_array_merge(array_keys($hash), $p_head));
# Create response
$response = array("result" => 'ok', "image" => $header . "\n" . implode("\n", $strs), "image_type" => "text/csv");
if ($is_first_ups_label) {
    $all_ups_shipping_labels['result'] = 'ok';
    $all_ups_shipping_labels['image'] = $header . "\n" . implode("\n", $strs);
    $all_ups_shipping_labels['image_type'] = 'text/csv';
    $is_first_ups_label = false;
} else {
    $all_ups_shipping_labels['image'] .= "\n" . implode("\n", $strs);
}
function cw_shipper_ARB($weight, $customer_id, $address, $debug, $cart)
{
    global $config, $tables;
    $airborne_account =& cw_session_register("airborne_account");
    $ARB_FOUND = false;
    if (is_array($allowed_shipping_methods)) {
        foreach ($allowed_shipping_methods as $key => $value) {
            if ($value['code'] == "ARB") {
                $ARB_FOUND = true;
                break;
            }
        }
    }
    if (!$ARB_FOUND) {
        return;
    }
    cw_load('http', 'xml');
    $ab_id = $config['Shipping']['ARB_id'];
    $ab_password = $config['Shipping']['ARB_password'];
    $ab_ship_accnum = $config['Shipping']['ARB_account'];
    $ab_testmode = $config['Shipping']['ARB_testmode'];
    #
    # Currently shipping only from US is supported
    #
    if (empty($ab_id) || empty($ab_password) || empty($ab_ship_accnum) || $config['Company']['country'] != "US") {
        return;
    }
    if ($ab_testmode == 'Y') {
        $ab_url = "https://ecommerce.airborne.com:443/ApiLandingTest.asp";
    } else {
        $ab_url = "https://ecommerce.airborne.com:443/ApiLanding.asp";
    }
    $ab_ship_key = ab_get_ship_key($ab_url, $ab_id, $ab_password, $ab_ship_accnum, $config['Company']['zipcode'], $ab_testmode, $address['country'] != 'US');
    if (empty($ab_ship_key)) {
        if ($debug == "Y") {
            ab_show_faults();
        }
        ab_conv_faults();
        return;
    }
    $ship_weight = max(1, round(cw_weight_in_grams($weight) / 453.6, 0));
    $ship_weight_oz = round(cw_weight_in_grams($weight) / 28.3, 0);
    $ab_packaging = $params['param00'];
    $ab_ship_length = $params['param02'];
    $ab_ship_width = $params['param03'];
    $ab_ship_height = $params['param04'];
    $ab_ship_prot_code = $params['param05'];
    $ab_ship_prot_value = $params['param06'];
    $ab_ship_codpmt = $params['param08'];
    $ab_ship_codval = (double) $params['param09'];
    # options
    list($ab_ship_haz, $ab_ship_own_account) = explode(',', $params['param07']);
    $_ship_date = date("Y-m-d", time() + $params['param01'] * 86400);
    $mod_AB_ship_flags = array(109 => array('code' => 'G', 'sub' => ''), 31 => array('code' => 'S', 'sub' => ''), 33 => array('code' => 'N', 'sub' => ''), 32 => array('code' => 'E', 'sub' => ''), 124 => array('code' => 'E', 'sub' => '1030'), 125 => array('code' => 'E', 'sub' => 'SAT'), 32 => array('code' => 'IE', 'sub' => ''));
    if ($address['country'] != 'US') {
        return ab_int_ratings($allowed_shipping_methods, $address, $weight, $debug, array("package" => $ab_packaging, "length" => $ab_ship_length, "width" => $ab_ship_width, "height" => $ab_ship_height, "id" => $ab_id, "password" => $ab_password, "account" => $ab_ship_accnum, "testmode" => $ab_testmode, "url" => $ab_url, "skey" => $config['Shipping']['ARB_shipping_key_intl'], "weight" => $ship_weight, "weight_oz" => $ship_weight_oz, "ship_date" => $_ship_date));
    }
    if (cw_use_arb_account($params) && isset($airborne_account) && trim($airborne_account) != "") {
        $_party_code = "R";
        $_party_account = "<AccountNbr>" . trim($airborne_account) . "</AccountNbr>";
    } else {
        $_party_code = "S";
        $_party_account = "";
    }
    $shipments = "";
    $cnt = 0;
    $ship_reqs = array();
    foreach ($allowed_shipping_methods as $method) {
        if ($method['code'] == "ARB" && ($ship_weight < $method['weight_limit'] || $method['weight_limit'] == 0.0) && isset($mod_AB_ship_flags[$method['subcode']]) && $method['destination'] == 'L') {
            $_ship_srv_key = $mod_AB_ship_flags[$method['subcode']]['code'];
            $_ship_srv_sub = $mod_AB_ship_flags[$method['subcode']]['sub'];
            if ($_ship_srv_key == "G" && $ab_packaging == 'L') {
                # Letter express is not allowed with Ground Shipments. (Code=4119)
                continue;
            }
            if ($_ship_srv_key == "G" && $_ship_srv_sub == "SAT") {
                # Saturday pickup service is not available for Ground shipments. (Code=4105).
                continue;
            }
            $_shipproc_instr = "";
            $_secial_express = "";
            if ($_ship_srv_key == 'E') {
                # Express Saturday & Express 10:30AM services are not compatible within "Hazardous Materials"
                if ($ab_ship_haz == "Y" && $_ship_srv_sub != "") {
                    continue;
                }
                if ($_ship_srv_sub == "SAT") {
                    $_shipproc_instr = "<ShipmentProcessingInstructions><Overrides><Override><Code>ES</Code></Override></Overrides></ShipmentProcessingInstructions>";
                    $_secial_express = "<SpecialServices><SpecialService><Code>SAT</Code></SpecialService></SpecialServices>";
                } elseif ($_ship_srv_sub == "1030") {
                    $_secial_express = "<SpecialServices><SpecialService><Code>1030</Code></SpecialService></SpecialServices>";
                }
            }
            $_additional_protection = '';
            if ($ab_ship_prot_code == 'AP') {
                $_additional_protection = "<AdditionalProtection><Code>{$ab_ship_prot_code}</Code><Value>{$ab_ship_prot_value}</Value></AdditionalProtection>";
            }
            $_secial_haz = "";
            if ($ab_ship_haz == "Y") {
                $_secial_haz = "<SpecialServices><SpecialService><Code>HAZ</Code></SpecialService></SpecialServices>";
            }
            $_cod_payment = "";
            if ($ab_ship_codval > 0 && $_party_code == "S") {
                # When using COD service freight charges must be billed to sender. (Code=4116)
                $_cod_payment = "<CODPayment><Code>{$ab_ship_codpmt}</Code><Value>{$ab_ship_codval}</Value></CODPayment>";
            }
            $_dimensions = '';
            if ($ab_packaging == 'P') {
                $_dimensions = "<Weight>{$ship_weight}</Weight><Dimensions><Width>{$ab_ship_width}</Width><Height>{$ab_ship_height}</Height><Length>{$ab_ship_length}</Length></Dimensions>";
            } else {
                if ($ship_weight_oz > 8) {
                    # Shipment exceeds allowable weight for Letter. (Code=4118)
                    # Letter Express packages must be in Letter Express envelopes and weigh 8 ounces or less.
                    continue;
                }
            }
            $shipment = <<<EOT
\t<Shipment action='RateEstimate' version='1.0'>
\t\t<ShippingCredentials>
\t\t\t<ShippingKey>{$ab_ship_key}</ShippingKey>
\t\t\t<AccountNbr>{$ab_ship_accnum}</AccountNbr>
\t\t</ShippingCredentials>
\t\t<ShipmentDetail>
\t\t\t<ShipDate>{$_ship_date}</ShipDate>
\t\t\t<Service>
\t\t\t\t<Code>{$_ship_srv_key}</Code>
\t\t\t</Service>
\t\t\t<ShipmentType>
\t\t\t\t<Code>{$ab_packaging}</Code>
\t\t\t</ShipmentType>
\t\t\t{$_secial_express}
\t\t\t{$_secial_haz}
\t\t\t{$_dimensions}
\t\t\t{$_additional_protection}
\t\t</ShipmentDetail>
\t\t<Billing>
\t\t\t{$_cod_payment}
\t\t\t<Party>
\t\t\t\t<Code>{$_party_code}</Code>
\t\t\t</Party>
\t\t\t{$_party_account}
\t\t</Billing>
\t\t<Receiver>
\t\t\t<Address>
\t\t\t\t<City>{$address['city']}</City>
\t\t\t\t<State>{$address['state']}</State>
\t\t\t\t<Country>{$address['country']}</Country>
\t\t\t\t<PostalCode>{$address['zipcode']}</PostalCode>
\t\t\t</Address>
\t\t</Receiver>
\t\t{$_shipproc_instr}
\t</Shipment>
EOT;
            $shipments .= $shipment;
            $cnt++;
            if ($cnt >= 5) {
                $cnt = 0;
                if ($shipments != "") {
                    $ship_reqs[] = $shipments;
                }
                $shipments = "";
            }
        }
    }
    if ($shipments != "") {
        $ship_reqs[] = $shipments;
    }
    if (count($ship_reqs) > 0) {
        $ab_request = "";
        foreach ($ship_reqs as $req) {
            ab_rate_estimate($ab_url, $ab_id, $ab_password, $debug, $req);
        }
    }
}
         if ($config['shipping_label_generator']['usps_sample_mode'] == 'Y') {
             $head = "DelivConfirmCertifyV3.0";
             $api = "DelivConfirmCertifyV3";
         } else {
             $head = "DeliveryConfirmationV3.0";
             $api = "DeliveryConfirmationV3";
         }
     }
 } else {
     return;
 }
 $weight_in_ounces = 0;
 foreach ($order['products'] as $product) {
     $weight_in_ounces += $product['weight'] * $product['amount'];
 }
 $weight_in_ounces = ceil(round(cw_weight_in_grams($weight) / 28.35, 3));
 if ($weight_in_ounces < 1) {
 }
 $weight_in_ounces = 1;
 list($from['s_address1'], $from['s_address2']) = explode("\n", $from['s_address']);
 list($to['s_address1'], $to['s_address2']) = explode("\n", $to['s_address']);
 if (empty($from['s_address2'])) {
     $from['s_address2'] = $from['s_address1'];
     $from['s_address1'] = '';
 }
 if (empty($to['s_address2'])) {
     $to['s_address2'] = $to['s_address1'];
     $to['s_address1'] = '';
 }
 $from_fname = $from['s_firstname'];
 $from_lname = $from['s_lastname'];
function cw_shipper_CPC($weight, $customer_id, $address, $debug, $cart)
{
    global $config, $tables;
    if ($config['Company']['country'] != "CA" || empty($config['Shipping']['CPC_merchant_id'])) {
        return;
    }
    $cpc_methods = array();
    foreach ($allowed_shipping_methods as $v) {
        if ($v['code'] == "CPC") {
            $cpc_methods[] = $v;
        }
    }
    if (empty($cpc_methods)) {
        return;
    }
    $cp_merchant = $config['Shipping']['CPC_merchant_id'];
    $cp_language = "en";
    $cp_qnty = "1";
    $cp_packed = true;
    $cp_weight = round(cw_weight_in_grams($weight) / 1000, 3);
    if ($cp_weight < 0.1) {
        $cp_weight = 0.1;
    }
    $cp_description = $params['param00'];
    $cp_length = $params['param01'];
    $cp_width = $params['param02'];
    $cp_height = $params['param03'];
    $cp_currency_rate = $params['param05'];
    $cp_insured_value = $params['param04'];
    $cp_dest_country = $address['country'];
    $cp_dest_city = $address['city'];
    $cp_dest_zip = $address['zipcode'];
    $cp_dest_state = empty($address['state']) ? "NA" : $address['state'];
    $cp_orig_zip = $config['Company']['zipcode'];
    # Server DNS; if does not work, use 'cybervente.postescanada.ca:30000'
    $cp_host = "sellonline.canadapost.ca:30000";
    if (isset($cart['discounted_subtotal'])) {
        $itemsPrice = "<itemsPrice>{$cart['discounted_subtotal']}</itemsPrice>";
    } elseif (!empty($cp_insured_value)) {
        $itemsPrice = "<itemsPrice>{$cp_insured_value}</itemsPrice>";
    } else {
        $itemsPrice = "";
    }
    $cp_request = "<?xml version=\"1.0\" ?>\n" . "<eparcel>" . "<language>{$cp_language}</language>\n" . "<ratesAndServicesRequest>\n" . "  <merchantCPCID>{$cp_merchant}</merchantCPCID>\n" . "  <fromPostalCode>{$cp_orig_zip}</fromPostalCode>\n" . "  {$itemsPrice}\n" . "  <lineItems>\n" . "    <item>\n" . "      <quantity>{$cp_qnty}</quantity>\n" . "      <weight>{$cp_weight}</weight>\n" . "      <length>{$cp_length}</length>\n" . "      <width>{$cp_width}</width>\n" . "      <height>{$cp_height}</height>\n" . "      <description>{$cp_description}</description>\n" . ($cp_packed ? "      <readyToShip/>\n" : "") . "    </item>\n" . "  </lineItems>\n" . "  <city>{$cp_dest_city}</city>\n" . "  <provOrState>{$cp_dest_state}</provOrState>\n" . "  <country>{$cp_dest_country}</country>\n" . "  <postalCode>{$cp_dest_zip}</postalCode>\n" . "</ratesAndServicesRequest>\n" . "</eparcel>";
    $md5_request = md5($cp_request);
    if (!cw_is_shipping_result_in_cache($md5_request) || $debug == "Y") {
        list($a, $result) = cw_http_post_request($cp_host, "/", $cp_request);
        $parse_errors = false;
        $options = array('XML_OPTION_CASE_FOLDING' => 1, 'XML_OPTION_TARGET_ENCODING' => 'ISO-8859-1');
        $parsed = cw_xml_parse($result, $parse_errors, $options);
        $products =& cw_array_path($parsed, 'EPARCEL/RATESANDSERVICESRESPONSE/PRODUCT');
        if (is_array($products)) {
            foreach ($products as $product) {
                $pid = $product['@']['ID'];
                $rate = cw_array_path($product, 'RATE/0/#');
                if ($pid === false || $rate === false) {
                    continue;
                }
                $is_found = false;
                foreach ($cpc_methods as $v) {
                    if ($v['service_code'] == $pid) {
                        $rates[] = array("methodid" => $v['subcode'], "rate" => $rate * $cp_currency_rate);
                        $is_found = true;
                        break;
                    }
                }
                if (!empty($pid) && !$is_found) {
                    $tmp_name = cw_array_path($product, "NAME/0/#");
                    cw_add_new_smethod($tmp_name, "CPC", array("service_code" => $pid));
                }
            }
        }
        if ($debug != "Y") {
            cw_save_shipping_result_to_cache($md5_request, $rates);
        }
        $error_code = cw_array_path($parsed, 'EPARCEL/ERROR/STATUSCODE/0/#');
        if ($error_code !== false) {
            $error_msg = cw_array_path($parsed, 'EPARCEL/ERROR/STATUSMESSAGE/0/#');
        }
    } else {
        $rates = cw_get_shipping_result_from_cache($md5_request);
    }
}
function cw_shipper_USPS($weight, $customer_id, $address, $debug, $cart)
{
    global $config, $tables, $current_language;
    $USPS_username = $config['Shipping']['USPS_username'];
    $USPS_password = $config['Shipping']['USPS_password'];
    $USPS_servername = $config['Shipping']['USPS_servername'];
    $use_usps_https = false;
    if (empty($USPS_username) || empty($USPS_servername)) {
        return;
    }
    $USPS_FOUND = false;
    if (is_array($allowed_shipping_methods)) {
        foreach ($allowed_shipping_methods as $key => $value) {
            if ($value['code'] == "USPS") {
                $USPS_FOUND = true;
                break;
            }
        }
    }
    if (!$USPS_FOUND) {
        return;
    }
    cw_load('http', 'xml');
    $pounds = 0;
    $ounces = ceil(round(cw_weight_in_grams($weight) / 28.35, 3));
    if ($ounces < 1) {
        $ounces = 1;
    }
    $mailtype = $params['param00'];
    $package_size = $params['param01'];
    $machinable = $params['param02'];
    $container_express = $params['param03'];
    $container_priority = $params['param04'];
    if (!empty($container_express) && $container_express != 'None') {
        $container_express = "<Container>" . $container_express . "</Container>";
    } else {
        $container_express = "";
    }
    if (!empty($container_priority) && $container_priority != 'None') {
        $container_priority = "<Container>" . $container_priority . "</Container>";
    } else {
        $container_priority = "";
    }
    if ($address['country'] == 'PR' || $address['country'] == 'GU' || $address['country'] == 'VI') {
        $address['country'] = 'US';
    }
    $dst_country = USPS_get_country($address['country']);
    if (empty($dst_country)) {
        $dst_country = cw_query_first_cell("SELECT value FROM {$tables['languages']} WHERE name = 'country_" . $address['country'] . "' AND code = '{$current_language}'");
    }
    $USPS_file = $USPS_servername == "testing.shippingapis.com" ? "/ShippingAPITest.dll" : "/ShippingAPI.dll";
    $hash = array();
    if ($address['country'] != $config['Company']['country']) {
        # International shipping
        $query = <<<EOT
<IntlRateRequest USERID="{$USPS_username}" PASSWORD="******">
<Package ID="0">
<Pounds>{$pounds}</Pounds>
<Ounces>{$ounces}</Ounces>
<MailType>{$mailtype}</MailType>
<Country>{$dst_country}</Country>
</Package>
</IntlRateRequest>
EOT;
        $md5_request = md5($query);
        if (cw_is_shipping_result_in_cache($md5_request) && $debug != "Y") {
            $rates = cw_get_shipping_result_from_cache($md5_request);
            return;
        }
        if ($use_usps_https) {
            $post = array("API=IntlRate", "XML=" . urlencode($query));
            list($header, $result) = cw_https_request("GET", "https://" . $USPS_servername . ":443" . $USPS_file . "?API=IntlRate&XML=" . urlencode($query));
        } else {
            list($header, $result) = cw_http_get_request($USPS_servername, $USPS_file, "API=IntlRate&XML=" . urlencode($query));
        }
        $xml = cw_xml_parse($result, $err);
        # Get <Error> elemenet
        $err = cw_array_path($xml, "IntlRateResponse/Package/Error");
        if (empty($err)) {
            # Get <Service> elements
            $packages = cw_array_path($xml, "IntlRateResponse/Package/Service");
            if (!empty($packages) && is_array($packages)) {
                foreach ($packages as $p) {
                    # Get shipping method name
                    $sname = cw_array_path($p, "SvcDescription/0/#");
                    # Get rate
                    $rate = cw_array_path($p, "Postage/0/#");
                    # Get comment
                    #$comment = cw_array_path($p, "SvcCommitments/0/#");
                    if (empty($sname) || zerolen($rate)) {
                        continue;
                    }
                    # Define shipping method
                    $is_found = false;
                    foreach ($allowed_shipping_methods as $sm) {
                        if ($sm['code'] == "USPS" && $sm['destination'] == "I" && preg_match("/^" . preg_quote($sm['shipping'], "/") . "/S", "USPS " . $sname)) {
                            if (!in_array($sm['subcode'], $hash)) {
                                $rates[] = array("methodid" => $sm['subcode'], "rate" => $rate, "warning" => "");
                                $hash[] = $sm['subcode'];
                            }
                            $is_found = true;
                            break;
                        }
                    }
                    if (!$is_found) {
                        # Add new shipping method
                        cw_add_new_smethod("USPS " . $sname, "USPS", array("destination" => "I"));
                    }
                }
                if ($debug != "Y") {
                    cw_save_shipping_result_to_cache($md5_request, $rates);
                }
            }
        }
    } else {
        # Domestic shipping
        $ZO = $config['Company']['zipcode'];
        $ZD = $address['zipcode'];
        $query = <<<EOT
<RateV2Request USERID="{$USPS_username}">
\t<Package ID="0">
\t\t<Service>EXPRESS</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t{$container_express}
\t\t<Size>{$package_size}</Size>
\t</Package>
\t<Package ID="1">
\t\t<Service>FIRST CLASS</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t<Container>None</Container>
\t\t<Size>{$package_size}</Size>
\t</Package>
\t<Package ID="2">
\t\t<Service>PRIORITY</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t{$container_priority}
\t\t<Size>{$package_size}</Size>
\t</Package>
\t<Package ID="3">
\t\t<Service>PARCEL</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t<Container>None</Container>
\t\t<Size>{$package_size}</Size>
\t\t<Machinable>{$machinable}</Machinable>
\t</Package>
\t<Package ID="4">
\t\t<Service>BPM</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t<Container>None</Container>
\t\t<Size>{$package_size}</Size>
\t</Package>
\t<Package ID="5">
\t\t<Service>LIBRARY</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t<Container>None</Container>
\t\t<Size>{$package_size}</Size>
\t</Package>
\t<Package ID="6">
\t\t<Service>MEDIA</Service>
\t\t<ZipOrigination>{$ZO}</ZipOrigination>
\t\t<ZipDestination>{$ZD}</ZipDestination>
\t\t<Pounds>{$pounds}</Pounds>
\t\t<Ounces>{$ounces}</Ounces>
\t\t<Container>None</Container>
\t\t<Size>{$package_size}</Size>
\t</Package>
</RateV2Request>
EOT;
        $md5_request = md5($query);
        if (cw_is_shipping_result_in_cache($md5_request) && $debug != "Y") {
            $rates = cw_get_shipping_result_from_cache($md5_request);
            return;
        }
        if ($use_usps_https) {
            $post = array("API=RateV2", "XML=" . urlencode($query));
            list($header, $result) = cw_https_request("GET", "https://" . $USPS_servername . ":443" . $USPS_file . "?API=RateV2&XML=" . urlencode($query));
        } else {
            list($header, $result) = cw_http_get_request($USPS_servername, $USPS_file, "API=RateV2&XML=" . urlencode($query));
        }
        $xml = cw_xml_parse($result, $err);
        # Get <Package> elements
        $packages = cw_array_path($xml, "RateV2Response/Package");
        if (is_array($packages)) {
            foreach ($packages as $p) {
                # Get <Error> element
                $err = cw_array_path($p, "Error");
                if (!empty($err)) {
                    continue;
                }
                # Get shipping method name
                $sname = cw_array_path($p, "Postage/MailService/0/#");
                # Get rate
                $rate = cw_array_path($p, "Postage/Rate/0/#");
                if (empty($sname) || zerolen($rate)) {
                    continue;
                }
                # Define shipping method
                $is_found = false;
                foreach ($allowed_shipping_methods as $sm) {
                    if ($sm['code'] == "USPS" && $sm['destination'] == "L" && preg_match("/^" . preg_quote($sm['shipping'], "/") . "/S", "USPS " . $sname)) {
                        if (!in_array($sm['subcode'], $hash)) {
                            $rates[] = array("methodid" => $sm['subcode'], "rate" => $rate, "warning" => "");
                            $hash[] = $sm['subcode'];
                        }
                        $is_found = true;
                        break;
                    }
                }
                if (!$is_found) {
                    # Add new shipping method
                    cw_add_new_smethod("USPS " . $sname, "USPS", array("destination" => "L"));
                }
            }
            if ($debug != "Y") {
                cw_save_shipping_result_to_cache($md5_request, $rates);
            }
        }
        // if (is_array($packages))
    }
}