Monday, October 6, 2008

Paypal Integration Can Be Painless If You Know How



Here's my primer on how to get going with PayPal for your site. I'll admit that PayPal makes it difficult. I feel for you.

First, you need a product catalog. Don't have one? Fine. Get a CMS, make some categories and subcategories, give people a menu for that on the left, and start drawing up your articles as product pages. So I can here you asking me -- where's the shopping cart and the integration with PayPal? Well, PayPal gives you a FREE shopping cart, and the steps below will show you how to integrate it easily.

Okay, now you need to add two buttons. One is an Add To Cart button. The other is a Checkout Now button. I'll save you the hassle of going to make one on PayPal's site. Here's how it's made:

Replace [ and ] with < and > below.

[form target="paypal" action="$sPayPalDom/cgi-bin/webscr" method="post"]
[input name="cmd" value="_cart" type="hidden"]
[input name="business" value="$sPayTo" type="hidden"]
[input name="lc" value="$sLocation" type="hidden"]
[input name="item_name" value="$sTitle" type="hidden"]
[input name="item_number" value="$sProdID" type="hidden"]
[input name="amount" value="$sPrice" type="hidden"]
[input name="currency_code" value="$sCurrency" type="hidden"]$sNoShipping $sShipping
[input name="rm" value="1" type="hidden"]
[input name="return" value="$sPurchase" type="hidden"]
[input name="cancel_return" value="$sCancel" type="hidden"]
[input name="add" value="1" type="hidden"]
[input name="bn" value="PP-ShopCartBF:btn_cart_LG.gif:NonHosted" type="hidden"]
[input src="images/addcart.png" name="submit" alt="" border="0" type="image"]
[img alt="" src="http://www.blogger.com/$sPayPalDom/en_US/i/scr/pixel.gif" border="0" height="1" width="1" /]
[/form]


In the above, replace $sPayPalDom with 'https://www.paypal.com' when you want to go into production, or 'https://www.sandbox.paypal.com' when you want to be in sandbox test mode. For sandbox test mode, you need to go to sandbox.paypal.com and sign up for two accounts -- a merchant account and a customer account. Then, you'll use those for your sandbox mode -- not only for this button on $sPayTo, but also when you pretend to be a customer and want to purchase something. Remember, when you're on the sandbox, everything is entirely phony, but it feels real.

For $sPayTo, that's either your production PayPal email account that you use, or your sandbox email account as the merchant. For $sLocation, that's your ISO two-letter country code, such as CA, US, etc. For $sTitle, that's the title of your product. For $sProdID, that's some made-up product ID you want to give your product, and it should be unique. For $sPrice and $sCurrency, that's the price you want and in what currency. The currency code is a 3 letter code like USD, GBP, CAD, etc.

Then you see something odd -- $sNoShipping and $sShipping. Okay, if you plan on having a product that will be shipped out, then $sShipping needs to be:

Replace [ and ] with < and > below.

[input type="hidden" name="cn" value="Add special instructions to the seller"]
[input name="no_shipping" value="2" type="hidden"]


If you don't intend on shipping something out, such as provide a hyperlink to download an eBook at the end of the purchase, then $sNoShipping needs to be:

Replace [ and ] with < and > below.

[input name="no_note" value="1" type="hidden"]
[input name="no_shipping" value="1" type="hidden"]


Now, notice I have an addcart.png file. Go make yourself your own Add To Cart button -- PayPal's versions look awful. Navy on orange? Give me a break!

For $sPurchase, make that a url back to a page on your site. It needs to be an absolute URL like http://mydomain.com/purchase.php. For $sCancel, make that a url back to a page on your site. It needs to be an absolute URL like http://mydomain.com/cancel.php. Now go make a cancel.php page that basically says something to the effect of, "Your purchase was cancelled. Have a nice day."

Now, go back and edit your $sPurchase variable. You need to tack on to the end of it:


"?id=$sProdID" . "&s=" . $sSecurityCode;


The $sProdID we already discussed. The $sSecurityCode should be a unique code based on your ProdID in order to reduce the opportunities of hacking purchases from you. So how do you make that? Well, here's an algorithm:


$sSecurityCode = 'PROD' . mt_rand(11, 99) . base64_encode(crc32($sProdID));
$sSecurityCode = str_replace('=','',$sSecurityCode);
$sSecurityCode = urlencode($sSecurityCode);


However, everyone should make their own algorithm and it should at least involve crc32 on the Product ID, and everything else needs to be predictable flourish, but only predictable to you. The reason I do urlencode is, well, we're going to tack it on the end of a URL and we need it to run properly in the browser. PayPal returns back to your site after a purchase by this URL.

So, stick that piece of HTML on your product pages to draw your Add To Cart button. But it's also nice to have a Checkout Now button. Here's what that looks like:

