PayPal Integration with PHP and MySQL

Step 1 – Setup PayPal Account

Sign up for a PayPal account if you don’t already have one. Select an appropriate account type, either Personal or Business.

Once you have a registered PayPal account your account must be setup correctly to use IPN.

Select ‘edit profile’ from your PayPal account and check the following settings.

  • Under ‘Selling Preferences’ >> ‘Instant Payment Notification Preferences’
  • Under ‘Selling Preferences’ >> ‘payment receiving preferences’
    • Block payments from users who pay with echeck. (This is because these will not be instant payments)
  • Under ‘account information’ >> ‘email’
    • Note down your primary email address. This email will be visible to users so make it a professional one. User’s may feel apprehensive about sending money to an e-mail address with the domain ‘hotmail.com’ or ‘Yahoo.com’ etc…

Step 2 – Simple HTML Form

Your website must now send all the required values to PayPal so that the payment can be processed.

The following code example demonstrates a basic form that we will use to send the values:

1 <form id="paypal_form" class="paypal" action="payments.php" method="post">
2     <input name="cmd" type="hidden" value="_xclick" />
3     <input name="no_note" type="hidden" value="1" />
4     <input name="lc" type="hidden" value="UK" />
5     <input name="currency_code" type="hidden" value="GBP" />
6     <input name="bn" type="hidden" value="PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest" />
7     <input name="first_name" type="hidden" value="Customer's First Name" />
8     <input name="last_name" type="hidden" value="Customer's Last Name" />
9     <input name="payer_email" type="hidden" value="customer@example.com" />
10     <input name="item_number" type="hidden" value="123456" />
11     <input type="submit" value="Submit Payment" />
12 </form>

The business name, price, submit type, notify URL and other sensitive values will be sent during the next step.

A full list of the values to send can be found at the PayPal website under the title “A Sample IPN Message and Response”.

Step 3 – Payments.php (The Request)

The payment.php page will be used to handle the outgoing request to PayPal and also to handle the incoming response after the payment has been processed.

The following sample code shows the querystring being constructed before it is posted to PayPal. Here you can specify the following values:

  • Business ($paypal_email) – Enter the email address of your PayPal account.
  • Item name ($item_name) – The name of the item being purchased.
  • Amount ($item_amount) – The price of the item.
  • Return ($return_url) – The address to return to after a successful payment.
  • Cancel Return ($cancel_url) – the address to return to after a cancelled payment.
  • Notify URL ($notify_url) – The address of the payments.php page on your website.
  • Custom – Any other data to be sent and returned with the PayPal request.
1 // Database variables
2 $host = "localhost"; //database location
3 $user = ""; //database username
4 $pass = ""; //database password
5 $db_name = ""; //database name
6
7 // PayPal settings
8 $paypal_email = 'paypal@example.com';
12
13 $item_name = 'Test Item';
14 $item_amount = 5.00;
15
16 // Include Functions
17 include("functions.php");
18
19 //Database Connection
20 $link = mysql_connect($host, $user, $pass);
21 mysql_select_db($db_name);
22
23 // Check if paypal request or response
24 if (!isset($_POST["txn_id"]) && !isset($_POST["txn_type"])){
25
26     // Firstly Append paypal account to querystring
27     $querystring .= "?business=".urlencode($paypal_email)."&";
28
29     // Append amount& currency (£) to quersytring so it cannot be edited in html
30
31     //The item name and amount can be brought in dynamically by querying the $_POST['item_number'] variable.
32     $querystring .= "item_name=".urlencode($item_name)."&";
33     $querystring .= "amount=".urlencode($item_amount)."&";
34
35     //loop for posted values and append to querystring
36     foreach($_POST as $key => $value){
37         $value = urlencode(stripslashes($value));
38         $querystring .= "$key=$value&";
39     }
40
41     // Append paypal return addresses
42     $querystring .= "return=".urlencode(stripslashes($return_url))."&";
43     $querystring .= "cancel_return=".urlencode(stripslashes($cancel_url))."&";
44     $querystring .= "notify_url=".urlencode($notify_url);
45
46     // Append querystring with custom field
47     //$querystring .= "&custom=".USERID;
48
49     // Redirect to paypal IPN
50     header('location:https://www.sandbox.paypal.com/cgi-bin/webscr'.$querystring);
51     exit();
52
53 }else{
54     // Response from PayPal
55 }

Step 4 – Payments.php (The Response)

The next part of the payments.php page handles the response from PayPal. The response is re-assigned to variables and then posted back to PayPal for verification using fsockopen.

If the response is VERIFIED then a validation check can be performed. The check_txnid and check_price functions are called to check that the correct Transaction ID and Price have been returned. The updatePayments function can finally be called to store the details of the payment in the payments table (Step 6).

