QuantumView API with AbleCommerce

Recently a client requested a challenging project.  They wanted to fully automate the processing of tracking numbers pulled from the QuantumView API data feeds.

The majority of the client’s shipments are drop-shipped direct from the manufacturer or distributor who charge my client’s UPS account number.   This is a technique known as 3rd-party billing.  This works well because my client can leverage all of their shipping volume with UPS instead of just the in-stock shipments.   And they know what to expect for shipping charges since it’s their account being billed.

However there is a downside to this shipping process.  Normally an integration like ShipStation or WorldShip would post tracking numbers back to AbleCommerce.  However with drop-ship orders, these tracking numbers must all be hand-entered on every shipment.   A major hassle when your order volume is significant.

The client’s workaround was to create two feeds in their QuantumView account.  One feed for in-stock shipments and the other for all 3rd-party (dropship) shipments.  Each day the client would download the feed, load it into Excel for readability purposes and then copy/paste tracking number data.   A huge pain.

The design for this integration needed to meet the following requirements:

  • Download the feed files on a regular basis from the UPS QuantumView API
  • Locate the Origin record types and identify the shipment Id for each one
  • Post the associated tracking number to the shipment Id
  • Set aside any Origin records that could not be automatically processed
  • Provide a UI for manually processing Origin records which could not be automatically processed
  • Log a summary of each interaction with the QuantumView API for debugging purposes

The first step to the project was to dig into the UPS QuantumView API documentation.  The docs clearly show the API supports both a JSON and XML payload.  However I was never able to get the JSON payload to work properly.  The problem came down to arrays/collections.  When a specific element in the API specifications supported multiple items, I would naturally define it as an array i.e. element[].  But when the element had only one entry, UPS would not send the element as an array with a single entry.  UPS would simply send a standard element definition.   This broke my class structure in C# – I couldn’t get JSON.Net to handle a element that could arrive as a single piece or as an array of pieces.

After several frustrating hours I was forced to give up and switch to the XML format of the API.  The documentation from UPS for the XML API was vastly more detailed.  Clearly it seems they added JSON as an afterthought.

I wasn’t looking forward to the prospect of hand-building a class that matched the XML structure of the API response.  Fortunately, I found an awesome trick that involved using a command-line tool from Visual Studio.  Just hand the XML file to the tool and *poof* it generates the necessary class and child classes to consume that XML layout.  Later on I found that feature actually exists right in Visual Studio – just copy the XML to your clipboard and then use Edit/Paste Special/Paste XML as Classes.  SWEET!

Once I had the XML importing into strongly typed classes, progress moved much faster.  I was able to leverage HangFire to automatically poll the UPS API on schedule controlled through an admin settings page.   Now that automation is handled, I moved on to processing the downloads.

Testing the API proved a bit confusing because of one REALLY important detail:  The default API endpoints only deliver what transactions have been received by UPS since the last time you asked UPS for them.  Helpful in a production scenario since you never have to worry if you’ve already received a specific Origin record.  But it makes testing your code a major source of stress.  Your first request comes back with data, and then suddenly you get nothing.  Over and over again, what you thought was working now appears to be broken.  The way around this is to add a date-range criteria (up to 7 days in the past).  When a date range is included in the request, QuantumView will respond with all transactions regardless if they’ve already been delivered or not.

Now that I’m pulling down data, the processing became simple.  The client was already having each manufacturer put the AbleCommerce Shipment Id in one of the UPS reference fields.  UPS manifests support up to five ‘reference’ fields usable by the shipper for any purpose.  Having the Able Shipment Id in each Origin record makes it a snap to determine which Able shipment gets the tracking number.

 

Handler “ChartImageHandler” has a bad module “ManagedPipelineHandler” in its module list

HTTP Error 500.21 – Internal Server Error

Handler "ChartImageHandler" has a bad module "ManagedPipelineHandler" in its module list

 

Moving an AbleCommerce Gold R4 install today created a weird error.   Site was moved from Windows 7 64-bit to staging server running Server 2008 R2.

Able Gold R4 ran fine.  Booted right up, logged in and no issues noted.  Until I clicked the Charts tab.  None of the graphs were rendering.   Just the little bad-image icon in my Google Chrome.

After a lot of digging, I found many posts saying to reinstall ASP.net.   I tried that, didn’t work.

