

How I Reimplemented My Shopping Cart To Sell More Software, w/ Code - patio11
http://www.bingocardcreator.com/articles/developing-shopping-cart.htm

======
patio11
Hiya guys. I recently redid the shopping cart for my business. Then I spent a
few hours writing it up for folks, with the hope somebody can use something.

Article includes:

\+ Results of my A/B tests with previous ways of presenting software for sales
to my customers.

\+ How I use lightboxes to make a good deal of money

\+ An AJAX cart I have used to good effect

\+ How I went about designing and reimplementing a cart, in JS, to give the
feel of the AJAXy one but improve its speed and UI

\+ Code for everything, which I put in the public domain. Go nuts.

~~~
apsurd
>So your shopping cart needs to be willing to continue the conversation with
your customers.

Great advice, I like your insight into how users interact with shopping carts.
I'll be taking this with me on my project!

FYI: the link to e-junkie at the end of the page is broken. It points to:
<http://www.e-junkie/>

------
lonestar
Maybe I've missed something, but it seems like you could completely eliminate
the security flaw of letting your user's decide how much to pay for your
software very easily. Just have the server send the price with an HMAC, check
the HMAC on return, and voila.

~~~
dmolnar
This is a neat idea, but there is at least one subtlety: you need to make sure
that it is not possible to cut-and-paste HMAC'd prices from one web page into
another. Otherwise the user could ask for a page for an item with a price of
$1, receive an HMAC on "$1", and paste that into a page for a different item.

Two possible ways to do this:

1) Use a different HMAC key for each page you generate. 2) HMAC the pair
(price,nonce) where nonce never repeats from one page to another. The server
has to keep the nonce, as well, i.e. is not obtained from the web page.

~~~
rcoder
A simple one-way hash will provide sufficient security for most cases.
Assuming you're representing items for sale in a Javascript array, you might
send data like this to the browser:

    
    
      var forSale = {
        "book": {"price": 19.95, "description": "a book", "checksum": "c6da835c1fd2ee98d68eee3912dd199e41c82a32"}
      }
    

The value for 'checksum' is just a SHA1 hex digest of the ('book', '19.95',
'secret'), joined by tab characters. It can be included as a hidden form field
or invisible element within your page; it doesn't matter so long as you can
capture it and POST is along with the item + price.

In your order-processing logic, just check that the hash verifies with your
secret key ('secret' in the above), and you know with a reasonable degree of
certainty that the original page was one generated by your server.

~~~
patio11
That would work, but I don't do order fulfillment. e-junkie does. They get to
keep the IPN and Google payment notification interfaces, an email server to
send out registration keys, bunches o' reporting code, and integration to the
company that stamps CDs for me.

The cart posts directly to them, so hypothetically assuming I generated a
secret and passed it over, they'd process the order anyhow and then tell me
"By the way, your website passed this secret with the order -- do whatever
with it", after which point a) the customer would have a registration key and
b) if they ordered a CD, it would be scheduled to ship already.

Which is a long way of saying "There are ways to make this setup more secure
but they'd involve me having to rewrite large portions of my business
processes." Like I mentioned: it would cost me a lot of time at a very minor
increase in security.

Probably illusory, actually. No amount of securing my cart will protect me
from this attack: buy the software, write me an email saying "You offer an
unconditional guarantee. I'd like a refund." And there is absolutely nothing
that anyone could say or do which would make me stop offering that
unconditional guarantee, because it is practically a license to print money.
(To anyone who produces a low-marginal-cost product or service: if you do not
have a guarantee, start A/B testing one. Its the closest thing in life to free
money.)

~~~
Tangurena
I remember reading one of the "hacking exposed" books (the exact one I can't
remember now), where there was an incident where an online store used values
in the webpage itself to handle the prices of goods. In the example in the
book, the hackers had replaced $45 list price with $1 giving huge discounts to
the purchasers. And to make things even worse, some of the hackers would order
dozens of shirts (at $1 each) and then return them for full price.

It might have been an earlier edition of this one, but I do remember the
bright red cover: [http://www.amazon.com/Hacking-Exposed-Web-
Applications-2nd/d...](http://www.amazon.com/Hacking-Exposed-Web-
Applications-2nd/dp/0072262990/)

------
MattMitchell
Um, I'm not sure I'm reading this right but you hard-code your prices in JS to
cut down on an AJAX call.

Why not just print your JS from server-side - i.e. you can still have your
prices in your JS but have the server generate these?

~~~
patio11
Easy, fast, and clean all in one little packet of geek joy. I like this
suggestion a lot. Thanks. (The whole code-generates-code thing is still taking
me some time to get used to... even though I spent several hours yesterday
writing code-generates-code-generates-essay.)

------
swombat
_Accordingly, the fact that the same URL rewriting trick that lets me change
the price to give users discounts could be used to reprice my software to a
penny... really doesn't worry me that much._

Is this an invitation to get a 1 penny trial version of your software?

------
staunch
> _"Originally posted by monkeyfish at Hacker News: "_

Should be mechanical_fish I think.

~~~
patio11
I'll fix that once I get back home. Good eye.

------
weaksauce
Does your cart fail gracefully if javascript is turned off, or is that not a
concern for you?

~~~
patio11
Did you try it?

It should fall-through to e-junkie's traditional non-Javascript cart hosted
offsite. I personally think the experience is decidedly suboptimal next to
either of the JS carts but, honestly, I think the Internet is moving away from
assuming that Javascript is optional.

(I would have a different opinion if I had to support a range of mobile
browsers but, well, I sell downloadable software to elementary schoolteachers.
Most of them don't think "Ooh great I loved this downloadable free trial! Let
me write down the URL, get out my iPhone, type in the URL, then order a
copy!")

------
apollo
Good work, I admire your approach.

------
jwesley
How I SEOed my website to make more sales!

~~~
patio11
The main reason it is on the website, as opposed to my blog, is because I am
making _extensive_ use of Rails as the world's most over-engineered templating
system to write that. It wouldn't be interesting at all without the cart to
play with, now would it? I'm all about avoiding sucky user experiences and "I
am going to extensively discuss a feature of another website. Please open that
website in a tab and follow along" is a sucky user experience.

But yeah, to the extent that people find this article as valuable and link to
it, Google will see my site as more trustworthy and send me more frazzled
teachers trying to get ready for fourth period.

I really don't have a problem with that: they get their prep work done, I get
money, the rest of the world gets a few hours of engineer time writing what I
hope was a useful article as a result of the cross-subsidy. The notion is
quite similar to OSS. Its a win for everybody.

~~~
jwesley
Don't get all defensive bro. It's cool to get paid.

