In my reply to this thread The sad state of Perl + UPS Rate Requests, I mentioned that it would make sense to have a common Perl API for package shipping services (Fedex, UPS etc), along the lines of the DBI/DBD modules. Since it seems that there may be some interest, I dug out my notes for such a project that never really got started.

Although the various shipping carriers have online APIs for their services, each uses their own proprietary system. While access to documentation for these API's often have various degrees of restrictions, I have been able to gain access to some of them. In studying documents from UPS, Fedex, DHL and USPS, I found is that there is much in common between them:

It seems very feasible that we can have a common module with a standard API that does the heavy lifting, and a separate backend module for each shipping carrier. The carrier modules would probably need a minimum of actual coded logic, and would mostly consist of XML templates, and tables to translate field names and request/response data between the Perl API and the carrier's API.

Here is my very basic concept of what this might look like. ShipAPI is the common module and ShipAPI::carrier (substitute Fedex, UPS etc for carrier) is for whichever shipping carrier you use.

User Shipment Service Initialize Info Request Module | A | | . . |. |. . . . |. . . . . . . . .|. . . . . . . . +. . | | | | ShipAPI.pm +. . V | | V +. . | +. . initialize | _ shipper +. . object | | config info +. . ______| | +. . | . . . .|. . . . . . . . . . . +. . | . | . V . .V. . . . . . . . . . . +. . . . ShipAPI::carrier.pm +. . parse . . +. . request <------------> Available +. . . . Services +. . | . . +. . | . . +. . V . . +. . . . +. . translate . . field +. . & validate <----------> translation +. . fields . . tables +. . . . +. . | . . +. . | . . +. . V . . +. . . . +. . fill XML . . +. . template <----------> XML template +. . . . +. . | . . +. . | . . +. . V . . +. . . . +. to carrier . transmit . . URI, Auth +. server <------ HTTPS <----------> & access +. . request . . info +. . . . +. . . . +. from . receive . . +. carrier -------> HTTPS . . +. server . response . . +. . . . +. . | . . +. . | . . +. . V . . +. . . . +. . parse XML . . +. . . . +. . | . . +. . | . . +. . V . . +. . . . +. . translate . . response +. . response <---------> translation +. . data . . tables +. . . . +. . | . . +. . . . . | . . . . . . . . . . . . . . . . . . +. | V Asynchronous User Response (via callback?)

The idea is to make it as trivial as possible to add new carrier modules, or to update a carrier module when their API changes. There are many other candidates for carrier modules (one person mentioned Australia Post) that could be added with a minimal effort. A Perl API that could communicate to any of the carrier services might look something like this:

# definitions: # shipper - sends the shipment # carrier - transports the shipment # recipient - recieves the shipment # configuration info %conf = ( weightUnits => dimensionUnits => currency => shipper => { name => address => ... etc => } carriers => [ { carrier => shipperId => serverUrl => authent => ... etc => },{ carrier => ... etc => } ] ); # configure the module ShipAPI->configure(\%conf); # create a shipping object w/recipient info $pkg = ShipAPI->shipment( carrier => name => company => address => ...etc => ); # validate recipient address $rv = $pkg->validate(); # add package(s) info $rv = $pkg->addPackage( weight => dimensions => [$h, $w, $d] type => ); # get shipping services available(ground, next day etc) $rv = $pkg->availableShipping(); # get transit time $rv = $pkg->transit( service => ); # get add-on services available for this shipment $rv = $pkg->availableAddon() # add add-on services (COD, pickup, etc) $rv = $pkg->addService( type => param => ...etc => ); # get service rates $rv = $pkg->rates( service => ); # add billing info if not billed to shipper $rv = $pkg->billing( account => zipcode => ); # submit for shipment $rv = $pkg->ship( service => ); # cancel shipment $rv = $pkg->cancel(); # cancel shipment $rv = ShipAPI->cancel( carrier => tracknum => ); # track shipment $rv = $pkg->track(); # track shipment $rv = ShipAPI->track( carrier => tracknum => ); # response callbacks: shippingRates trackingResults transitTime addressValidation shipmentAcknowledge

Remember, these are all ideas from some preliminary notes, there is no working code to go with it. This would be a rather ambitious project for me, and I'm not certain my coding skills are up to it without getting over some learning curves. So, I'm looking for feedback: What do you all think of the concept? Would this be a worthwhile & useful project? Any ideas to contribute? Anyone want to tackle this? Or help out?


In reply to RFC: Package Shipping Modules by hangon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.