Saturday, August 29, 2009

Paypal integration issues - Message 4003 and merchant is not a business or premier PayPal account errors

A quick post for anyone struggling with Encrypted Website Payments (EWP) with Paypal and are getting the errors:

"Message 4003", or
"The merchant is not a business or premier PayPal account. This feature is only enabled for a business or a premier PayPal account holder."

You'll get these errors if the variables you're encoding aren't formatted properly. To expand on the paypal doc's:

"Each variable must be on its own line in the format: 'key=value'"

What they fail to mention is that the line delimiters must be "\n" rather than "\r\n". If you use the native "Environment.Newline" it'll do the latter, and add the return character screwing up your pk12 string that you set as your "encrypted" field.

I wasted a couple of hours on this stupid error.

Wednesday, August 19, 2009

Site optimization - Leveraging Content Delivery Networks (CDN) for blazingly quick sites

Ok firstly there's a lot of different content delivery network providers around. I'm going to be using Amazon CloudFront in this post because I'm endeared to their pricing structure ($0.17 per GB) and REST based API.

The problem: You have a web site hosted in the US. Whenever you connect to the site, all the resources are downloaded from that single host. If you pay for cheap hosting, chances are your download speeds are deplorable. Add to that the fact that if you hit the site from outside the US, you get worse performance due to latency. How do you make your site faster without spending big?

We all know that slow sites drives visitors away. If they click a link to your site, you better try your damned best to get your landing page up on their screen as fast as possible - before they hit 'back' and go to your competitor's site.

Content Delivery Networks (CDN) are set up exactly for this purpose - to get your content onto your customer's computer as quickly as possible.

CDN's basically replicate your content onto "edge locations" that are servers that sit on crazy fast backbone networks, and are located in different continents around the world. When a customer requests some content, their request is routed to the geographically closest edge location, and the response is sent back. ridiculously fast.

CloudFront is Amazon's implementation of this. To use it you'll also need to register for an S3 account. There are a few considerations that you need to be aware of before going down this path, so it's worthwhile reading on to get an overview.

A typically implementation will see that you serve images, video, audio, flash, whatever content from the CDN. Your actual HTML page, however, should be served from your normal web host (not mandatory, but easier this way). Whenever you reference a resource, eg an IMG such as: 

<img src="/Images/Home.png" />

You just need to direct this to your CDN via:

<img src="http://yourdomain.cloudfront.net/Images/Home.png" />

So that when the customer's browser request the image, the route to the closest edge location will be determined, and will fulfil the request.

Pretty easy so far.

To get your image into the edge server, you need to pop it in the origin server, ie: your S3 bucket. Once you've uploaded it, you create a new distribution to CloudFront so that Amazon knows the content you've uploaded is to be placed on their CDN.

To do this, it's best to check out the API

Price is always a consideration. You get charged for storage, and charged for transfers (not just from your edge location to the customer, but also from your S3 bucket to the edge location).

By default, content will expire after being at an edge location for 24 hours. It is only pushed to these locations when that location receives a request to serve some content. At that point it quickly goes to copy the resource from the bucket, and then serves this to the request.

Interestingly if you have big files (eg: video), browsers tend to chunk the request and download it in parts. If the browser requests from byte 0, then the entire resource is copied to the edge location. If the browser requests some other arbitrary byte, then only that chunk of the file is copied.

It's not all smooth sailing. If you have secure content that you want to distribute, eg: user pays downloads, then you're out of luck. Cloudfront only serves content, and provides no authentication, authorisation or restrictions of content. Furthermore it will strip all query parameters, so even if you're trying to be clever, you'll get tripped up here.

In summary, if you're looking to increase the scalability and speed of your site, check out a CDN. Taking advantage of a globally distributed content network will let your users - wherever they're geographically located - to hit your site, drive more throughput, and make more profits.

Sunday, August 9, 2009

Virtual Begging - Paypal's "Make a Donation"

