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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |