Showing posts with label API. Show all posts
Showing posts with label API. Show all posts

Tuesday, March 19, 2013

Wiring Vend POS with CouchDB

Motivation:

  • Vend is a pretty awesome point-of-sale (POS) that resides in the cloud and has an even awesome~er developer API.
  • You can easily create and query views in CouchDB (common hosts: Cloudant and IrisCouch).

Steps:

  1. Get all the products from your Vend store and upload them to CouchDB.
    • Some standalone code be written to pull all the products and upload them. So many ways to do this, depending on what has the best utilities to cobble together something in a hurry: curl or Java or javascript (run via Node.JS) etc.
      • I'm partial to Node.JS because all of Vend's data is in JSON-format and there are some excellent libraries like Cradle which make it simpler to talk with CouchDB.
    • For the upload to CouchDB, it should be possible to leverage the bulk document API and finish it off in one shot.
  2. Going forward, keep everything up to date in real-time by utilizing Vend's webhooks to call into CouchDB's update handlers.
    • Create a design document in CouchDB with update handlers that can parse the payload delivered by a Vend webhook like a product update.
      • When writing an update handler for receiving a product update, I mimicked the Stripe Kanso project.
        • I didn't really write the upload script yet. I simply tried to point Vend's product webhook at the URL for my update handler and I was able to get a document populated in CouchDB.

        • For an actual product update (not just a new one), I haven't quite figured out the code, it fails right now. Just need to spend more time reading up on update handlers, I suppose.
          • Because the Vend API sends the update via a payload that is form urlencoded, I was left wondering where to look for the data and how to grab it inside CouchDB's update handler .. but those questions were easily tackled when I found documentation on handling form-style-submission of data with CouchDB.
          • I did send an email to the CouchDB mailing-list to ask for some advice on actual updates:
            1) I have a 3rd-party-webhook API calling into my update handler and there's nothing I can do to make it pass the document ID in the URL.
            2) That means the CouchDB server cannot provide the update function with the most recent version of that document.
            3) But the request does provide a payload from which I can pull out the document ID ... but by this time I'm inside the update handler function.
            4) So my question is: If CouchDB did not provide a doc, is there still a way for me to:
            a) either, fetch the latest version of the doc myself?
            b) or, override the existing document with another document formed with my request payload ... without running into a revision conflict?

            I know that I can probably route the request through a proxy that parses the payload, sets the document ID onto the request URL and sends it own its way ... but I'd rather leave that as a last resort.

            Thoughts?
          • One more challenge to keep in mind is authentication. If anyone figures out the URL endpoint for the CouchDB and the respective update handler, they could make false additions and updates.
            • It would be worth looking into any username/password BASIC authn provided by CouchDB to secure the update handler endpoint.
            • A quick fix would be to provide a unique token (?token=ABCDEF123) as part of the endpoint URL you specify for the webhook (product.update: https://couchdb.com/myDB/_design/doc/_update/productHandler?token=ABCDEF123) and since the query params are also encrypted in a request, your token would travel over a secure channel and then be validated on the CouchDB side to see if it matches what you expected.

Saturday, March 24, 2012

AuthNet iOS Integration Part 2

There are quite a few gaps in the sample code provided by AuthNet, we will discuss the logs indicating the problem and what chunk of code needs to be added/removed to get to a complete sample that works. This blog entry assumes that you've cleared the challenges of adding AuthNet binaries to your Xcode project. If not then have a peek at AuthNet iOS Integration Part 1 before continuing.
  1. Create a header & an implementation class containing the sample code
  2. If you happen to be using PayPal as well as AuthNet in your code then you may run into some syntactical problems. To resolve any such issues, please have a look at this post on stackoverflow.
  3. When substituting values in the code, if you provide the "API Login ID" and "Transaction Key" as the name / password values in your call to AuthNet then you will run into the following error as seen in the logs:
  4. This fails as password and transactionKey are distinctly different variables in the header files.
  5. So make sure to substitute the sample code with the username and password used with https://developer.authorize.net/ or https://test.authorize.net/
  6. If you run the code at this point and end up calling loginToGateway, you will run into the following error logs:
  7. This is not the same as being at the point where you simply need to login to the sandbox (https://test.authorize.net/) and enable the new device. No, this is very different and you need to get past this to get to the next point. So you need to add some additional code which is talked about on the forums as well:
  8. Now you should be at a point where running the code results in the following error logs:
  9. This is more like it! So head over to https://test.authorize.net/ and enable your new device. Here are some screenshots: screenshot_1 and screenshot_2
  10. Sadly we aren't done yet, we see a message about the mobile device being ready for use but we also notice that the sessionToken has come back as null and therefore the next call's response displays an error ... claiming that the request content was incomplete:
  11. Even I don't have a solution past this point, feel free to follow this forum thread for any progress on the matter.

AuthNet iOS Integration Part 1

  1. You can start with the official instructions to get an account with Authorize.Net and download their iOS SDK. Afterwards the instructions are bit out of date, so you can follow along below.
  2. After you download and unzip the SDK, you can move the files around to have them structured in this manner:
  3. The structure above has the following pros:
    • Clarity around which version has been downloaded and in use at any point of time: anet_ios_sdk-X.X.X
    • If you work long enough to have multiple versions, then having them in your repository (assumption - GIT repo) helps figure out any migration issues
      • $(SRCROOT)/anet_ios_sdk-1.0.0/ANMobilePaymentLib/
      • $(SRCROOT)/anet_ios_sdk-1.0.1/ANMobilePaymentLib/
      • $(SRCROOT)/anet_ios_sdk-1.0.2/ANMobilePaymentLib/
      • ...
      • $(SRCROOT)/anet_ios_sdk-X.X.X/ANMobilePaymentLib/
  4. Goto MyProject > Targets > Build Settings in Xcode and set:
    1. Header Search Paths
      1. "${SDK_DIR}"/usr/include/libxml2
        • Mark the Recursive checkbox as checked
      2. "$(SRCROOT)/anet_ios_sdk-1.0.0/ANMobilePaymentLib"
    2. Library Search Paths
      1. "$(SRCROOT)/anet_ios_sdk-1.0.0/ANMobilePaymentLib"
    3. Other Linker Flags
      1. -lxml2
  5. Drag & Drop the ANMobilePaymentLib.xcodeproj file from a Finder window into Xcode under MyProject.
    • If you don't follow this step then you will face compilation issues like:
  6. Goto MyProject > Targets > Build Phases in Xcode and set:
    1. Link Binary With Libraries
      1. libANMobilePaymentLib.a
  7. For a discussion on the fixes to the sample code, head over to AuthNet iOS Integration Part 2