Paypal's payment system is fantastic. It provides a simple way to provide a large number of payment options to your customers with a very low cost per transaction - far below what your bank and the majority of other merchants can (or rather, do) provide.

One of the things they provide is a "Donation" functionality that you can stick on your page to allow visitors to send funds to you voluntarily. 

You've probably seen this before, and probably will see more & more as the appeal of getting cash for doing nothing reaches more site owners. But does having such functionality profit the owner? Or does it hurt the site more and drive people away?

Firstly, it's almost impossible to get people to give you there cash for free. Even developers who write free software and offer a donation button will see terrible returns compared to selling there software (hence the increased popularity in freemium based pricing). Having a site, which already has advertising on it, and then a suggestion to send money to the author at most times is just insulting and akin to begging.

Thanks to the huge number of sites on the web, there is no shortage of variety. Visitors will stick around for half a minute and then click through to the next half minute distraction. Unless their lives are significantly enriched by that half minute on your site, you're not going to see a penny. 

Unless you can increase the perceived value of your site, you should not put a donation button on it. Doing so is a slap in the face to say that you're too lazy to spend the effort creating something that is of value that should be financially rewarded. If you want to get cash, make something worthwhile and sell it. 

Sunday, August 2, 2009

Implementing navier stokes - the fun of fluid mechanics

A few weeks ago I got a new HP - tx2, basically one of the first 3 lappies that support NTrig's multi-touch functionality. 

The plan being to explore more intuitive ways to interact with large sets of data that's a lot more natural and organic than throwing figures into grids on the screen. This is my first tablet, and so far I've been pretty impressed - especially after cleaning it and putting on the easiest install of Windows (win 7) I've ever done (seriously, it found all the right drivers from the start, and have been stable ever since).

After a bit of messing around with nesher's excellent Multitouch Vista library, I started to wonder how to get a bit lower down in the code and implement a visualization, such as those DSP plugins for winamp/wmplayer. 

I wanted to go for something that was very responsive to the user, and physically accurate to the environment as I could. Starting where a lot of people start out - I dusted off the old math books and found that Navier Stokes could help out. The implementation has been written many times by many people, but this was my first time so things were a bit shaky.

The basic formula goes something like:



which in plain English reads something along the lines of "the flow velocity and density of some fluid over time is affected by external pressures, viscosity/diffusion and additional density sources"

Basically if you take a blob of red dye inside a square container of water to be 'density'; it can get have it's shape changed by whatever's pushing it around (ie water). Invariably it will disperse out as it gets pushed around, hence the density will slowly disintegrate.

Without thinking too much, I launched VS2008 and started a new winforms 3.5 project, the idea being I could just write the output to a new image and throw it in a picbox. At this point I wasn't as concerned with a good frame rate as I was with just getting it working.  This would come back to bite me.

After a couple of nights work, I finally had something that worked. More than that, it would launch, jump into full screen, then be manipulated with my finger on the touch screen. The down side was that I was getting about 3fps. 

It was this time that I decided to translate it over to C++, and run it with OpenGL under Ubuntu.  A few hours later the code was translated, and not only did it run much faster, i was able to squeeze out a better resolution. result:


So I achieved what I set out to do, at least as a good first step.

The next iteration is to then combine this with OpenCV and wire it to the projector. I'm aiming to add collision detection of the density & velocity so that it naturally wraps around whatever gets in its way. 

Once that's complete, it should be a relatively simple process of using an average background diff method to pull foreground objects out of a scene and use their silhouette as generators to modify the fluid scene.


Lessons learned from this? Winforms is definitely not the right technology for this sort of processing. That was sort of a given, but there's nothing like jumping in and thinking later. Despite jumping out of managed code, I still couldn't push it very hard.

I started down the path of DirectX, and then was considering going to XNA; but I really wanted to write it at a lower level where I could have much better control over how things were being calculated and displayed. OpenGL/C++ provided a good route, but I've heard a lot of good things about the performance of XNA - so the code might be written for a 3rd time just to squeeze a bit more juice out of the app.