StellarWebSolutions.com Stellar Web Solutions

You are here: Home > Articles > PayPal Buttons in PERL

How-To: Build your own PayPal Encrypted Buttons

Paypal uses the X.509 standard certificate format which was originally developed for sending encrypted email messages. PayPal uses this to encrypt the data so they can decrypt it, while signing it so that they can ensure that you originated it.

How It Works

You first create a private key and public signing certificate and download PayPal's public key. You upload your public certificate to PayPal. PayPal generates a unique ID to ensure a malicious user is not just using their own certificate.

Using something like open source tool OPENSSL, you can encrypt your form data to be sent to PayPal. You can test all of this with PayPal's sandbox website.

How-To: Do it yourself button encryption

Step 1: Generate your private key and public certificate.

You can either generate your private key and public certificate on your own server manually (step 1a and 1b), or use our Stellar PayPal Certificate Wizard.

Step 1a: Manual Creation - Generate a Private Key 1024 bytes long

openssl genrsa -out my-prvkey.pem 1024

my-prvkey.pem is your private key.

Step 1b: Manual Creation - Generate public certificate good for 1 year

openssl req -new -key my-prvkey.pem -x509 -days 365 -out my-pubcert.pem

my-pubcert.pem is your public signing certificate. Remember that your certificate is only valid for 365 days with this command, you should recreate your key and certificate every year.

Step 2: Upload Your Public Certificate

To upload your public certificates to PayPal:
1. Log in to your Business or Premier account.
2. Click the Profile subtab.
3. In the Seller Preferences column, click Encrypted Payment Settings.
4. Click Add.
5. Click Browse, and select your public certificate file "my-pubcert.pem".
6. When your public certificate is successfully uploaded, it appears on the next screen under Your Public Certificates.
7. Record the Cert ID, you'll need to include this in any encrypted data.

Step 3: Download the PayPal Public Certificate

You use PayPal's public certificate to encrypt your button code. To download PayPal's public certificate: 1. Log in to your Business or Premier account.
2. Click the Profile subtab.
3. In the Seller Preferences column, click Encrypted Payment Settings.
4. Click Download in the PayPal Public Certificate area.

Step 4: Block unencrypted payment buttons

You can prevent malicious users from submitting made up unencrypted buttons by blocking unencrypted payments. You should probably have everything working before you complete this step or your current payment buttons may become broken.
1. Log in to your Business or Premier account.
2. Click the Profile subtab.
3. Click the Website Payment Preferences link in the right-hand menu.
4. Select On next to Block Non-encrypted Website Payments.
5. Click Save.

Step 5: Generate your own payment buttons.

You can use Perl or other languages to implement PayPal encrypted button generation.

The following code is an example of how to implement PayPal button encryption. The PayPal($hash) function accepts a hash of form data to be encrypted by calling the OPENSSL system command (there is currently no Perl API into this particular OpenSSL command.

Download Example


#!/usr/bin/perl
#Sample PayPal Button Encryption: Copyright 2006,2007 StellarWebSolutions.com
#Not for resale  - license agreement at
#http://www.stellarwebsolutions.com/en/eula.php
#Updated: 2007 01 10
use IPC::Open2; #for open2 command

$MY_KEY_FILE = "/usr/home/user/my-prvkey.pem"; #private key
$MY_CERT_FILE = "/usr/home/user/my-pubcert.pem"; #signing certificate
$PAYPAL_CERT_FILE = "/usr/home/user/paypal_sandbox.pem"; #PayPal certificate
$OPENSSL = "/usr/bin/openssl"; #openssl command


my %hash = ('cmd' => '_cart',
        'business' => 'paypala@accounthere.com',
        'cert_id' => 'ABCDEF1234567',
        'notify_url' => '',
        'return' => '',
	'shopping_url' => '',
        'cancel_return' => $cancel_return,
        'rm' => $rm,
        'lc' => 'US',

        'custom' => 'customfield',
        'invoice' => '', #must be unique
        'currency_code' => 'USD', #or USD
        'upload' => '1',
        'no_shipping' => '1',

        'item_name' => 'Stellar Cart',
        'item_number' => '12345',

        'item_name_1' => 'ebook A',
        'amount_1' => '10.00',
        'quantity_1' => '1',
        'item_number_1' => '111111',

        'shipping_1' => '0',

        'item_name_2' => 'Software B',
        'amount_2' => '39.99',
        'quantity_2' => '2',
        'item_number_2' => '222222',
        'shipping_2' => '0',
        'on0_1' => 'Delivery',
        'os0_1' => 'Electronic Download',
        'on1_1' => 'OS',
        'os1_1' => 'Linux',



        'item_name_3' => 'ebook C',
        'amount_3' => '69.69',
        'quantity_3' => '1',
        'item_number_3' => '333333',
        'shipping_3' => '0',
	);

	my $encrypted = paypal(%hash);


# print encrypted button form
        print <<HTML_HEADER;
Content-Type: text/html

<HTML>
<HEAD>
<TITLE>Sample Shopping Cart using PayPal Encrypted Buttons</TITLE>
</HEAD>
<BODY bgcolor=white>

<h1>Checkout</h1>
<P><I><B>Buy Now using PayPal!</B></I></P>
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="
$encrypted">
<input type="submit" value="Checkout">
</form>
HTML_HEADER

exit(1);


sub paypal ($)
{
#Sample PayPal Button Encryption: Copyright 2006,2007 StellarWebSolutions.com
#Not for resale  - license agreement at
#http://www.stellarwebsolutions.com/en/eula.php
#Updated: 2007 01 10
	my (%dat) = @_; 

	$dat{ 'bn' } = 'StellarWebSolutions.PERL_EWP';

	my $pid = open2(*READER, *WRITER,
		"$OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
		"-outform der -nodetach -binary | $OPENSSL smime -encrypt " .
		"-des3 -binary -outform pem $PAYPAL_CERT_FILE")
  		|| die "$OPENSSL: failed: $!\n"; 

	for my $key ( keys %dat ) {
 		if ($dat{$key} ne "") {
 			print WRITER "$key=$dat{$key}\n";
		}
	};

	close(WRITER);

	# get encrypted data
	my @lines = <READER>;

	close(READER);

	# get string of encrypted data
	my $encrypted = join('', @lines);

	return $encrypted
};

Here's an example of the above code in action using a simple donation. Right click in the white box and "View Source" to see the underlying secure encrypted button blob.

Download Example