PayPal REST API Payment System (PHP)

Everyone’s been really excited about PayPal REST API since its launch, so I decided to try and explore PayPal’s new RESTful web service. And after playing a bit with it, I was able to create my own simple online cell phone store successfully. Here’s how! Before we continue, make sure you have signed up for PayPal Developer account for testing mode, and for production mode you will need real PayPal account. Obtain your Client Id and Client Secret from developer portal (for testing) OR from your real PayPal account (for production mode). PayPal REST SDK requires PHP version 5.3.0 +, so make sure your PHP is latest. paypal-rest-api-store PayPal PHP SDK is included in downloadable file below, but you can get your own copy from github. If you are using composer, just point to downloaded file and give “composer update” command to have your SDK updated to latest version. Well, you can forget whole composer thing right now if it doesn’t ring a bell! Back to tutorial, I have created four files for my Online Cell Phone store, but we only need to focus on first two files to get things done. Other two files are helper script and cancellation page.
  • Index.php – (Products page) contains list of products for sale.
  • Order_process.php – Processes PayPal payment.
  • Functions.inc.php – Helper script, contains functions needed for processing.
  • Payment_cancel.html – PayPal redirects user to this page in-case of cancellation.

Products Page

In this page I have created list of items I want to sell, each item has HTML form, which contains its name, quantity, code and price ready to be posted to Order_process.php. I have tried using some CSS to make it look good, but hopefully you will do it better.
PHP
1234567891011121314
<img src="images/cell_phone1.jpg" width="220" height="220">
<div class="item-name">Star mini S5</div> 
<div class="btn-wrap">
<form action="order_process.php" method="post">
Qty:
<select name="qty">
    <option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>8</option><option>10</option><option>20</option>
</select> 
<input type="hidden" name="item_name" value="Star mini S5" />
<input type="hidden" name="item_code" value="001" />
<input type="hidden" name="item_price" value="100" />
<input type="submit" value="Buy $100" />
</form>
</div>

Order Processes

Next we look into order processes page. Here you might get bit confused, but the steps are fairly simple, let me make bit easier for you by pointing out the steps below.
  • Step 1: Get product POST Values from products page.
  • Step 2: Create a payment by constructing a payment object.
  • Step 3: Get approval url from the response, and redirect the user to PayPal for approval page.
  • Step 4: After Payment confirmation by user, execute payment on behalf of user using Payment ID andPayer ID.
  • Step 5: Redirect user to return URL and display success message set earlier in PHP session.
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
<?php
session_start(); //start session

define('CLIENT_ID', 'WIUEEW32IE2DSXCmsdwo9Eew23433SDOIWUDs'); //your PayPal client ID
define('CLIENT_SECRET', 'sEWOIDWE-EWeeewEWRdWE86LdfGFEfAaSDOoDS0WeDNVcXD-xFsSw'); //PayPal Secret
define('RETURN_URL', 'http://YOUR-SITE/paypal-store/order_process.php'); //return URL where PayPal redirects user
define('CANCEL_URL', 'http://YOUR-SITE/paypal-store/payment_cancel.html'); //cancel URL
define('PP_CURRENCY', 'USD'); //Currency code
define('PP_CONFIG_PATH', ''); //PayPal config path (sdk_config.ini)

include_once __DIR__ . "/vendor/autoload.php"; //include PayPal SDK
include_once __DIR__ . "/functions.inc.php"; //include our PayPal functions

