In preparation for offering a pdf download of my Rails Django Whitepaper for purchase, I figured I'd just put the file in the downloads section of my site and then post a Paypal Buy Now button that redirects to a page with the download link. Not elegant, but quick-and-dirty would be fine for this.
Buy Now Paypal
I created 3 pages on my site: the buynow page containing the Buy Now button that links to Paypal, a paysuccess page where users are redirected after successfully completing the payment (contains the actual download link), and a paycancel page where users are redirected if they cancel from Paypal.
Making a Buy Now button is easy enough. Assuming you have a Paypal Merchant account (they're a free upgrade from the regular Paypal consumer account), just go to the "Buy Now Buttons " page for selling single items at a time.
Fill in the item name, price, etc. then "Add more options" and give it the URL of your paysuccess and paycancel pages. The resulting button (unencrypted) may look like this:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input name="cmd" type="hidden" value="_xclick"></input>
<input name="business" type="hidden" value="firstname.lastname@example.org"></input>
<input name="item_name" type="hidden" value="Rails and Django Whitepaper"></input>
<input name="amount" type="hidden" value="15.00"></input>
<input name="no_shipping" type="hidden" value="1"></input>
<input name="rm" type="hidden" value="2"></input>
<input name="return" type="hidden" value="http://www.mysite.com/paysuccess"></input>
<input name="cancel_return" type="hidden" value="http://www.mysite.com/paycancel"></input>
<input name="no_note" type="hidden" value="1"></input>
<input name="currency_code" type="hidden" value="USD"></input>
<input name="lc" type="hidden" value="US"></input>
<input name="bn" type="hidden" value="PP-BuyNowBF"></input>
<input alt="Make payments with PayPal - it's fast, free and secure!" name="submit" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif" type="image"></input>
<img src="https://www.paypal.com/en_US/i/scr/pixel.gif" border="0" alt="" width="1" height="1" />
Notice that I added another hidden field, "rm" (return method) with value "2", which requests the transaction details get POSTed to the return URL. This will allow us to validate the transaction and present the download link to the buyer on the paysuccess page.
We won't use IPN (Instant Payment Notification), since the download should be immediately available, not asynchronous. Under a different scenario, say, payment generates an email to the buyer containing the download link, then IPN would be fine.
This all seemed to work fine, both in the Paypal Sandbox (where you setup fake accounts with fake money to test your implementation), and a live site (where you can give yourself refunds for test purchases). Until...
The one case that fails is if a user does not have a Paypal account, and buys with a credit card. After completing the payment transaction he is not returned to my paysuccess page with the POSTed data. Rather, he is asked if he want to sign up for Paypal, doesn't get redirected to my paysuccess page and the POST variables seemingly are lost. I dwelled on the Paypal support forums and discovered I am not alone, it's not me, it's how Paypal works (or rather, fails to work, e.g. here's a specific comment). According to those posts, even using Paypal's Payment Data Transfer (PDT) mechanism may still fail.
Another thing that was bothering me was, in this simplistic scenario, the download link is always exposed and available if you know about it. Not that I'm so worried about thieves in this case, but having something like a unique download key would be more generally useful.
Frustrated, I started to look for another solution.
Looking for a hosted service I first came across PayLoadz , and signed up for a trial account. It was very easy to setup. I had the option of hosting my file(s) on their server or keep them on mine. It does not do any payment processing, you still use Paypal or other services like Google Checkout.
It supports delivering software registration codes but you're still responsible for generating and managing those codes. To my knowledge, it does not manage access keys for the download files themselves.
Then there's their pricing model -- a prepaid monthly fee based on my estimate of the max total in sales per month (roughly a minimum of 1.5%), on top of the Paypal and credit card fees. That's a bit presumptuous, especially for my risky little one item Buy Now application.
Perhaps for a shop with a high inventory of items, the PayLoadz model might work. In which case you'd probably need a Shopping Cart too. That's not the model I'm looking for.
Then I discovered E-junkie . Their service is just $5 per month for 10 items (and it goes up gently from there). For my one item application (and a high risk one at that) that was ok.
Like PayLoadz, it uses Paypal, Google Checkout, and a couple others, to do the payment processing.
E-junkie can generate software registration codes, and can provide secure product download immediately after a successful payment. That is, each download gets a unique download link (containing a validation code) taylored to a specific purchase, which you can set to expire after a limited time or number of downloads. And I can set a redirect back to my site so I can log transactions in my database as well. E-junkie does not require I setup PDT on my Paypal account.
Those features are very nice, exactly what I wanted, and would be a bit of a PITA (pain in the arse) to do for a one-off situation.
The E-junkie site is simple, fast, and has a wide range of features. Good job, guys!