Coders' Guidebook

How to capture PayPal transactions using PHP: server-side API integration

In this tutorial, we will learn how to retrieve transaction details from PayPal's V2 order/payment API. This is an important step when integrating PayPal's smart payment buttons with your website. If you would like to learn more about using PayPal and setting up an online store then you may be interested in our course. It's the ultimate guide for anyone looking to build an online store from scratch.

digital-store-checkout.png

PayPal's smart payment buttons

PayPal provides instructions on their website for how to integrate their smart payment buttons; however, the steps can be a little tricky to follow, especially when it comes to retrieving transaction details and information about the customer. To understand what's happening, let's first look at the script which loads the PayPal buttons. The following code is copied directly from PayPal's website:

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      // This function sets up the details of the transaction, including the amount and line item details.
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {
      // This function captures the funds from the transaction.
      return actions.order.capture().then(function(details) {
        // This function shows a transaction success message to your buyer.
        alert('Transaction completed by ' + details.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');
  //This function displays Smart Payment Buttons on your web page.
</script>

The part of the above code we should focus on here is the onApprove function. This function will run following successful payment. As it stands, the customer will be notified the transaction was completed but not much else will happen. In all likelihood, there is probably quite a bit more you would like to do following successful payment. For example, you may want to create a record of the order on your server, retrieve key customer details such as their email and shipping address, and perform other actions relating to their order. As such, it is often beneficial to run a separate PHP file after successful payment. The following code modifies the onApprove function to run a file called paypal-transaction-complete.php. We'll create this file shortly and it will mediate all the actions which are required to process an order:

onApprove: function(data, actions) {
  return actions.order.capture().then(function() {
  window.location = "store-files/paypal-transaction-complete.php?&orderID="+data.orderID;				
  });
}

The window.location command opens the paypal-transaction-complete.php file. At the end of the redirection instruction, we pass the PayPal order ID into the URL. This allows the PHP file to retrieve the order ID with a GET command and use it when communicating with PayPal's API. In the above example, the paypal-transaction-complete.php file is stored in a folder called 'store-files'. It's up to you where you store the file but you may need to amend the redirection command accordingly to reflect the new location.

Retrieving transaction details

We'll now write the code that retrieves the transaction details from PayPal and stores the information you want in variables. Copy and paste the following code inside the paypal-transaction-complete.php file:

<?php
//1. Import the PayPal SDK client
namespace Sample;

require __DIR__ . '/vendor/autoload.php';
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;

require 'paypal-client.php';

$orderID = $_GET['orderID'];

class GetOrder
{

  // 2. Set up your server to receive a call from the client
  public static function getOrder($orderId)
  {

    // 3. Call PayPal to get the transaction details
    $client = PayPalClient::client();
    $response = $client->execute(new OrdersGetRequest($orderId));
	
	// 4. Specify which information you want from the transaction details. For example:
	$orderID = $response->result->id;
	$email = $response->result->payer->email_address;
	$name = $response->result->purchase_units[0]->shipping->name->full_name;
	$address = $response->result->purchase_units[0]->shipping->address;
		
	header("Location:../success");
  }
}

if (!count(debug_backtrace()))
{
  GetOrder::getOrder($orderID, true);
}
?>

The above code begins by importing the necessary tools from the PayPal software development kit (SDK). The PayPal SDK is a collection of files and instructions for communicating with PayPal and retrieving transaction details. We'll talk about how to set up the PayPal SDK on your server shortly.

In the GetOrder class, we have a function called getOrder that uses the PayPal SDK to retrieve the transaction details for a given order ID from PayPal. Section 4 contains a couple of examples of data you can retrieve from the transaction details (e.g. the order ID and the customer's email, name and shipping address). The full set of data can be printed using the command:

echo json_encode($response->result, JSON_PRETTY_PRINT);

An example of the output you may get is shown below and was generated by doing a test purchase on our demo store:

{
	"id": "39326472021936719",
	"intent": "CAPTURE",
	"purchase_units": [ {
		"reference_id": "default",
		"amount": {
			"currency_code": "GBP",
			"value": "4.30" },
		"payee": {
			"email_address": "sb-twcx41025811@business.example.com",
			"merchant_id": "QGDUJLLDDQQ9W" },
		"shipping": {
			"name": {
				"full_name": "John Doe" },
			"address": {
				"address_line_1": "Spitalfields Arts Market",
				"admin_area_2": "London",
				"admin_area_1": "London",
				"postal_code": "E1 6RL",
				"country_code": "GB" }
			},
		"payments": {
			"captures": [ {
				"id": "21993968KG659754L",
				"status": "COMPLETED",
				"amount": {
					"currency_code": "GBP",
					"value": "4.30" },
				"final_capture": true,
				"seller_protection": {
					"status": "ELIGIBLE",
					"dispute_categories": [ "ITEM_NOT_RECEIVED", "UNAUTHORIZED_TRANSACTION" ] },
				"seller_receivable_breakdown": {
					"gross_amount": {
						"currency_code": "GBP",
						"value": "4.30" },
					"paypal_fee": {
						"currency_code": "GBP",
						"value": "0.35" },
					"net_amount": {
						"currency_code": "GBP",
						"value": "3.95" }
					},
			"links": [ {
				"href": "https:\/\/api.sandbox.paypal.com\/v2\/payments\/captures\/21993968KG659754L",
				"rel": "self",
				"method": "GET" },
			{
				"href": "https:\/\/api.sandbox.paypal.com\/v2\/payments\/captures\/21993968KG659754L\/refund",
				"rel": "refund",
				"method": "POST" },
			{
				"href": "https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/39326472021936719",
				"rel": "up",
				"method": "GET" } ],
			"create_time": "2020-03-21T14:30:28Z",
			"update_time": "2020-03-21T14:30:28Z" } ]
			}
		} ],
	"payer": {
		"name": {
			"given_name": "John",
			"surname": "Doe" },
		"email_address": "sb-bd7ux1025210@personal.example.com",
		"payer_id": "7CD2GSDFCE4Y6",
		"address": {
			"country_code": "GB" }
		},
	"create_time": "2020-03-21T14:29:55Z",
	"update_time": "2020-03-21T14:30:28Z",
	"links": [ {
		"href": "https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/39326472021936719",
		"rel": "self",
		"method": "GET" } ],
	"status": "COMPLETED"
}

Once you have retrieved the data then you can redirect the customer to an order success/confirmation page using the header command. You can learn how to set up the order success page and other stuff such as how to save transaction details in an SQL database in our course on how to set up an online store.

Setting up the PayPal SDK

In this last section, we will discuss how to set up the PayPal SDK on your server. The PayPal SDK is a collection of files and tools you can use to communicate with PayPal's payments and orders API. Referring back to section 1 of the paypal-transaction-complete.php file, you will notice a line of code which reads:

require __DIR__ . '/vendor/autoload.php';

This 'require' statement imports the information from a file called autoload.php that is located within a subfolder called vendor. The autoload.php file launches the PayPal SDK and allows its tools to be utilised by the paypal-transaction-complete.php file. Let's download the vendor folder and put it in the appropriate location so the PayPal SDK can be used. PayPal's website describes a couple of methods for downloading/installing the SDK. One of the simplest ways is to install Composer on your computer then run the command:

composer require paypal/paypal-checkout-sdk 1.0.1

Windows users can run the above command using command prompt, Linux users should use the command line, and Mac users can use Terminal. Once the command has executed and all the files have downloaded, copy the vendor folder to the same folder as the paypal-transaction-complete.php file. Upload the vendor folder along with its contents to your server to allow your website to communicate with the PayPal SDK.

The only other thing we have to do is create a file called paypal-client.php which contains the details of your PayPal business account. You'll notice this file is imported by the paypal-transaction-complete.php file using a 'require' statement. The paypal-transaction-complete.php file uses the details from the paypal-client.php when communicating with PayPal to ensure the data requests are authorised. PayPal will only send over the transaction details if the order was made using the payment buttons associated with your business. Create a file called paypal-client.php, save it in the same folder as the paypal-transaction-complete.php file, and copy and paste the following code inside:

<?php
namespace Sample;

use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\ProductionEnvironment;

ini_set('error_reporting', E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');

class PayPalClient
{
    public static function client()
    {
        return new PayPalHttpClient(self::environment());
    }

    public static function environment()
    {
        $clientId = "CLIENT-ID";
        $clientSecret = "CLIENT-SECRET";
        return new ProductionEnvironment($clientId, $clientSecret);
    }
}

?>

The above code assumes your store is ready to go live. If you would like to test your store first then change any references to ProductionEnvironment to SandboxEnvironment. Also, you will need to set the values of the clientId and clientSecret variables to your sandbox/live credentials as appropriate. You can obtain these details by logging into your PayPal developer account and creating a sandbox or live app (sandbox apps are used for mock transactions while live apps transfer real money). PayPal has a lot of advice on their website about how to use the sandbox and live credentials; however, you may also like to check out our course on how to create an online store. The course contains step-by-step instructions on how to build an online store from scratch and integrate PayPal.

<<< Previous

Next >>>