#### Prepare for Payment ####
if(isset($_POST["item_code"])){
	
	$item_name = $_POST["item_name"]; //get item code
	$item_code = $_POST["item_code"]; //get item code
	$item_price = $_POST["item_price"]; //get item price
	$item_qty = $_POST["qty"]; //get quantity
	/* 
	Note: DO NOT rely on item_price you get from products page, in production mode get only "item code" 
	from the products page and then fetch its actual price from Database.
	Example :
	$results = $mysqli->query("SELECT item_name, item_price FROM products WHERE item_code= '$item_code'");
	while($row = $results->fetch_object()) {
		$item_name = $row->item_name;
		$item_price = item_price ;
	}  
	*/

	//set array of items you are selling, single or multiple
	$items = array(
		array('name'=> $item_name, 'quantity'=> $item_qty, 'price'=> $item_price, 'sku'=> $item_code, 'currency'=>PP_CURRENCY)
	);
	
	//calculate total amount of all quantity. 
	$total_amount = ($item_qty * $item_price);
	
	try{ // try a payment request
		//if payment method is paypal
		$result = create_paypal_payment($total_amount, PP_CURRENCY, '', $items, RETURN_URL, CANCEL_URL);
			
		//if payment method was PayPal, we need to redirect user to PayPal approval URL
		if($result->state == "created" && $result->payer->payment_method == "paypal"){
			$_SESSION["payment_id"] = $result->id; //set payment id for later use, we need this to execute payment
			header("location: ". $result->links[1]->href); //after success redirect user to approval URL 
			exit();
		}
		
	}catch(PPConnectionException $ex) {
		echo parseApiError($ex->getData());
	} catch (Exception $ex) {
		echo $ex->getMessage();
	}
}


### After PayPal payment method confirmation, user is redirected back to this page with token and Payer ID ###
if(isset($_GET["token"]) && isset($_GET["PayerID"]) && isset($_SESSION["payment_id"])){
	try{
		$result = execute_payment($_SESSION["payment_id"], $_GET["PayerID"]);  //call execute payment function.

		if($result->state == "approved"){ //if state = approved continue..
			//SUCESS
			
			unset($_SESSION["payment_id"]); //unset payment_id, it is no longer needed 
			
			//get transaction details
			$transaction_id 		= $result->transactions[0]->related_resources[0]->sale->id;
			$transaction_time 		= $result->transactions[0]->related_resources[0]->sale->create_time;
			$transaction_currency 	= $result->transactions[0]->related_resources[0]->sale->amount->currency;
			$transaction_amount 	= $result->transactions[0]->related_resources[0]->sale->amount->total;
			$transaction_method 	= $result->payer->payment_method;
			$transaction_state 		= $result->transactions[0]->related_resources[0]->sale->state;
			
			//get payer details
			$payer_first_name 		= $result->payer->payer_info->first_name;
			$payer_last_name 		= $result->payer->payer_info->last_name;
			$payer_email 			= $result->payer->payer_info->email;
			$payer_id				= $result->payer->payer_info->payer_id;
			
			//get shipping details 
			$shipping_recipient		= $result->transactions[0]->item_list->shipping_address->recipient_name;
			$shipping_line1			= $result->transactions[0]->item_list->shipping_address->line1;
			$shipping_line2			= $result->transactions[0]->item_list->shipping_address->line2;
			$shipping_city			= $result->transactions[0]->item_list->shipping_address->city;
			$shipping_state			= $result->transactions[0]->item_list->shipping_address->state;
			$shipping_postal_code	= $result->transactions[0]->item_list->shipping_address->postal_code;
			$shipping_country_code	= $result->transactions[0]->item_list->shipping_address->country_code;
						
			  /*
				####  AT THIS POINT YOU CAN SAVE INFO IN YOUR DATABASE ###
				//see (https://www.sanwebe.com/2013/03/basic-php-mysqli-usage) for mysqli usage
			   
				//Open a new connection to the MySQL server
				$mysqli = new mysqli('host','username','password','database_name');
			   
				//Output any connection error
				if ($mysqli->connect_error) {
					die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error);
				}      
			   
				$insert_row = $mysqli->query("INSERT INTO transactions (payer_id, payer_name, payer_email, transaction_id)
					VALUES ('payer_first_name' , '$payer_email' , '$transaction_id')");
				*/
			   			
			//Set session for later use, print_r($result); to see what is returned
			$_SESSION["results"]  = array(
					'transaction_id' => $transaction_id, 
					'transaction_time' => $transaction_time,
					'transaction_currency' => $transaction_currency,
					'transaction_amount' => $transaction_amount,
					'transaction_method' => $transaction_method,
					'transaction_state' => $transaction_state
					);
						
			header("location: ". RETURN_URL); //$_SESSION["results"] is set, redirect back to order_process.php
			exit();
		}
		
	}catch(PPConnectionException $ex) {
		$ex->getData();
	} catch (Exception $ex) {
		echo $ex->getMessage();
	}

}

