Orange is my favorite color

I’ve been working on building a RESTful web service with ColdFusion lately and there isn’t much information out there. Lots of people talk about consuming them but few people are talking about how to build them. I’m not yet ready to share what I’ve learned (especially the insight from Kevin J. Miller) as I’m in process but I did want to toss out a neat application by Brian Carr on RIAForge that Kevin pointed me at: PowerNap.

PowerNap is a framework for building RESTful web services. I read through the docs and it appears to do nearly everything the 0.9 version of my API does. The only thing I’m not sure about yet is content-type negotiation which I find preferable to specifying the return type in the URL. Regardless, this looks like an excellent way to toss up a REST API and it takes advantage of my other favorite tool, Coldspring.

Well worth a read… in the mean time I’ll get to chronicling my development process.

We’ve been hard at work the last few weeks on making real, meaningful ground on CFPAYMENT, the open source ColdFusion payment processing library that generalizes many different gateways into a single, pluggable API. In the run-up to 1.0, I wanted to share some snippets to get you excited about using cfpayment for your next (or current!) e-commerce project:

<cfset config = {path = "braintree.braintree", username = "demo", password = "demo" } />
<cfset cfpayment = createObject("component", "cfpayment.api.core").init(config) />
<cfset gateway = cfpayment.getGateway() />
// create a money object to hold the amount in cents
<cfset money = cfpayment.createMoney(5000, "USD") />
// create an account to charge
<cfset account = cfpayment.createCreditCard() />
<cfset account.setAccount(4111111111111111) />
<cfset account.setMonth(10) />
<cfset account.setYear(10) />
<cfset account.setFirstName("John") />
<cfset account.setLastName("Doe") />
// authorize the card
<cfset response = gw.authorize(money = money, account = creditcard) />
// flag the authorization for settlement into your bank account
<cfset response = gw.capture(money = money, transactionid = response.getTransactionID()) />
// changed my mind, let's void it
<cfset response = gw.void(transactionid = response.getTransactionID()) />

Heard of PCI DSS? You can mitigate or avoid it altogether by using a remote storage system like Braintree’s Secure Vault:

// create a token
<cfset token = cfpayment.createToken(createUUID()) />
<cfset options = { store = token.getID() } />
// authorize and put the data into the vault
<cfset response = gw.authorize(money = money, account = account, options = options) />
// come back later and use that token to charge the card
<cfset response = gw.purchase(money = money, account = token) />
// changed my mind, delete it from the vault
<cfset response = gw.unstore(account = token) />

Don’t use Braintree? That’s OK, as of today, you could just as easily initialize the Core API to use iTransact or Skipjack without any change in your consumer code.

We’re working to add more payment gateways. The best source of these will come from people who have written integrations already or need to write one and want to benefit from the infrastructure of a community-supported and planned API that gives them flexibility in choosing their gateways and merchant accounts over the long road.

I need to run a customer satisfaction survey for 2008 so I spent some time reviewing the available online survey options and comparing which would be most suitable for my needs. I am not a survey junkie so it doesn’t make sense for me to buy a premium service or subscribe on an ongoing basis. I have very occasional needs and my requirements are pretty simple. Hopefully this cheat sheet saves somebody else some time!

Online Survey Services

I compared six online services and three alternatives that might work for people too. I’m not concerned with fancy features so I stuck to the basics: how many questions can I ask, how many responses can I collect and can I export it to Excel/CSV for further analysis?

Note: this compares the free editions of each service!

Service # Surveys ?s/Survey Responses CSV?
SurveyMonkey n/a 10 100 N
SurveyGizmo n/a n/a 250/mo Y
PollDaddy n/a 10 100/mo N
QuestionPro 2 10 n/a N
eSurveys 1 n/a 25 N
Zoomerang n/a 30 100 N
Alternatives
Wordpress Filled-In Plugin1 n/a n/a n/a Y
Google Docs2 n/a n/a n/a Y
Lime Survey3 n/a n/a n/a Y

1 - requires a Wordpress installation and the ability to add a plugin. You have to create your form but Filled In takes care of validating, processing and storing it as CSV or XML data. It can also email the data as it’s received.
2 - requires a Google Docs account for the survey creator but not the survey taker. Responses are automatically added to your Google spreadsheet.
3 - requires PHP/database but is a locally installed application with full control and extensive features. There is also a hosted version of the service.

My Selection

I care more about having enough questions and exporting the data than having hundreds of responses so I have created an account with SurveyGizmo. They also allow you to embed your survey into a remote website using an API key plus they provide a Wordpress plugin. So far it seems OK but although building my survey form looks flexible, I think it’s going to take me some time.

I also already use the excellent Filled-In plugin on another site so I am considering using SurveyGizmo to generate my HTML form and then paste it into my Wordpress install and configure Filled In to collect it.

The end of the year is coming - collect your feedback so you can make good decisions for 2009!

Doing a little Javascript hacking today and have a few parsers to share for the TableSorter jQuery plugin. I’ve written some in the past but more is always merrier.

Sorting alphanumeric data in numeric order

I have member numbers which can look like ‘A23423423′ or ‘2000-342′ or ‘220342BMW’ but I want to sort them in numeric order since the characters often refer to associate members or some sub-qualifier. It takes a pretty simple parser with a regular expression to accomplish it:

$.tablesorter.addParser({
id: 'memNumber',
is: function(s) {
return false;
},
format: function(s) {
return s.replace(/[^0-9]/g, "");
},
sorter: 'numeric'
});

Adspeed Parsers & Widgets

I also came across a recent post over at Adspeed.org that includes several parsers and widgets:

  1. Parser for sorting values like “$1,300.50″
  2. Parser for sorting values like “2 months ago”,”3 years ago” (actual timestamp hide in the comment)
  3. Parser for sorting values like “SMALLER”,”SMALL” (actual text value hide in comment)
  4. Widget to highlight a row when mouse hovers it
  5. Widget to highlight a header when mouse hovers it
  6. Widget to save/memorize sort order via AJAX

I particularly like the idea of embedding the sortable value in a comment and using that to sort. It gives you total freedom in how you display versus sort (and could work just as well as my custom member number parser above).

You can write your own parsers and widgets easily to extend TableSorter for your own requirements.