Replace [ and ] with < and > below.

[form target="paypal" action="$sPayPalDom/cgi-bin/webscr" method="post"]
[input name="cmd" value="_cart" type="hidden"]
[input name="business" value="$sPayTo" type="hidden"]
[input name="display" value="1" type="hidden"]
[input src="images/checkout.png" name="submit" alt="" border="0" type="image"]
[img alt="" src="http://www.blogger.com/$sPayPalDom/en_US/i/scr/pixel.gif" border="0" height="1" width="1" /]
[/form]


So, we've already discussed the $sPayTo and $sPayPalDom fields -- they're the same as the Add To Cart button. You can swap just as I mentioned above with the sandbox domain of 'https://www.sandbox.paypal.com' if you want to be in sandbox mode.

Notice also the checkout.png image. You need to draw your own Checkout Now button because PayPal has an ugly one.

Okay, this next part is where most newbie developers get bungled up, so listen carefully.

First, you need to change your merchant account settings in PayPal. Say, are you on Website Payments Standard or Website Payments Pro? You really only need to be Website Payments Standard for this arrangement I'm explaining here. Second, you need to edit your profile (click it's link to see the full set of profile options -- don't choose a submenu item) and do three critical things under Website Payment Preferences -- turn on auto return, type in a return URL. Let's stop there a second. This return URL business is confusing! What they don't make clear with PayPal is that your HTML you generated above will override this parameter, so you could put http://monkeybrains.com/ here and it wouldn't matter. But PayPal requires that you put something there, so make them happy. Now, the next thing you need to flip on in Website Payment Preferences is PDT, or Payment Data Transfer. Turn that on. BTW, they give you an ID there. You can blow that off -- ignore it because we're going to use $sSecurityCode instead. And why? Because I found it more secure and easier to manage than this stupid code they give me from PayPal, that's why.

Second, you need to build a purchase.php page. In it, you need to perform the following functions.

1. Check for a query parameter ($_GET['sig']) that comes back from PayPal. It needs to be a non-empty string. If you come up empty, then fire off an email with mail() to you about a potential hacker, and show a fake 404 page.

2. Check for a query parameter ($_GET['id']). That's your product ID. If you don't get a valid one, then handle as if it's a hacker attack just like in step # 1.

3. Check for a query parameter ($_GET['s']). That's your security code. Basically you need to take the product ID you recevied and then repeat that security code algorithm you came up with upon it. So, for instance:


$sProdID = $_GET['id'];
$sSecurityCode = 'PROD' . mt_rand(11, 99) . base64_encode(crc32($sProdID));
$sSecurityCode = str_replace('=','',$sSecurityCode);
$sSecurityCode = urlencode($sSecurityCode);


Now compare what you received in $_GET['s'] with $sSecurityCode. If they don't match, then, again, email yourself and put up a fake 404.

Otherwise, you need to send a nice message in your purchase.php because we have a valid user:

Replace [ and ] with < and > below.

[h5]Thank you for your payment. Your transaction has been completed, and a receipt for your purchase
has been emailed to you. You may log into your account at [a href="http://www.paypal.com/" target="_new"]www.paypal.com[/a] to view details of this transaction.[/h5]


Now, if this is a downloadable type product, feel free to show your download link to the end user at this point in your purchase.php. Otherwise, that's all you need to send. BTW, you'll want to Google on various methods to prevent people from having a download link that works more than 2 days. I mean, you don't want someone paying for the item, then requesting a refund, and then giving out that link to 100 people off his blog.

So, what do you get from this? You get an email from PayPal letting you know about new purchases, and when you login to PayPal, you have the option to approve or deny that purchase.

Now, there's something more elaborate called IPN (Instant Payment Notification), where PayPal tells your website, live, the status of an order, and then your website can authorize that order or decline it, but in my opinion if you're going to need that, you're doing waaaaaay too much business than to need PayPal. You need something better and on a pay-by-month program. IPN is not only troublesome to set up, but it's known for not always being as reliable -- it has some major outages.

Saturday, September 13, 2008

PunBB -- Like It Better Than phpBB

I was getting sick and tired of phpBB. Underneath it's code, it's the craziest bunch of spaghetti code you've ever seen. And the tech support forum has some tough moderators to deal with. The support was shoddy and I didn't like it. And I got sick and tired of phpBB losing its theme settings!!!

I went looking around and found something I really, really like. It's called PunBB. I downloaded version 1.3 RC and installed it. It's a snap to install, and even easier to customize. Now, there are two drawbacks with this, but I found a way to overcome each one:
  • It doesn't have Private Messaging. However, I merely installed pun_pm extension and it was working beautifully.
  • It doesn't have Rich Editing. However, within 2 hours, I managed to convert it over to using TinyMCE with BBCode output.
