Home > Articles > Business > PayPal and License Keys

In Brief: PayPal and License Keys

15 jan 2008, Simon Strandgaard

When a purchase happens, then I want to send a license key to the customer. Here is a rough overview of what I did.

I havn't found any great websites about this topic. Its either tiny or huge documents, where you cannot find what you are looking fore. So I cannot provide you with any useful links at all!

Paypals homepage sux too, and that makes it difficult to figure out how things work. Everything is https and maybe that is part of the reason its slow. Its also terrible organised. And the code examples are bad too. Anyways when it works then we don't have to deal with it. If I had to deal with it on daily basis I would go crazy.

STEP1: create 2 bank, 2 email, 2 paypal accounts

One account for your company and another one for a test-customer.

For some reason paypal doesn't allow payment from yourself to youself, it must be from one person to another person!

For some reason two paypal-accounts cannot share the same bank-account. In order to get your accounts verified you need 2 bank-accounts.

A paypal account is bound to the email adress. Therefore I suggest creating an email adress ala paypal@example.com.

Optionally. Paypal has a sandbox for testing, and it requires a 3th email account. Within this sandbox you need to create a buyer account and a seller account, these needs their own email addesses too. And there is a paypaldeveloper.com community that also requires registration, (plus it was difficult to figure out if paypaldeveloper.com were fake or not). In total you may need roughly 6 paypal accounts of different types, sigh!

STEP2: make a purchase page

containing a buynow button. When clicked it redirect to paypals website with info about whats being purchased. Usually its a form with a submit button, like this:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<p>To purchase, <input type="submit" value="click here"/>.</p>
<input type="hidden" name="cmd"           value="_xclick" />
<input type="hidden" name="business"      value="paypal@example.com" />
<input type="hidden" name="item_name"     value="Toolbox" />
<input type="hidden" name="currency_code" value="EUR" />
<input type="hidden" name="amount"        value="10.00" />
<input type="hidden" name="no_shipping"   value="1" />
<input type="hidden" name="no_note"       value="1" /> 
</form>

However our buynow button uses URL encoding, like this:

<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40example.com&item_name=Toolbox&currency_code=EUR&amount=10.00&no_shipping=1&no_note=1#">click here</a>

Also see paypal - the buy now button.

We are selling our computer program only online, so it doesn't make sense to show a shipping address on the order. To prevent paypal from writing a shipping adress on the order, we have to set no_shipping=1. Further more paypal's default payment form, has a textfield where the buyer can write a note to the seller. It may confuse, since there is only one flavor of our computer program and there is no shipping, so we disabling it like this no_note=1.

STEP3: make a paypal callback page

Create a "paypal_callback.php" page, that sends a mail to yourself when ever its accessed. Make sure to print $_POST into the mail-body, so that you can see what is going on when PayPal visit your page. This gives an idea of what to expect from a paypal payment.

STEP4: edit paypal profile for the seller account

All the settings are very well hidden on paypals website. Go to My Account -> Overview -> edit profile -> Selling Preferences. This is the minimal changes you have to do to get things working.

Paypal don't use the name callback, but has chosen the long name "Instant Payment Notification" (IPN). You set the URL address: Selling Preferences -> Instant Payment Notification Preferences. Set this address to: "http://example.com/paypal_callback.php".

The default setting is to block payments and ask you if you want to receive the payment. However we want the our system to be fully automated, so go to: Selling Preferences -> Payment Receiving Preferences, and set "Block payments sent to me in a currency I do not hold:" = "No, accept them".

STEP5: make you first real purchase

take a look at the mail send from you IPN page. You can see some of the many fields that you get from paypal.

test_ipn = 1
charset = windows-1252
txn_type = web_accept
payment_date = 08:40:35 Jan 09, 2008 PST
first_name = Test
last_name = User
residence_country = US
pending_reason = multi_currency
item_name = Toolbox
quantity = 1
payment_gross =
mc_currency = EUR
business = seller@example.com
payment_type = instant
verify_sign = OBFUSCATED
payer_status = verified
tax = 0.00
payer_email = buyer@example.com
txn_id = OBFUSCATED
receiver_email = seller@example.com
payer_id = OBFUSCATED
receiver_id = OBFUSCATED
item_number =
payment_status = Pending
shipping = 0.00
mc_gross = 10.00
custom =
notify_version = 2.4

Lets try interpret this:

test_ipn = 1 This purchase were made using our sandbox accounts, so it not real.

charset = windows-1252 SIGH, terrible encoding. We want unicode. This must be set up inside our business account. My Account -> Overview -> edit profile -> Selling Preferences -> Language Encoding -> More Encoding Options.
Set Encoding = UTF8
Choose "Yes", we want to use same encoding for mails
Next time see if it says charset = UTF-8.

STEP6: make a skeleton include file

to be included in the IPN page. Just echo everything for now. PHP code below:

function process_ipn($postdata) {
    foreach($postdata as $key => $value) {
        echo $key . " = " . $value . "\n";
    }
}

STEP7: make a test page

From here I exercised the include file. I made a form with text fields corresponding to those in the 'first real purchase mail'. From here you can fill in text and pass it to the 'process_ipn' function.

STEP8: rework the include file

I reworked this page over and over until I was satisfied. my goal was to:

  • » Send mail to customer with license key.
  • » Send mail to company with debug info.
  • » Store IPN debug info in database.
  • » Deal with security.

This step is huge. Have a look at the fields needed in your database!

STEP9: rework the IPN page

Now call the 'process_ipn' function.

STEP10: make you second real purchase

See if things is actually working.

STEP11: deal with license keys

See Allan Odgaard's article about this subject.

It was difficult to find good documentation on how to interact with paypal and how software companies can generate license keys after purchasing. I made lots of miss-steps on my way, so I decided to share my leasons, hopefully saving other people for the fuss.