PayPal Payment Gateway Integration in PHP using PayPal REST API

PayPal is one of the most trusted payment gateways on the Internet. It is widely used on websites to accept online payments. However, integrating the PayPal payment gateway into the application is not easy. PayPal API documentation is quite vast and hard to understand. A developer who is going to integrate the PayPal gateway for the first time will take long hours and effort to succeed in it. Fortunately, while researching this topic, I found a better way of integrating the PayPal payment gateway using PayPal REST API which we are going to discuss in this tutorial.

In order to achieve this goal, I’ll use the package called Omnipay. Omnipay provides a clean and easy way to integrate different payment gateway on your web application. Their code structure is clean and efficient. All you need to do is follow the Omnipay guidelines and pass your credentials. The package does the rest of the stuff for you.

Having said that, let’s start with PayPal gateway integration using PHP. The very first step is getting the PayPal API credentials.

Get PayPal Client ID and Client Secret

For PayPal integration in the website, you first need to create a REST API app on a PayPal developer account. Once you created the app, you will get the client id and client secret.

To create a REST API app, go to your PayPal developer account and log in to the dashboard.

In the dashboard, click on the menu Apps & Credentials. Then click on the Create App button.

create-app-on-paypal

In the next step, fill out the app name and you will get your client id and client secret. In my case, in the below screenshot, I can see sandbox credentials. It’s always recommended to test the payment first on sandbox and then switch to production mode.

paypal-rest-api-credentials

Copy these credentials. It will require in the next steps.

Library Installation and Basic Setup

As I said, I’ll use the Omnipay package for PayPal REST API integration. Install this library using the command below.

composer require league/omnipay omnipay/paypal

After installing the library, create a configuration file to store the API credentials, connect the database, and initialize the gateway.

config.php

<?php
require_once "vendor/autoload.php";

use Omnipay\Omnipay;

define('CLIENT_ID', 'PAYPAL_CLIENT_ID_HERE');
define('CLIENT_SECRET', 'PAYPAL_CLIENT_SECRET_HERE');

define('PAYPAL_RETURN_URL', 'YOUR_SITE_URL/success.php');
define('PAYPAL_CANCEL_URL', 'YOUR_SITE_URL/cancel.php');
define('PAYPAL_CURRENCY', 'USD'); // set your currency here

// Connect with the database
$db = new mysqli('DB_HOST', 'DB_USERNAME', 'DB_PASSWORD', 'DB_NAME'); 

if ($db->connect_errno) {
    die("Connect failed: ". $db->connect_error);
}

$gateway = Omnipay::create('PayPal_Rest');
$gateway->setClientId(CLIENT_ID);
$gateway->setSecret(CLIENT_SECRET);
$gateway->setTestMode(true); //set it to 'false' when go live

Here, I passed the ‘Paypal_Rest’ parameter to the create() method of Omnipay. It tells Omnipay to use PayPal REST API in the background to process the payment. For the constant PAYPAL_CURRENCY, I used the USD currency. Adjust this value as per your requirement. You should also pass the sandbox credentials to the constants CLIENT_ID and CLIENT_SECRET. Apart from it, replace the placeholders like YOUR_SITE_URL and MySQL database credentials.

Next, create the HTML form where a user can enter the amount. For demo purposes, I just keep one field in the form. Modify the form as per your requirement.

form.html

<form action="charge.php" method="post">
    <input type="text" name="amount" value="20.00" />
    <input type="submit" name="submit" value="Pay Now">
</form>

When the payment gets completed you should save the transaction details in the database table. Create a payments table using the below SQL statement.

CREATE TABLE `payments` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `payment_id` varchar(255) NOT NULL,
 `payer_id` varchar(255) NOT NULL,
 `payer_email` varchar(255) NOT NULL,
 `amount` float(10,2) NOT NULL,
 `currency` varchar(255) NOT NULL,
 `payment_status` varchar(255) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

I am not adding any foreign key to the payments table. Because it may differ as per the requirement. For instance, you can add a column user_id to relate the payment with the user.

PayPal Payment Gateway Integration in PHP

While making the payment through PayPal, the user will redirect to the PayPal website to complete the transaction. After following prompted steps by PayPal, the user will redirect back to the application based on success or failure status. You have defined these URLs in the config.php file.

Once, the user redirects back to the application with a successful response, it needs to execute the payment in the success.php file. After executing the payment, you can store the payment information to the database.

