The USPS now allows small packages up to 16oz to ship First-Class (previously it was 13oz). Evidently you can only get access to this rate through the USPS' API under the service name, "First-Class™ Package Service" which is not supported by Ubercart 7.x-3.10 at this time. "First-Class Mail® Parcel" (which is supported by Ubercart) still has the 13oz weight limit. I would like to get access to the new 16oz limit to offer more competitive shipping prices.

You can see this with the attachments, 8-2ozQuote.png and 13-2ozQuote.png, which show First-Class shipping option responses from the USPS for an 8.2oz shipment and 13.2oz shipment respectively. For the 8.2oz quote Ubercart only reports the non-commercial "FirstClass Parcel" option (commercial rate is selected in configuration and is reported for other shipping options like priority mail), and ignores the "FirstClass Package Service. For the 13.2oz quote the USPS only has the "First-Class Package Service" option and Ubercart ignores it, not providing any First-Class shipping options to the customer.

The issue seems to be with uc_usps.module : uc_usps_quote() around line 373. Here we are iterating though the postage options reported by USPS and we only have an option for "First-Class Mail Parcel":

if ($classid === '0') {
  if ((string)$postage->MailService == "First-Class Mail® Parcel") {
    $classid = 'zeroParcel';
  }
  elseif ((string)$postage->MailService == "First-Class Mail® Letter") {
    $classid = 'zeroFlat';
  }
  else {
    $classid = 'zero';
  }
}

For an experiment, I replaced "First-Class Mail® Parcel" in the above code with "First-Class™ Package Service" expecting to see the option appear in the shopping cart. It did not. I verified that USPS was reporting the option to Ubercart, so am a bit confused why Ubercart didn't pick it up. As best as I can tell the string comparison fails for some reason.

Three questions:

(1) Why doesn't Ubercart pick up my "hack" noted above?

(2) What is a "quick-fix" I could try on my copy of Ubercart to fix it?

(3) What is a long-term fix for this new shipping option?

Thank you for your time and help.

Jeff

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

labtech created an issue. See original summary.

TR’s picture

The problem we've always had with USPS is that they change their API without changing the API version number. AND if they do change the version number, they always process API calls against the current version and NOT against the version specified in the API request.

So we can write code that is valid for a major.minor version of the API, and we can send the major.minor version as part of the request to USPS, but if USPS has changed something in their API then the code will not work properly anymore.

(Note: FedEx and UPS do this correctly! If they change the API, they give it a new version number. And if you send an older version number as part of your request, they will process the request using the older version number. This way working code will remain working.)