So, anyway, I highly recommend that all your future forum choices use PunBB. It's easy to setup, customize, and integrate, and the tech support community for it is really good too.

Thursday, September 4, 2008

Project Management Needs -- Use ActiveCollab

Okay, I'm sold. I'm a convert. This ActiveCollab is really neat. I'm using it on a project with a partner and it helps us collect our ideas in a central place since our inboxes sometimes get confusing to go through. We can also set up permissions in it such that our clients can interact with us but cannot see certain parts.

Sunday, August 31, 2008

Latest Thoughts

  • I didn't realize how wonderful it is when you have built a mini-CMS, an admin scaffolding, you draw all your GUI pages up front before coding, and you understand common concepts like file upload, TinyMCE rich editing, paginated grids, and jQuery. It makes a world of difference. And it seems that the best approach on building sites is to start in the admin system, then the page templates for the end user experience, and then build the gadgets in the end user experience that interact with the data.
  • I see a bright future for me once I get two projects out of the way. I'll have about $4500 in here from those projects, but then I'll turn around and have a reusable CMS and/or admin system (whichever I need to use) that I can do for countless projects in the future.
  • Another thing I need to build is a mini-Product Catalog which ties into PayPal's Add To Cart and Checkout buttons.

Monday, August 18, 2008

Tough Right Now

Things are tough right now. I think after earning my entire salary of last in year in just 6 months, I was severely burnt out. However, then I had a contract loss in July that ate up $5K of my normal quota, and then here it is mid-August and I'm at $0 income right now.

However, here's what's going on...

* I'm working out the details for a $10K to $20K contract. This is going to be a tough one. I don't think my client has the $20K to give me if that's what the project hours will end up coming to once I estimate this. However, I'll also have an equity stake on the project for a period of years so that I can get residual income. It's a job seeker site, and those usually do well (I think).

* I started on a project for $500 starter websites made entirely with WordPress and some fancy tricks, and I was going to farm that on Craigslist. However, I got stuck on the time consuming part of building the form for them to choose options, the ad I need to write, and so on -- fine little details that suck time. And then I mentioned it to my UK client (who's like a partner to me) and he said not to worry about those sites for now -- that he can feed me enough $2K projects to keep me going. (I only usually need $6K per month to survive comfortably.)

* I started my first public phpBB forum. It's on an obscure topic, though, and I don't have any visitors yet except one, so it's going kind of slow. However, I'm learning as I go here and my next forum will be better. I'm collecting income from AdBrite and Google AdSense -- so far $0.

* I've got a $3K contract I'm on right now and another for $1500. They kind of bleed into each other in requirements -- I can share code a little. Anyway, I've been dragging my feet to get this moving, and I'm now suddenly forced to doing this so that I don't have a lot of debt. The other trouble is the time consumption here -- I have very little time to earn that total $4500 and move on to the next stuff.

Nice Regexps

I've been doing some Javascript client-side form data entry validation lately. I wasn't interested in using a jQuery plugin because I frankly didn't trust that the plugin author would get it right. Besides, I can write my own plugin once I figure this out. Anyway, here's some need RegExps I found along the way:

Test for Alphanumeric

if (/\W/.test(s)) {
alert('That field is not alphanumeric.');
}


Test for Normal Full Name Structure

if ((!/^([a-z\x80-\xFF\'\.\-]+(. )?[ ]?)+$/i.test(sFull)) || (/\d/.test(sFull))) {
alert("The Full Name must be alphabetical and properly formatted (i.e., O'Malley Haven-Wilcox Jr.)";
}


Anyway, more can be found here, but they aren't all perfect and require testing:

http://regexlib.com/

Monday, July 28, 2008

Latest Thoughts

  • A new hosting site, Mosso, seems to want to brag about having affordable rates for a scalable website. They're really for mid-sized sites that have grown out of shared hosting plans and need something more robust. Yeah, but the trouble is they don't even use Apache. They use IIS7. Ha, yeah, like that's scalable and secure. No wonder they're still too pricey for me to even think of them.
  • I thought I was the first to come out with the news about W2K8S having a free 240 day trial license from Microsoft. But now I'm seeing that others are repeating what I'm saying.
  • Saw a neat logo on this site. It's interesting what a little light effect, some font uniqueness (using all uppercase or all lowercase), and good color choices can do for your site with relative ease.
  • The newer browsers -- FF3, Opera, and Safari -- now have a new feature where if you use non-styled HTML form controls, they will automatically style them with fairly visually appealing 3D glass-like effects with curved borders on some of the controls as well as a highlight color during a mouseover. Microsoft, however, has not gotten the memo on this. Let's hope they do because it would be great to not have to worry about styling these components ever again.