1 // Database variables
2 $host = "localhost"; //database location
3 $user = ""; //database username
4 $pass = ""; //database password
5 $db_name = ""; //database name
6
7 // PayPal settings
8 $paypal_email = 'paypal@example.com';
12
13 $item_name = 'Test Item';
14 $item_amount = 5.00;
15
16 // Include Functions
17 include("functions.php");
18
19 //Database Connection
20 $link = mysql_connect($host, $user, $pass);
21 mysql_select_db($db_name);
22
23 // Check if paypal request or response
24 if (!isset($_POST["txn_id"]) && !isset($_POST["txn_type"])){
25     // Request from step 3
26 }else{
27
28     // Response from Paypal
29
30     // read the post from PayPal system and add 'cmd'
31     $req = 'cmd=_notify-validate';
32     foreach ($_POST as $key => $value) {
33         $value = urlencode(stripslashes($value));
34         $value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value);// IPN fix
35         $req .= "&$key=$value";
36     }
37
38     // assign posted variables to local variables
39     $data['item_name']          = $_POST['item_name'];
40     $data['item_number']        = $_POST['item_number'];
41     $data['payment_status']     = $_POST['payment_status'];
42     $data['payment_amount']     = $_POST['mc_gross'];
43     $data['payment_currency']   = $_POST['mc_currency'];
44     $data['txn_id']             = $_POST['txn_id'];
45     $data['receiver_email']     = $_POST['receiver_email'];
46     $data['payer_email']        = $_POST['payer_email'];
47     $data['custom']             = $_POST['custom'];
48
49     // post back to PayPal system to validate
50     $header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
51     $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
52     $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
53
54     $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
55
56     if (!$fp) {
57         // HTTP ERROR
58     } else {
59                 mail('ash@evoluted.net', '0', '0');
60         fputs ($fp, $header . $req);
61         while (!feof($fp)) {
62             $res = fgets ($fp, 1024);
63             if (strcmp ($res, "VERIFIED") == 0) {
64
65                 // Validate payment (Check unique txnid & correct price)
66                 $valid_txnid = check_txnid($data['txn_id']);
67                 $valid_price = check_price($data['payment_amount'], $data['item_number']);
68                 // PAYMENT VALIDATED & VERIFIED!
69                 if($valid_txnid && $valid_price){
70                     $orderid = updatePayments($data);
71                     if($orderid){
72                         // Payment has been made & successfully inserted into the Database
73                     }else{
74                         // Error inserting into DB
75                         // E-mail admin or alert user
76                     }
77                 }else{
78                     // Payment made but data has been changed
79                     // E-mail admin or alert user
80                 }
81
82             }else if (strcmp ($res, "INVALID") == 0) {
83
84                 // PAYMENT INVALID & INVESTIGATE MANUALY!
85                 // E-mail admin or alert user
86             }
87         }
88     fclose ($fp);
89     }
90 }

Step 5 – Functions.php

The payments.php page calls upon a number of functions used to validate the returned data and store the response in the database.

1 // functions.php
2 function check_txnid($tnxid){
3     global $link;
4     return true;
5     $valid_txnid = true;
6     //get result set
7     $sql = mysql_query("SELECT * FROM `payments` WHERE txnid = '$tnxid'", $link);
8     if($row = mysql_fetch_array($sql)) {
9         $valid_txnid = false;
10     }
11     return $valid_txnid;
12 }
13
14 function check_price($price, $id){
15     $valid_price = false;
16     /*
17     you could use the below to check whether the correct price has been paid for the product
18     if so uncomment the below code
19
20     $sql = mysql_query("SELECT amount FROM `products` WHERE id = '$id'");
21     if (mysql_numrows($sql) != 0) {
22         while ($row = mysql_fetch_array($sql)) {
23             $num = (float)$row['amount'];
24             if($num == $price){
25                 $valid_price = true;
26             }
27         }
28     }
29     return $valid_price;
30     */
31     return true;
32 }
33
34 function updatePayments($data){
35     global $link;
36     if(is_array($data)){
37         $sql = mysql_query("INSERT INTO `payments` (txnid, payment_amount, payment_status, itemid, createdtime) VALUES (
38                 '".$data['txn_id']."' ,
39                 '".$data['payment_amount']."' ,
40                 '".$data['payment_status']."' ,
41                 '".$data['item_number']."' ,
42                 '".date("Y-m-d H:i:s")."'
43                 )", $link);
44     return mysql_insert_id($link);
45     }
46 }

Step 6 – Setting Up The Payments Table

To store payment details in the database a payments table must be created in your database. The following MYSQL code will create a payments table.

1 CREATE TABLE IF NOT EXISTS `payments` (
2   `id` int(6) NOT NULL AUTO_INCREMENT,
3   `txnid` varchar(20) NOT NULL,
4   `payment_amount` decimal(7,2) NOT NULL,
5   `payment_status` varchar(25) NOT NULL,
6   `itemid` varchar(25) NOT NULL,
7   `createdtime` datetime NOT NULL,
8   PRIMARY KEY (`id`)
9 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Step 7 – Sandbox Testing / Going Live

PayPal Sandbox offers all of the functionality of PayPal, but the information involves all “Fake accounts” created by the developer. You can create fake buyer and fake seller profiles, then test your PayPal integration through your development website.

During the testing phase of the development process the PayPal links should be prefixed to www.sandbox.paypal.com. You can visit the PayPal Developer website and sign up for a free PayPal Sandbox account

Once the payment process is ready to be used by real customers you will need to remove the sandbox from each PayPal link to www.paypal.com.

That’s it; you’re ready to start taking payments online through your website.

3 thoughts on “PayPal Integration with PHP and MySQL

  1. Hi, I do think this is an excellent web site. I stumbledupon it 😉 I’m going to revisit once again since I book marked it.
    Money and freedom is the best way to change, may you be rich and continue to help other people.

  2. Sweet blog! I found it while surfing around on Yahoo News.
    Do you have any suggestions on how to get listed in Yahoo News?
    I’ve been trying for a while but I never seem to get there!
    Appreciate it

  3. Hey there! I’m at work browsing your blog from my new apple iphone!
    Just wanted to say I love reading your blog and look forward to all your posts!
    Keep up the superb work!

Leave a comment