So what needs to be done is someone needs to review the most recent USPS API documentation line-by-line (they also don't have comprehensive change notices - a complete review is really the only way to catch changes) then update the uc_usps module to account for any changes. This is not hard, it just takes time.

As for why your hack failed, my first guess is that USPS is sending back a trademark superscript that is HTML encoded and we're not changing that to Unicode so the comparison fails. Why would we not change it to Unicode? Because the previous version of the API improperly sent DOUBLE encoded HTML, so that's what we've been expecting (i.e., instead of <sup>&trade;</sup> it was sending &lt;sup&gt;&amp;trade;&lt;/sup&gt;). Actually, it should not be sending any form of HTML at all, it should be sending pure Unicode - they're making an assumption that the service name will be directly displayed in a browser and used in no other way. So you might need to adjust the portion of uc_usps.module here:

    // Map double-encoded HTML markup in service names to Unicode characters.
    $service_markup = array(
      '&lt;sup&gt;&amp;reg;&lt;/sup&gt;'   => '®',
      '&lt;sup&gt;&amp;trade;&lt;/sup&gt;' => '™',
      '&lt;sup&gt;&#174;&lt;/sup&gt;'      => '®',
      '&lt;sup&gt;&#8482;&lt;/sup&gt;'     => '™',
      '**'                                 => '',
    );
    // Use this map to fix USPS service names.

And/or _uc_usps_services() also needs to be modified.

TR’s picture

Version: 7.x-3.10 » 7.x-3.x-dev

Marked #2922411: USPS First-Class option missing as a duplicate, as it contains a related problem which will also be fixed by an update to uc_usps as I described in #2.

retiredpro’s picture

My original post from #2922411: USPS First-Class option missing

I have enabled USPS Domestic - USPS Parcel Services:

U.S.P.S First-Class Mail Parcel
U.S.P.S Priority Mail
U.S.P.S Express Mail
But during checkout I only see Priority Mail and Express Mail. No First-Class Mail Parcel is shown. My package is only 4oz.

Attached is the debug log (I changed out the address for this post).

According to this Magento Blog post, 'On September 1st, 2017 USPS changed the “First-Class Mail Parcel” service to “First-Class Package Service – Retail”'

https://www.orangecollarmedia.com/usps-api-changes-first-class-mail-parcel/

The issue is perhaps related to the USPS API change?

Solution by EducoWebDesign

This issue is definitely related to the API change - USPS changed the name of the First-Class Parcel service. I had a client reach out about the missing First-Class option a couple of days ago, and here's the fix that worked for me.

Edit ubercart > shipping > uc_usps > uc_usps.module at Line 373

Replace
if ((string)$postage->MailService == "First-Class Mail® Parcel") {
with
if ((string)$postage->MailService == "First-Class Package Service - Retail™") {

Hope that helps!
Chris

retiredpro’s picture

Uploading a patch based on @EducoWebDesign's solution

retiredpro’s picture

@TR, I made an adjustment to my putty settings so that the remote character set is UTF-8. The characters render fine and I created the patch. But clicking on the patch in Chrome still shows funny characters. Is this a Chrome issue?

TR’s picture

If I download your patch and look at it on my computer it looks fine, so I think the patch is actually fine.

But it looks wrong if you click on it in the browser. It's not just Chrome, it's Firefox as well - possibly all browsers. I suspect this is a drupal.org problem - patches seem to be served up with text/plain content type and windows-1252 encoding. The encoding seems to be the problem ...

I just filed a bug report for drupal.org, let's see what they have to say. https://www.drupal.org/project/issues/drupalorg/2922638

retiredpro’s picture

Sounds good. Thank you.

joelstein’s picture

Status: Active » Reviewed & tested by the community

We encountered the same issue, and this patch resolved it for us. Thank you!

TR’s picture

You reviewed the current API documentation and there were no other changes?

joelstein’s picture

I'm sorry, no.

TR’s picture

Status: Reviewed & tested by the community » Active
vijaymaadhes’s picture

this patch is not working for me. Thanks

JWinTX’s picture

The #5 patch worked for me after I added a space between the ")" and "$" in both lines containing "((string)$postage".

joelstein’s picture

Status: Active » Needs work
FileSize
751 bytes

Here's an updated patch which applies cleanly with 7.x-3.11.

laryn’s picture

This patch works for me as well. I'd recommend merging/releasing it and opening a separate issue for the 'line by line' review you refer to, as this is a pretty major fail that is fixed by a simple patch. (But that's my opinion, I realize!)

TR’s picture

Or, alternatively, you could spend the ~1 hour it would require to do a proper and complete fix for the new API changes and contribute a patch here ...

laryn’s picture

Fair enough!

For what it's worth, before posting the above I did get as far as looking into the USPS Release Notes section of their site to see how lengthy the 'line by line' process would be. I see 10 PDFs of release notes since May of 2017 (when this issue was created). I opened the first few of them and they were 29 and 28 pages. For someone with my level of experience with USPS API and Ubercart code (ie. not much in either case), I'm guessing it would take well beyond 1 hour to go through all of these line by line and see if there were any other potential changes.

That said, I didn't mean to put any pressure or expectation on you with my comment in #16. I understand that you are busy and maintaining this module out of the goodness of your heart. If you prefer not to release this patch until sometime later, it's totally your call. I appreciate all you've done and do – thank you.

glynster’s picture

Anyone else finding this patch no longer works? Did they update the name yet again? In my research I am finding:

First-Class Package Service-Retail®

hanoii’s picture

#15 still works for me.

I tried giving this some thoughts. I am not sure what @TR meant with line by line reviewing of their API. I did try to see if there's any better documentation now but found none.

A list seem to be present in https://docs.rocketship.it/php/1-0/usps-class-ids.html but not sure how accurate it is.

I also looked at the code and see if I was able to come up with a bigger refactor alternative but I can see this being hard.

I brainstormed about:

- fetching a dummy request before showing the options, however I'd assume this is dependent on weight. Is there any other parameter that affects services returned by USPS. Maybe getting the request for different regular "weights".
- Using the strings as Ids rather than CLASS ID or whatever, we can have a textarea where you actually write all of the services yo want to make available. If there's a change or a new one you can go and add it there. Some debug message (if enabled) can accompany a list of all mail services returned.

If any of the above seems like a good path, I might try exploring it a bit further.