So on a hunch I decided to switch my IIS application pool from ASP.Net 4.0 Classic to ASP.Net 4.0 Integrated.  BAM!  All the charts start rendering exactly right.

Apparently Gold R4 requires 4.0 Integrated.

InfusionSoft API for AbleCommerce all done

I finally finished the InfusionSoft integration with AbleCommerce that I’ve been working on.

The initial steps to push a contact are pretty simple.  But most times, it not enough to just push contact info.  You want to use tags, you want do email marketing, you want to set specific defaults.  But these aren’t set by the basic CreateContact API provided by InfusionSoft.

Thus I wrote my own optIn routine so emails imported with the API aren’t marked as ‘not marketable’.  Now they come in as ‘Unconfirmed’ like they should.  AbleCommerce doesn’t really have a flag for this.

And I wrote a routine to pull down all tags defined in InfusionSoft so they can be assigned to specific trigger actions via a backend configuration page.  This turned out excellent and minimizes future programming changes.  Client just needs to change the dropdown and *poof* new customers are automatically assigned to the designated InfusionSoft tag.

Overall, a fun project.  I like working with API interfaces.  Especially ones that are well documented like the InfusionSoft API.

InfusionSoft API for AbleCommerce

Having a blast putting together a nice integration between InfusionSoft and AbleCommerce. 

So far I can:

  • Push new contacts into InfusionSoft from AbleCommerce user records
  • Look up existing InfusionSoft contacts
  • Identify all InfusionSoft tags
  • Assign existing InfusionSoft contacts to tags
  • Update custom InfusionSoft fields

The API for InfusionSoft is pretty slick.  Implementing it using the necessary 3rd party library wasn’t hard either.  But putting together the necessary classes to drive the integration took a little more effort than I expected.

Looking forward to seeing this fully automated in the post-checkout routine.  It’ll really save the client a ton of time, no more re-entering customers into InfusionSoft.

Authorize.Net Direct Post Method (DPM) and AbleCommerce 7

Ever have a project where you pretty much had to ‘just do it’ to see if you could?  Enter DPM from Authorize.Net.

Direct Post Method is a way to avoid certain PCI compliance requirements for an AbleCommerce 7 online store.  It works by avoiding any interaction between the storefront and the payment details.  If the storefront never sees the payment details, the PCI compliance requirements drop significantly.

Unfortunately the documentation for DPM provided by Authorize.Net is worthless for an ASP.Net Web Forms environment.  It’s written exclusively for Win-Forms apps.    Back to square-one if you’re an AbleCommerce developer like me.

After a TON of digging online, I finally found a working example of using Direct Post Method with ASP.Net and C#.  Apparently I wasn’t the only one noticing the lack of ASP.Net documentation.

Now I can start my project for integrating Authorize.Net DPM into AbleCommerce.

EDIT:  URL added  http://www.tandasoft.com/2011/05/05/using-authorize-net-dpm-direct-post-method-from-asp-net-web-forms/

Quickbooks Web Connector Rewrite Features and Improvements

After 6 weeks of work, I have completed testing on the feature list for the new release of my Quickbooks module.  It’s quite a list of work accomplished:

  • Option to set default Sales Rep when creating new customer in Quickbooks.
  • Option to set default Customer Type when creating new customer in Quickbooks.
  • Option to automatically add order note to Notes/History when order is successfully transferred.
  • Ability to update inventory values from Quickbooks back into AbleCommerce.
  • Full support for sub-categorized lists in Quickbooks such as G/L accounts and Inventory Items.
  • Improved error handling.   Error messages now report what specific part of the transfer caused an error and more importantly, why.
  • Improved logging to AC7 Error Log since it already supports easy export for emailing it to tech support.
  • Improved configuration page Bank Account-to-Payment Method assignment.  Now dropdown lists are used so typos cannot cause a transfer error.
  • Improved configuration page layout so parameters are grouped in a more logical way.
  • Improved documentation.  Clarified key points of transfer.  Added new content for new features and configuration settings.  Added new upgrade instructions.
  • Improved efficiency of accessing configuration parameters during a transfer session.  This dramatically cuts down on database hits during transfers.
  • Improved Bill and Purchase Order routines to handle multiple shipments more accurately.
  • Improved Quickbooks list retrieval.  Quickbooks lists are now stored in the database instead of individual files in the /App_Data/ folder.
  • Eliminated second DLL from installation.  Now the entire module is deployable in a single DLL file.
  • Added support for Sales Orders (only available in Quickbooks Premier or Enterprise)
  • Fixed bug when searching by Order Number range in the SetExported page.