Create the below files in your project root directory.

  • charge.php : It collects the user inputs and forwards the customer to the PayPal website.
  • success.php : Execute payment as PayPal authorized the payment. Store transaction details in the database.
  • cancel.php : If the customer didn’t complete the payment, they will redirect to this page.

charge.php

<?php
require_once 'config.php';

if (isset($_POST['submit'])) {

    try {
        $response = $gateway->purchase(array(
            'amount' => $_POST['amount'],
            'currency' => PAYPAL_CURRENCY,
            'returnUrl' => PAYPAL_RETURN_URL,
            'cancelUrl' => PAYPAL_CANCEL_URL,
        ))->send();

        if ($response->isRedirect()) {
            $response->redirect(); // this will automatically forward the customer
        } else {
            // not successful
            echo $response->getMessage();
        }
    } catch(Exception $e) {
        echo $e->getMessage();
    }
}

success.php

<?php
require_once 'config.php';
 
// Once the transaction has been approved, we need to complete it.
if (array_key_exists('paymentId', $_GET) && array_key_exists('PayerID', $_GET)) {
    $transaction = $gateway->completePurchase(array(
        'payer_id'             => $_GET['PayerID'],
        'transactionReference' => $_GET['paymentId'],
    ));
    $response = $transaction->send();
 
    if ($response->isSuccessful()) {
        // The customer has successfully paid.
        $arr_body = $response->getData();
 
        $payment_id = $db->real_escape_string($arr_body['id']);
        $payer_id = $db->real_escape_string($arr_body['payer']['payer_info']['payer_id']);
        $payer_email = $db->real_escape_string($arr_body['payer']['payer_info']['email']);
        $amount = $db->real_escape_string($arr_body['transactions'][0]['amount']['total']);
        $currency = PAYPAL_CURRENCY;
        $payment_status = $db->real_escape_string($arr_body['state']);
 
        $sql = sprintf("INSERT INTO payments(payment_id, payer_id, payer_email, amount, currency, payment_status) VALUES('%s', '%s', '%s', '%s', '%s', '%s')", $payment_id, $payer_id, $payer_email, $amount, $currency, $payment_status);
        $db->query($sql);
 
        echo "Payment is successful. Your transaction id is: ". $payment_id;
    } else {
        echo $response->getMessage();
    }
} else {
    echo 'Transaction is declined';
}

cancel.php

<h3>User cancelled the payment.</h3>

Test Payment in Sandbox Mode

You are done with the programming part of the tutorial. The next part is testing the payments with dummy cards. Visit this link to generate your dummy credit card. These card details can use while testing the payment with PayPal sandbox mode.

Make Payment Live

Once you’re done with sandbox testing, you can make your payments live for the customers. For this, you need to pass your live credentials to the PHP constants – CLIENT_ID and CLIENT_SECRET. In addition to this, set the false value to the setTestMode() method.

$gateway->setTestMode(false);

Send Product Information to PayPal

In the above code, you are sending the amount to pay on PayPal. You may also want to send product information. Your customers can see these product details on the payment page before making a payment.

To send the product information, you need to pass the ‘items’ array to the purchase method as follows.

$response = $gateway->purchase(array(
    'amount' => $_POST['amount'],
    'items' => array(
        array(
            'name' => 'Course Subscription',
            'price' => $_POST['amount'],
            'description' => 'Get access to premium courses.',
            'quantity' => 1
        ),
    ),
    'currency' => PAYPAL_CURRENCY,
    'returnUrl' => PAYPAL_RETURN_URL,
    'cancelUrl' => PAYPAL_CANCEL_URL,
))->send();

Here I have passed the product details statically. You should make it dynamic depending on your product.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

5 thoughts on “PayPal Payment Gateway Integration in PHP using PayPal REST API

  1. Hi,

    Please note that currently, composer has some errors in installation of the Omnipay. After following instructions step-by-step, resulting error is that autoload.php is not found.

    vendor folder has a subfolder /guzzlehttp, no other files.

    Error:

    Warning: require_once(vendor/autoload.php): Failed to open stream: No such file or directory in C:\xampp\htdocs\paypal_v2\config.php on line 3

    Fatal error: Uncaught Error: Failed opening required ‘vendor/autoload.php’ (include_path=’C:\xampp\php\PEAR’)

  2. Fatal Error: Uncaught Omnipay\Common\Exception\RuntimeException: Class ‘\Omnipay\Paypal\RestGateway’ not found

Leave a Reply

Your email address will not be published. Required fields are marked *