Jump to content
greasemonkey

FedEx - Web Services v9

Recommended Posts

Tried again this morning by completely removing the module, commenting out line 299 (in V9.5) in fedexwebservices.php:

 

if($ShipmentRateDetail->ShipmentRateDetail->RateType=='PAYOR_LIST_PACKAGE')

 

and removing the comments from line 300:

if($ShipmentRateDetail->ShipmentRateDetail->RateType==('PAYOR_LIST_PACKAGE' || 'PAYOR_LIST_SHIPMENT')) // try this if having international quoting errors

 

It now seems to work for both domestic and international. I must not have removed and re-installed the module after applying the V9.5 update files.

Share this post


Link to post
Share on other sites

Why is my FedEx shipping not recognizing Canada addresses as "International Ground" instead of just "Ground?"  It cost me about $30 today. :(

Share this post


Link to post
Share on other sites

It seems this is a trait by FedEx that FedEx Ground is returned for Canada.  However, why is this code not working in my fedexwebservices.php file:

 

    // because FEDEX_GROUND also is returned for Canadian Addresses, we need to check if the country matches the store country and whether international ground is enabled
    if ((MODULE_SHIPPING_FEDEX_WEB_SERVICES_GROUND == 'true' && $order->delivery['country']['id'] == STORE_COUNTRY) || (MODULE_SHIPPING_FEDEX_WEB_SERVICES_GROUND == 'true' && ($order->delivery['country']['id'] != STORE_COUNTRY) && MODULE_SHIPPING_FEDEX_WEB_SERVICES_INTERNATIONAL_GROUND == 'true')) {
      $this->types['FEDEX_GROUND'] = array('icon' => '', 'handling_fee' => ($order->delivery['country']['id'] == STORE_COUNTRY ? MODULE_SHIPPING_FEDEX_WEB_SERVICES_HANDLING_FEE : MODULE_SHIPPING_FEDEX_WEB_SERVICES_INT_HANDLING_FEE));
      $this->types['GROUND_HOME_DELIVERY'] = array('icon' => '', 'handling_fee' => ($order->delivery['country']['id'] == STORE_COUNTRY ?

 

??

 

My store country is most definitely USA - my USPS and UPS modules are not having a problem distinguishing Canada as an International destination.

Share this post


Link to post
Share on other sites

This is another one where the module/code makes me feel pretty stupid.  This is entirely setup in the admin-configuration for the FedEx module.  "International Ground" apparently means FedEx Ground if you are in an international country (Canada).  For some reason, I thought "International Ground" would work for a Canadian address.  Disable it, and the domestic rate option of "FedEx Ground" disappears from the checkout.  "FedEx Ground" does not actually show up for any addresses, including Canada.  The only ground service that shows up is "Ground Home Delivery" for US addresses (if your store is in the US and you enable "Ground").

Edited by TomB01

Share this post


Link to post
Share on other sites

I downloaded Fedex shipping adds on. How can I instal or uplaod to my oscommerce website? I did unzip the file. whats the right path to upload to admin ?

 

Thank you,

 

Maria

Share this post


Link to post
Share on other sites

FedEx is moving to dimensional shipping on 1 Jan 2015.  See http://news.van.fedex.com/fedex-announces-pricing-changes

 

 

Looks like this version of FedEx never had dimensional shipping added.

 

Anyone looking at that?

 

If I read that right, FedEx will apply dimensional shipping to Freight and Ground services, but they will also keep the weight based shipping.

This change to these 2 specific services seems to be USA exclusive and all other services are not affected anyway.

As I do not personally ship inside the USA, do not use any of these mentioned services and always ship by weight only, I did not have the need to look into this and will not spend the time to modify the module, but it should be quite easy to modify it and add the dimension shipping or you can hire a freelancer to modify it for you from places like http://www.freelancer.com

Share this post


Link to post
Share on other sites

First, thank you RoadDoctor for all of your work on this module. I have v9.4.3.1 all working, but fixed one issue and still have another one.

 

First, I think the instructions for the "ship_separately" functionality are incomplete, and/or the code in the includes/modules/shipping/fedexwebservices.php file is wrong. The settings for the module seem to combine the UPS XML "Ready to Ship" and FedEx "Ship_Separately", and the code does the same, but the installation instructions only tell the user how to get the "ship_separately" working (there is a fedexweb.sql.php in the "sql" folder that alters the products table, and it does add the ship_separately field, but not the "ready_to_ship" field, which the code requires when the module option is enabled).

 

I was using the previous FedEx Realtime Quotes, so I already had the ship_separately field in the database, and already had the categories.php changes made, but the shipping module still expected the "ready_to_ship" field in the products table. For anyone else who has this issue, you have two options.

 

1) manually add the field to the products table

 

2) In the fedexwebservices.php module file, change the following two lines

 

Around line 181, change

 

$dimensions_query = "SELECT products_ready_to_ship, products_ship_sep, products_weight FROM " . TABLE_PRODUCTS . "

 

To this

$dimensions_query = "SELECT products_ship_sep, products_weight FROM " . TABLE_PRODUCTS . "

 

Around line 186, change

 

if ($product_dimensions['products_ready_to_ship'] == 1 || $product_dimensions['products_ship_sep'] == 1) {

To this

if ($product_dimensions['products_ship_sep'] == 1) {

 

 

The above changes will tell the code to not even try to find or use the "products_ready_to_ship" column in the products table.

 

 

 

I still have one more issue though. In the osCommerce general Shipping options, the "Maximum Weight You Will Ship" variable does work with this FedEx WebServices Module, but "Package Tare Weight" and "Larger Packages - percentage increase" options do not seem to have any effect on this shipping module. Is anyone else having this problem? Or does anyone know what could be affecting it or how to make it work?

 

@@pcwerks Were you able to find a solution to this probelm?

 

I am exerpiencing the same issue :-/

Share this post


Link to post
Share on other sites

For those struggling with Error Code 1000 (detailed report below) I found a fix. It's been talked about before on this thread, but looks like the specific bits have changed a little.

 

If you're using test credentials, the standard s1:address will not work, and you'll be rejected form the server. I think this has been mentioned elsewhere in the thread, but I couldn't find any exact details. To make it all work with test creds, change:

<s1:address location="https://gateway.fedex.com/web-services/"/>

to 

<s1:address location="https://wsbeta.fedex.com:443/web-services/rate"/>

and back again when you're done and want to use production info. Obviously, this can change frequently at FedEx' prerogative. So tread lightly and keep an eye out! 

Share this post


Link to post
Share on other sites

Has anyone successfully modified this to provide quotes with insurance?  I've found a post that mentioned 3 places that must be modified, but nothing specific as to how it needs to be changed.

 

All I need it to do is request insurance for the amount of the subtotal.  I've already added an "enable insurance" field to the config, and a check whether or not it's true or false.  Just no real idea where to go from here.

Share this post


Link to post
Share on other sites

Playing with insurance I like using Echo statements to show waht is happening with variables - for example to try and figure out what the value for insurance should be (sub_total - text) on the page I use:

 

      echo "Order amount for insurance purposes: " . $totals . "<br>";

 

However this shows as blank unless you enable one of the previous commented out statements (around line 144)

 

// Depending on your version of Order Editor, any one of the following lines may be appropriate for your setup.
//    $totals = $order->info['subtotal'] = $cart->total;  // from CRE Loaded code - testing - this may be the one for all? // 09/04/2014 -  Disabling this as it may no longer be necessary and it screws up the sub-totals
//    $totals = $order->info['subtotal'] = $_SESSION['cart']->show_total();  // original code
//    $totals = $order->info['subtotal'] || $_SESSION['cart']->show_total();  // or perhaps this is better
//    $totals = $cart->show_total();  // this seems to work for most - needed for insurance to get sub-total amount

 

I enable the last one to show the sub-totals in my echo statement that shows up in my test setup (localhost) at the left top of the screen. This value IS handed to the data sent to FedEx (when $totals shows a value), however it doesn't appear to come back as anything in the price that makes a difference. Unless the value in my shopping cart is too low during this test ($219USD).

 

I'll play some more and see what happens...

Share this post


Link to post
Share on other sites

For those struggling with Error Code 1000 (detailed report below) I found a fix. It's been talked about before on this thread, but looks like the specific bits have changed a little.

 

If you're using test credentials, the standard s1:address will not work, and you'll be rejected form the server. I think this has been mentioned elsewhere in the thread, but I couldn't find any exact details. To make it all work with test creds, change:

<s1:address location="https://gateway.fedex.com/web-services/"/>

to 

<s1:address location="https://wsbeta.fedex.com:443/web-services/rate"/>

and back again when you're done and want to use production info. Obviously, this can change frequently at FedEx' prerogative. So tread lightly and keep an eye out! 

I reworked that somewhat, created two RateService file in /catalog/includes/wsdl/ - one called RateService_v9.wsdl (the default one) and a second called RateService_Test_v9.wsdl where I modified the line to:

<s1:address location="https://gatewaybeta.fedex.com:443/web-services/rate"/>

but left the default file as usual.

 

Then in catalog/includes/modules/shipping/fedexwebservice.php I added (around line 83):

// added for Web Services Testing - Sept 1, 2015
     if ((MODULE_SHIPPING_FEDEX_WEB_SERVICES_TEST) == 'true') {
     $path_to_wsdl = DIR_FS_CATALOG . DIR_WS_INCLUDES . "wsdl/RateService_v9_Test.wsdl"; 
     } else { 
     $path_to_wsdl = DIR_FS_CATALOG . DIR_WS_INCLUDES . "wsdl/RateService_v9.wsdl";
     }
// End addition for Web Services testing  

 and then at line 519:

    tep_db_query ("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Test Mode', 'MODULE_SHIPPING_FEDEX_WEB_SERVICES_TEST', 'false', 'Testing using gatewaybeta.fedex.com', '6', '19', 'tep_cfg_select_option(array(\'true\', \'false\'), ', now())");

and line 571 (just after module_shipping_debugging'; !!! Add a comma after module_shipping_debugging !!!

                 'MODULE_SHIPPING_FEDEX_WEB_SERVICES_TEST'

and the reinstalled fedexwebservices.php to install the changes.

 

Now it is easier to switch between the test and production environment - of course you have to change passwords, signin stuff, etc.!

Share this post


Link to post
Share on other sites

While I have the rate quoting working using rateservice_v9.wsdl, there are some shortfalls - it appears that insurance is not calculated into the price even though the insurance amount is passed to the FedEx server:

 

<ns1:TotalInsuredValue><ns1:Currency>USD</ns1:Currency><ns1:Amount>219.00</ns1:Amount></ns1:TotalInsuredValue>

 

With or without an insurance amount there, the cost to the customer does not change.

 

Thus I was thinking that it may be time to update to the latest rateservice_v18.wsdl file, but adding that to the /wdsl directory (and editing the fedexwebservices.php file so it uses it) doesn't work.

 

I get this error back:

 

xmlns="http://fedex.com/ws/rate/v18"><HighestSeverity>ERROR</HighestSeverity><Notifications><Severity>ERROR</Severity><Source>crs</Source><Code>300</Code><Message>Package1 - Group package count must be at least a value of 1.</Message><LocalizedMessage>Package 1 - Group package count must be at least a value of 1.</LocalizedMessage>

 

which means that v18 wants parameters sent to the server that aren't considered in v9, so one has to add something to take care of group packages - even if the best way to start is setting it to default to "1".

 

The error list page on FedEx says error 300:

 

Package {PACKAGE_INDEX} - Group package count must be at least a value of 1.

 

so one needs to introduce PACKAGE_INDEX - somewhere!

 

 

 

I was also looking at using the label generation - but that is for another day.

Edited by Pinball

Share this post


Link to post
Share on other sites

@@Pinball

 

Numinex who codes for ZenCart has a much more up to date version of this module... perhaps you could look to their module for inspiration in adapting/updating to the latest wsdl and perhaps adding in address verification etc.... Jeff Lew (the original creator of this FedEx code) has been very helpful to me in the past when I updated this previously to work with osc,


-Dave

Share this post


Link to post
Share on other sites

Is there a way to make Saturday Delivery as a separate option only for those who want to use it, instead of accounting for it whether needed or not? I don't usually do Saturday Delivery, but sometimes, people ask for that, so I need to charge them in addition to whatever they already paid.

Share this post


Link to post
Share on other sites

I am hoping someone has worked out how to get insurance added to the shipping qoute with this module. I'm not very clear on how to modify XML code.

 

FedEx responded to my request for help (below), but so far I have not been able to find out how to implement this. Any help would be greatly appreciated!

 

Response Via Email (Christian Moran) 12/04/2015 12:30 PM

You can add insurance to shipments by passing another portion in your transactions.

<InsuredValue>
<Currency>USD</Currency>
<Amount>100.00</Amount>
</InsuredValue>

for example. You can find more information in the developer guide at https://www.fedex.com/us/developer/WebHelp/ws/2015/html/webServicesLandingPage.html

 

 

Share this post


Link to post
Share on other sites

You don't modify the xml code directly.  Everything is generated through the fedexwebservices.php module.  I don't use insurance and I've modified the module i use but I think it's set to work.  Look around line 16 for MODULE_SHIPPING_FEDEX_WEB_SERVICES_INSURE and adjust that setting.  If you have a test site to experiment with and you should, you can use var_dump to see the request or the reponse. Find the first line in the code and then put the var_dump after it.  Don't do this on a live site though.

        $response = $client->getRates($request);
var_dump($response);

 


I'm not really a dog.

Share this post


Link to post
Share on other sites

Hi, I'm getting the dreaded error:

 

 

 

Please enter a ZIP Code to obtain your shipping quote.
Or possibly:
If no rate is shown, the heavy weight of the item(s) in your Shopping Cart suggests a Request for Freight Quote, rather than FedEx Ground service, is recommended.

 

osC 2.3.1

Fedex WebService 9.4.6 then 9.5.1

SOAP installed, tested, and working

Shipping from Canada to Canada , in KGs

Production credentials

UPSXML not installed

Ship Separate option not installed or enabled

 

Tried switching the commented out IF for international problem.

Verified all my info 10 times.

Uninstalled re-installed.

Tried List and Account.

Verified that postal code is same in Admin and Fedex as what Fedex has on file.

Verified that address is entered exactly as what Fedex has.

Verified that my country code is correct in the CONFIGURATION table.

Added the recipient StateOrProvince code to outgoing XML.

Added this to checkout_shipping.php:

// BOF changes for adding class packing
  if (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'Ready-to-ship only') {
    $dimensions_support = 1;
  } elseif (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'With product dimensions') {
    $dimensions_support = 2;
  } else {
    $dimensions_support = 0;
  }
 
  if ($dimensions_support > 0) {
    require(DIR_WS_CLASSES . 'packing.php');
    $packing = new packing;
  }
// EOF changes for adding class packing

Is there a specific version that works best with 2.3.1?
I read this entire thread and tried everything.

 

I sent a sample XML request/response to Fedex and they see no problem with it, structure, or data provided. They hinted that it could be a problem with using v9 when the current version is v18... v18 integration of this contrib hasn't happened yet, I'm not qualified to do it... Anything else I should try?
 

THANK YOU!

Share this post


Link to post
Share on other sites

Hello again,

 

Turns out I was requesting a test quote for a postal code that Fedex doesn't serve, so the "no valid services"/ZIP Code error is sometimes correct... kids, try various postal codes before assuming there's a technical problem.

 

So now I get some rates from the Fedex server as XML (as seen with the Debug Headers function of the contrib) but the shipping page otherwise fails, so it's blank (or internal server error when debug is off). The response from the Fedex server appears correct, so is the contrib not able to digest it for the user? Anyone else having this problem?

 

I'll uninstall and re-install again to see..

Edited by cinolas

Share this post


Link to post
Share on other sites

Greetings again. So re-installing 9.4.5 worked well, upgrading to 9.5.1 causes an internal server error on the checkout_shipping page (I'm on osC 2.31)

 

I really wish I could upgrade to 9.5.1 to remove the known bugs and add estimated delivery dates to the rates show to the customer. I tried grafting just that part of the new fedexwebservices.php code into my 9.4.5 file but it didn't work (only showed delivery time for overnight, all prices went to $0, etc).

 

Anyone know what the internal server error is caused by in the latest version?

 

Thanks

Share this post


Link to post
Share on other sites

Hey I've been installing and going through the code trying to fix the Fatal error in version 9.5.1 some people (including myself) have gotten after switching to ACCOUNT rates.

 

It looks like the XML response from FedEx changes the structure a bit when using FedEx Ground (I'm testing from Canada to Canada) when in that ACCOUNT rates mode (doesn't seem to effect the LIST mode but i needed to switch that if statement including the PAYER_LIST_SHIPMENT).

 

I've fixed it by adding this code for anyone that just wants to copy the code:

if($rateReply->ServiceType === 'FEDEX_GROUND') {
    $cost = ($rateReply->RatedShipmentDetails->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
} else {
    $cost = ($rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
}

Put that instead of line 625 (in 9.5.1) or on the line that reads:

$cost = $rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount;

Might need to add other types where 'FEDEX_GROUND' is if International Ground is the same structure.

Share this post


Link to post
Share on other sites

Hey I've been installing and going through the code trying to fix the Fatal error in version 9.5.1 some people (including myself) have gotten after switching to ACCOUNT rates.

 

It looks like the XML response from FedEx changes the structure a bit when using FedEx Ground (I'm testing from Canada to Canada) when in that ACCOUNT rates mode (doesn't seem to effect the LIST mode but i needed to switch that if statement including the PAYER_LIST_SHIPMENT).

 

I've fixed it by adding this code for anyone that just wants to copy the code:

if($rateReply->ServiceType === 'FEDEX_GROUND') {
    $cost = ($rateReply->RatedShipmentDetails->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
} else {
    $cost = ($rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
}

Put that instead of line 625 (in 9.5.1) or on the line that reads:

$cost = $rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount;

Might need to add other types where 'FEDEX_GROUND' is if International Ground is the same structure.

Thank you @@dapennsta

 

In my case I had to change line 313 from:

$cost = ($rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;

to:

if($rateReply->ServiceType === 'FEDEX_GROUND') {
$cost = ($rateReply->RatedShipmentDetails->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
} else {
$cost = ($rateReply->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount)/MODULE_SHIPPING_FEDEX_WEB_SERVICES_CURRENCY;
}

Thank you again for the contribution and solution!

Share this post


Link to post
Share on other sites

For defining the shipping to type (commercial or residential) I have added a new field to the customer table called address_type.

 

On log in, this new field is made as a session, having the values :

 

residential

commercial

empty (not set  since customer has not added to the cart any items and checked out)

 

the session variable $address_type is added to the shipping module function quote as a global.

 

New code to add into the function quote is:

    if($address_type == ''){

        $path_to_address_validation_wsdl = DIR_FS_CATALOG . DIR_WS_INCLUDES . "wsdl/AddressValidationService_v2.wsdl";
        $av_client = new SoapClient($path_to_address_validation_wsdl, array('trace' => 1)); // Refer to http://us3.php.net/manual/en/ref.soap.php for more information
        ini_set("soap.wsdl_cache_enabled", "0");
        $residential_address = true;
        $address_validation = false;

          $av_request['WebAuthenticationDetail'] = array('UserCredential' => array('Key' => $this->fedex_key, 'Password' => $this->fedex_pwd));
          $av_request['ClientDetail'] = array('AccountNumber' => $this->fedex_act_num, 'MeterNumber' => $this->fedex_meter_num);
          $av_request['TransactionDetail'] = array('CustomerTransactionId' => ' *** Address Validation Request v2 using PHP ***');
          $av_request['Version'] = array('ServiceId' => 'aval', 'Major' => '2', 'Intermediate' => '0', 'Minor' => '0');
          $av_request['RequestTimestamp'] = date('c');
          $av_request['Options'] = array('CheckResidentialStatus' => 1,
                                         'VerifyAddress' => 1,
                                         'MaximumNumberOfMatches' => 10,
                                         'StreetAccuracy' => 'MEDIUM',
                                         'DirectionalAccuracy' => 'MEDIUM',
                                         'CompanyNameAccuracy' => 'MEDIUM',
                                         'ConvertToUpperCase' => 1,
                                         'RecognizeAlternateCityNames' => 1,
                                         'ReturnParsedElements' => 1);
          $av_request['AddressesToValidate'] = array(
            0 => array(
              'AddressId' => 'Customer Address',
              'Address' => array(
                'StreetLines' => array(utf8_encode($street_address), utf8_encode($street_address2)),
                'Company' => $order->delivery['company'],
                'PostalCode' => $postcode,
                'City' => $city,
                'StateOrProvinceCode' => $state,
                'CompanyName' => $order->delivery['company'],
                'CountryCode' => $country_id
              )
            )
          );
          try {
            $av_response = $av_client->addressValidation($av_request);
            if ($av_response->HighestSeverity == 'SUCCESS') {
              $address_validation = true;
              if ($av_response->AddressResults->ProposedAddressDetails->ResidentialStatus == 'BUSINESS') {
                $residential_address = false;
                $address_type = 'commercial';
                tep_session_register('address_type');
              }elseif(($av_response->AddressResults->ProposedAddressDetails->ResidentialStatus == 'INSUFFICIENT_DATA') ||
                      ($av_response->AddressResults->ProposedAddressDetails->ResidentialStatus == 'UNAVAILABLE') ||
                      ($av_response->AddressResults->ProposedAddressDetails->ResidentialStatus == 'NOT_APPLICABLE_TO_COUNTRY'))    {
                    $address_type = 'residential';
                    tep_session_register('address_type');
              }
            }
          } catch (Exception $e) {
          }

        if ($address_validation == false) {
          if ($order->delivery['company'] != '') {
            $residential_address = false;
          } else {
            $residential_address = true;
          }
        }
            if(isset($customer_id) && ($customer_id > 0)) tep_db_query("update " . TABLE_ADDRESS_BOOK . " set entry_delivery_type = '" . tep_db_prepare_input($address_type) . "' where address_book_id = '" . (int)$order->delivery['delivery_id'] . "'");
    }else{
        if ($address_type == 'commercial') {
            $residential_address = false;
          } else {
            $residential_address = true;
          }
    }

This new code work is based off of USPS tables that fedex looks up the address to find out the address type.

 

If no type is returned and the customer has a company name then defaults to commercial, else all others are residential.

 

hope this helps.

 

cheers

Peter


Peter McGrath

-----------------------------

See my Profile (click here) for more information and to contact me for professional osCommerce support that includes SEO development, custom development and security implementation

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×