Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Email:

Clickbank Security Using PHP

By Robert Plank
2005-05-25


Couldn't the download url, hash, and receipt be shared?

You can't prevent sharing completely... after all, your customer can always download the file and share the file, not the download URL, to friends.  We can do one thing to give these would-be freeloaders a bit of a headache, and that is expiration.

Here we can say, 30 days after someone buys your product, the thank you page will be inaccessible to them.  If they buy on October 25th, they can bookmark and revisit that thank you page up until November 25th at the exact time they made their purchase.  It's kind of a nice compromise because it gives honest people enough time to get what they need but at the same time it becomes impractical to share the URL.

In chapter 9 of my book, Simple PHP (http://www.simplephp.com), I explained how time works on computers, they use a big number which is just a count of how many seconds have passed since January 1st, 1970.  I also explained that there was a function, called strtotime(), which we could use to determine this "number" or timestamp of a certain date.  For example, 30 days ago or 1 year ago.

30 days sounds about right.  To figure out the Unix timestamp of this moment, minus 30 days is:

strtotime("-30 days")

Now, to store it in a variable called $expire:

$expire = strtotime("-30 days");

But you're saying, how do I know when these people purchased?  I don't have that kind of information.  Aha!  But you can.  Remember, the seed you put in your order links can be anything you want.  So let's just make it the timestamp of this exact moment.

When the customer revisits the thank you page, they can't change the seed, because as I mentioned, if you change *either* the seed or the secret key, the resulting hash (proof of purchase) will be different.  So you see, they're stuck with it.  But, the current time always changes!

All we have to do, in cb.php, are these two steps:

* Figure out what the timestamp was exactly 30 days ago, and store this value in $expire.

* Compare the seed and $expire.  If the the value of the seed is less than that of $expire, it means that the product was purchased more than 30 days ago and the visitor shouldn't be given access to the page.  Die.

We've already taken care of step one by saving the timestamp 30 days prior in $expire.  Now, we compare the seed (it's $_GET["seed"], remember, because we're grabbing it out of the URL string) and $expire like:

if ($_GET["seed"] < $expire)

And finally plug it into the if-statement before that checked the hashes:

if ($_GET["seed"] < $expire or !cbValid($_GET["seed"], $_GET["cbpop"], $secret_key)) die();

We've got that part taken care of, now for the home stretch.  We've got to actually get those seeds to be the current time.  How do we do that?  Again, the pages containing your order link will have to be renamed to end in ".php".  Hey, you're the one who wants to prevent theft.

Let's pretend this is a Clickbank link:

<a href="Order" target="_blank">http://www.clickbank.net/sell.cgi?link=YOUR_CLICKBANK_ID/YOUR_PRODUCT_ID/YOUR_PRODUCT_NAME&seed=YOUR_SEED">Order Now</a>

Instead of YOUR_SEED we want PHP to call the function mktime(), which gives us the current timestamp, and output it, using echo.

echo mktime();

Now just put <?php and ?> around it...

<?php echo mktime(); ?>

And shove it in there.

<a href="http://www.clickbank.net/sell.cgi?link=YOUR_CLICKBANK_ID/YOUR_PRODUCT_ID/YOUR_PRODUCT_NAME&seed=<?php echo mktime(); ?>">Order Now</a>

Now setup a link for $0.00 in your Clickbank control panel and try it.  You can be sure it works by changing that "-30 days" in strtotime to "-5 minutes".  Then try accessing the download page, then wait 5 minutes and try again.  Neat, isn't it?

You say, I've done this, but I have more than one product.  How do I keep someone from grabbing everything once they've grabbed one?

Have your links look like the following: <a href="http://www.clickbank.net/sell.cgi?link=YOUR_CLICKBANK_ID/YOUR_PRODUCT_ID/YOUR_PRODUCT_NAME&seed=stringbeans<?php echo mktime(); ?>">Order Now</a>

This way the seeds will look like "stringbeans445433" if you're selling stringbeans.  Then again if you're selling corn on the cob on another sales page, you can change "stringbeans" to "cornonthecob".  Now the seeds for each product will be different.

Those seeds won't be all numbers, will they?  So, in cb.php, do this:

$timestamp = ereg_replace("[^0-9]","",$_GET["seed");

I won't go into a lot of detail about pattern matching, but the [^0-9] means "NOT anything from 0 to 9.  It basically goes through every letter and number of $_GET["seed"], and if what's there isn't a 0, 1, 2, etc. it's replaced with nothing (hence the "").  The final result is saved in a variable called $timestamp.

Since now we're looking at $timestamp and not $_GET["seed"], let's change that if-statement:

if ($timestamp < $expire or !cbValid($_GET["seed"], $_GET["cbpop"], $secret_key)) die();

Now it checks with $timestamp instead of $_GET["seed"].

One last thing I implemented in here was a little something that keeps a customer from paying for one of your products, and getting access to the rest.  Look at this part of that order link I gave you:

&seed=thankyou<?php echo mktime(); ?>"

When I extracted the timestamp from the seed, I simply removed all characters that were not numbers, leaving just the numbers contained within that string.  Now I want to do the opposite.  Here's an example seed:

test1074482258

I take out all the numbers and am left with "test".  Next I figure out which script called cb.php (which is stored in the variable $_SERVER["SCRIPT_NAME"]).  Then the script takes out everything up to the last slash (/) and everything before the first dot (.).  If the script was located at "/clickbank/test.php", all that's left is "test".

If you give each thank you page a different name, and make sure all your seeds reflect the correct page, i.e. if your thank you page is called "carrots", the part of that order link containing the seed should appear as:

&seed=carrots<?php echo mktime(); ?>"

If you don't care how Clickbank's protection works, that's your prerogative.  Just get the zip file and follow the instructions I've provided in cb.php.

As far as scripts that handle several Clickbank products -- I can't recommend any at this time, since I've never across any good ones.  (But you should check out Harvey Segal's free site, ClickbankGuide.com, which can answer most of your questions about Clickbank.)

Here's that script again in case you missed it: http://www.jumpx.com/tutorials/clickbank/cb.zip

Make sure to read the instructions I've supplied in cb.php, get everything setup and on your web server, and you'll be well on your way to having bulletproof protection on your Clickbank products.

Tutorial Pages:
» The first step
» "Cookie Cutter" tools
» Using someone else's code
» Use mine
» Couldn't the download url, hash, and receipt be shared?


 | Bookmark
Related Tutorials:
» Zend Framework Tutorial
» Port Scanning and Service Status Checking in PHP
» Web Database Access from Desktop Applications
» CubeCart 3.0 Installation and Configuration
» PHP Site Search Made Easy
» Installing and Configuring Drupal 6.1

Ask A Question
characters left.