### Display order confirmation if $_SESSION["results"] is set  ####
if(isset($_SESSION["results"]))
{
	$html = '<!DOCTYPE HTML>';
	$html .= '<html>';
	
	
	$html .= '<head>';
	$html .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
	$html .= '<title>Order Confirm Details</title>';
	$html .= '<style type="text/css">';
	$html .= '.transaction_info {margin:0px auto; background:#F2FCFF;; max-width: 750px; color:#555;}';
	$html .= '.transaction_info thead {background: #BCE4FA;font-weight: bold;}';
	$html .= '.transaction_info thead tr th {border-bottom: 1px solid #ddd;}';
	$html .= '</style>';
	$html .= '</head>';
	$html .= '<body>';

	$html .='<div align="center"><h2>Payment Success</h2></div>';
	$html .= '<table border="0" cellpadding="10" cellspacing="0" class="transaction_info">';
	
	$html .= '<thead><tr><td>Transaction ID</td><td>Date</td><td>Currency</td><td>Amount</td><td>Method</td><td>State</td></tr></thead>';
	
	$html .= '<tbody><tr>';
	$html .= '<td>'.$_SESSION["results"]["transaction_id"].'</td>';
	$html .= '<td>'.$_SESSION["results"]["transaction_time"].'</td>';
	$html .= '<td>'.$_SESSION["results"]["transaction_currency"].'</td>';
	$html .= '<td>'.$_SESSION["results"]["transaction_amount"].'</td>';
	$html .= '<td>'.$_SESSION["results"]["transaction_method"].'</td>';
	$html .= '<td>'.$_SESSION["results"]["transaction_state"].'</td>';
	$html .= '</tr>';
	$html .= '<tr><td colspan="6"><div align="center"><a href="index.php">Back to Products Page</a></div></td></tr>';
	$html .= '</tbody>';
	$html .= '</table>';
	$html .= '</body>';
	$html .= '</html>';
	
	echo $html;
	
	unset($_SESSION["results"]);
}
?>
That’s it! you should now have a functional online store of your own using PayPal REST API. There is now just one more step to follow. Before you make it live find sdk_config.ini config file, open it and change Service mode to live and don’t forget to enter real PayPal client ID and Secret in order_process.php.

Conclusion

PayPal REST API has lots of new features and supports a number of countries and currencies, please check whether your country is in the list. For countries not yet supported by the REST API, you can take a look at my other tutorial about PayPal. Download Demo
  • 30 Comments

    Add Comment
    • Syed mustafa
      Please send me (Functions.inc.php) page.
    • Andy
      Hi, I have a problem with this script: white page, no errors. It is something with sessions.
    • Arvind kumar yadav
      hi, paypal's payment work proper .and there is need to implement refund the amount if any request is canceled,please help how to use refund option in php.
    • Slee
      Hi I put your file in local hotdocs, but I opened up by internet browser and not able to your content, could you guide me how to browse your file using in locally?
    • Lorello
      Great Script, all works fine, but Paypal doesn't start any transaction. After return to the success page, i can't see any transfer, on any side.. What is the problem?
    • Lijo
      Hello, Could you please help me? Tested the code in sandbox mode, it is working properly, but when I switched to live mode I am getting an error saying "Got Http response code 401 when accessing https://api.sandbox.paypal.com/v1/oauth2/token.". I updated the mode in sdk_config.ini to live and used live client ID and secret key in functions.inc.php. Still it redirecting to sandbox URL. Please guide me. Thanks
    • Dave
      Thank you. I am using the sample codes from php paypal sdk rest api home page and they can prove pretty intimidating especially when you look at the success request and response objects. I came here to learn what are the essential data that we should capture from the API response and your example above together with the Demo is extremely useful in showing the whole transaction process.
    • Geekad
      How do i make it live ? i tried changing .ini file but that doesn't work
    • Tariq
      Many Thanks for tutorial Its work for me Regards, Tariq
    • Stefan
      Hi, if I use the API I get a error back "error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failureArray ( ) " any idea to fix it? Stefan
      • Stefan Stefan
        It works if you update ... public static $defaultCurlOptions = array( CURLOPT_SSLVERSION => 6, ...