AbleCommerce Quickbooks module rewrite nearly complete

Testing has gone very well.  What a project.  Wound up rewriting like 90% of the entire module.  Added several new features, vastly improved error handling and laid a solid foundation for more enhancements.

Intuit has done a decent job of working out the kinks found in the older versions of their QBWC SDK.

The final improvement will be the support for Sales Orders.  Not entirely sure what I’ll do with the payment side of an order being transferred into a Sales Order, but we’ll cross that bridge once I reach it.  I’m waiting now on a QB Enterprise trial from Intuit so I can test.  Buying a full copy of Enterprise just for testing purposes seems wasteful.

I eliminated support for AbleCommerce 7 versions prior to release 7.0.2.  If you’re not on 7.0.2 or later, you should be.

The manual has already been updated.  As soon as I can test Sales Order transfer, I’ll release the new build to the general public.  Then it’s on to the next project !

Quickbooks for AbleCommerce 7 rewrite in progress

Well I’ve been working hard for over three weeks now doing a complete rewrite of my Quickbooks Connector that transfers AbleCommerce 7 data electronically into Quickbooks using ASP.Net web services.

The first challenge was getting the entire Quickbooks API written into a strongly-typed ASP.Net class library.  I originally wrote some very basic classes that would serialize.  However it was a hack job as I was very new to XML, serialization etc.  Boy was it confusing. 

Plus none of the Quickbooks response messages were de-serialized back into strongly typed data classes.  I was actually doing a manual XML search on the response text to find any data needed from the responses.  Ugly doesn’t even begin to describe the code.  I never want to see another XML node search again.

Having such clumsy access to the response and query data meant the code was brutal to debug when something didn’t work right.

So I sat down and bit the bullet.  I built 26 strongly-typed objects that all correctly serialize and de-serialize the Quickbooks SDK requests and responses.  These are written exactly to the Intuit SDK specifications.  Testing serialization and de-serialization created some long nights but it was well worth it.

Now any response from the QB web connector can be quickly de-serialized into usable strongly-typed classes.  Responses are even typed correctly so dollar amounts are (double) and logical values are (bool).  Wow does this make things easier to program.

So now the sky’s the limit.  I’ve already implemented full support for sub-grouped GL accounts and sub-grouped inventory items.  This is becoming increasingly more popular with businesses using Quickbooks.

I’ve also vastly improved error reporting.  Troubleshooting has always been a nightmare with the QB module.  No longer though, I’ve got a solid handle on it now that I have strongly-typed responses.

Next I’m going fix another common problem: Inventory.  Many companies use Quickbooks inventory to track their stock levels.  Getting these values back into AbleCommerce is a manual process.  I am going to make this new version of the Quickbooks Web Connector for AbleCommerce 7 synchronize inventory stock levels from QuickBooks into AbleCommerce.

I’m also going to implement another inventory problem, selling in bulk.  Often an AC7 site will sell a case of something but inventory it indivdually in QuickBooks.  That poses a problem with the transfer because the quantity sold will be 1 yet the case contained 250 units.

The new version of the module will allow a "multiplier" value to be set to each product in AbleCommerce 7 so the Quantity 1 sold becomes Quantity 250 when it hits QuickBooks.

That’s all for now, more to follow.  As always, check out my http://www.Solunar.com site for all your solunar times and solunar table needs plus camping, hunting, marine equipment and yes, even boat anchors.

AbleCommerce 7 Web Service progress report July 17 2010

Well it’s Saturday.  First it was Monday.  Then suddenly Friday afternoon was here and I just didn’t get much done that I wanted.  Several phone calls got in the way as well as some programming research.  Now I’m spending a portion of my weekend getting some much needed bookkeeping work done. 

This should pave the way to put a big dent in the web service module next week.  I came up with a few new web service methods I’d like to add related to inventory items.  It adds more time to the module but I think it’s a solid benefit and worth the delay.

I’d love to complain but business is great and the increased workload feels good.  It feels like a solid flow of work-in and work-out.  Having too much of one or the other just doesn’t set well with me 🙂

AC7 Web Service code is done

Finished the last of the routines I want to add to the Web Service.  Everything came out nicely.

Now for documentation, packaging, install testing and online catalog setup.