PayPal Payments Pro Integration in Laravel

I have written an article accept credit card payments using PayPal Payments Pro in PHP. One of the readers asked me how to do the same integration in Laravel. Though Laravel is written in PHP while writing code for Laravel you have to follow their standards. Beginners often find it difficult to convert plain PHP code in Laravel.

In this article, we study how to integrate PayPal Payments Pro and accept credit card payments in Laravel.

If you are running an online store, membership site, or something else where you want to collect online payments then PayPal is the secure option. Using PayPal Payments Pro you can accept online credit card payments that go directly into your PayPal account.

Keep a note at the time of writing this article, PayPal Payments Pro is available for the merchants in the US, UK, and Canada.

Getting Started

In order to get started, you need to get the PayPal API credentials. It’s always a good practice to test the payments in sandbox mode. If everything works as expected then make the payment live.

Get your sandbox credentials by login to the PayPal Developer account. After login, go to SANDBOX->Accounts from the left side menu and create a business account.

Once you have the business account, upgrade your account type to ‘Business-Pro’. PayPal Payments Pro integration requires a ‘Business-Pro’ account type. Click on the ‘Upgrade to Pro’ link and PayPal will convert your account type to ‘Business-Pro’.

Business Pro

Next, click on the ‘API Credentials’ tab and copy your credentials.

Credentials

Open the .env of your Laravel project and add the copied credentials in it.

PAYPAL_API_USERNAME=
PAYPAL_API_PASSWORD=
PAYPAL_API_SIGNATURE=

Add the route for the controller in the web.php file. In my case, my route is as follows.

Route::resource('payment', 'PaymentController');

I am going to use the Omnipay library which provides an easy way to integrate payment gateways. Run the below command which installs the Omnipay library.

composer require league/omnipay:^3 omnipay/paypal

Create a Payment Form

While accepting a credit card payment, you have to give users a form where they can enter their card details. Let’s design the payment form using this codepen example.

Create a ‘css’ and ‘js’ folder inside the ‘public’ directory of the Laravel project. Copy the CSS code from codepen and add it in css/card.css.

@import url(https://fonts.googleapis.com/css?family=Roboto:400,900,700,500);

body {
  padding: 60px 0;
  background-color: rgba(178,209,229,0.7);
  margin: 0 auto;
  width: 600px;
}
.body-text {
  padding: 0 20px 30px 20px;
  font-family: "Roboto";
  font-size: 1em;
  color: #333;
  text-align: center;
  line-height: 1.2em;
}
.form-container {
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.card-wrapper {
  background-color: #6FB7E9;
  width: 100%;
  display: flex;

}
.personal-information {
  background-color: #3C8DC5;
  color: #fff;
  padding: 1px 0;
  text-align: center;
}
h1 {
  font-size: 1.3em;
  font-family: "Roboto"
}
input {
  margin: 1px 0;
  padding-left: 3%;
  font-size: 14px;
}
input[type="text"]{
  display: block;
  height: 50px;
  width: 97%;
  border: none;
}
input[type="email"]{
  display: block;
  height: 50px;
  width: 97%;
  border: none;
}
input[type="submit"]{
  display: block;
  height: 60px;
  width: 100%;
  border: none;
  background-color: #3C8DC5;
  color: #fff;
  margin-top: 2px;
  curson: pointer;
  font-size: 0.9em;
  text-transform: uppercase;
  font-weight: bold;
  cursor: pointer;
}
input[type="submit"]:hover{
  background-color: #6FB7E9;
  transition: 0.3s ease;
}
#column-left {
  width: 46.8%;
  float: left;
  margin-bottom: 2px;
}
#column-right {
  width: 46.8%;
  float: right;
}

@media only screen and (max-width: 480px){
  body {
    width: 100%;
    margin: 0 auto;
  }
  .form-container {
    margin: 0 2%;
  }
  input {
    font-size: 1em;
  }
  #input-button {
    width: 100%;
  }
  #input-field {
    width: 96.5%;
  }
  h1 {
    font-size: 1.2em;
  }
  input {
    margin: 2px 0;
  }
  input[type="submit"]{
    height: 50px;
  }
  #column-left {
    width: 96.5%;
    display: block;
    float: none;
  }
  #column-right {
    width: 96.5%;
    display: block;
    float: none;
  }
}

Similarly, add JavaScript code from codepen into the js/card.js file.

$('form').card({
    container: '.card-wrapper',
    width: 280,

    formSelectors: {
        nameInput: 'input[name="first-name"], input[name="last-name"]'
    }
});

Get a copy of jquery.card.js from this GitHub repository. Store this file under your ‘js’ directory.

Finally, in the blade file add the code below.

<link rel="stylesheet" href="{{ asset('css/card.css') }}">

<form method="POST" action="{{ url('ROUTE_HERE') }}">
    {{ csrf_field() }}
    <div class="form-container">
        <div class="personal-information">
            <h1>Payment Information</h1>
        </div> <!-- end of personal-information -->
         
        <input id="column-left" type="text" name="first-name" placeholder="First Name" required="required" />
        <input id="column-right" type="text" name="last-name" placeholder="Surname" required="required" />
        <input id="input-field" type="text" name="number" placeholder="Card Number" required="required" />
        <input id="column-left" type="text" name="expiry" placeholder="MM / YY" required="required" />
        <input id="column-right" type="text" name="cvc" placeholder="CCV" required="required" />

        <div class="card-wrapper"></div>

        <input id="input-field" type="text" name="streetaddress" required="required" autocomplete="on" maxlength="45" placeholder="Streed Address"/>
        <input id="column-left" type="text" name="city" required="required" autocomplete="on" maxlength="20" placeholder="City"/>
        <input id="column-right" type="text" name="zipcode" required="required" autocomplete="on" pattern="[0-9]*" maxlength="5" placeholder="ZIP code"/>
        <input id="input-field" type="email" name="email" required="required" autocomplete="on" maxlength="40" placeholder="Email"/>
        <input id="input-field" type="text" name="amount" required="required" autocomplete="on" maxlength="40" placeholder="Amount"/>
        <input id="input-button" name="submit" type="submit" value="Submit"/>
    </div>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="{{ asset('js/jquery.card.js') }}"></script>
<script src="{{ asset('js/card.js') }}"></script>

In the above code, I included CSS, JS from the respective directory. You have to give your route URL to the form action.

PayPal Payments Pro integration in Laravel

We are done with the setup required to accept credit card payments. Now in the controller, we have to write code as instructed by Omnipay. Omnipay makes the developer’s life easy. We have to just follow their instructions and they do all the hard work of capturing payment and returning a final response.

PaymentController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Omnipay\Omnipay;

class PaymentController extends Controller
{

    public $gateway;

    public function __construct()
    {
        $this->gateway = Omnipay::create('PayPal_Pro');
        $this->gateway->setUsername(env('PAYPAL_API_USERNAME'));
        $this->gateway->setPassword(env('PAYPAL_API_PASSWORD'));
        $this->gateway->setSignature(env('PAYPAL_API_SIGNATURE'));
        $this->gateway->setTestMode(true); // here 'true' is for sandbox. Pass 'false' when go live
    }

    public function index()
    {
        return view('payment');
    }

    public function store(Request $request)
    {
        $arr_expiry = explode("/", $request->input('expiry'));
 
        $formData = array(
            'firstName' => $request->input('first-name'),
            'lastName' => $request->input('last-name'),
            'number' => $request->input('number'),
            'expiryMonth' => trim($arr_expiry[0]),
            'expiryYear' => trim($arr_expiry[1]),
            'cvv' => $request->input('cvc')
        );

        try {
            // Send purchase request
            $response = $this->gateway->purchase([
                'amount' => $request->input('amount'),
                'currency' => 'USD',
                'card' => $formData
            ])->send();

            // Process response
            if ($response->isSuccessful()) {

                // Payment was successful
                $arr_body = $response->getData();
                $amount = $arr_body['AMT'];
                $currency = $arr_body['CURRENCYCODE'];
                $transaction_id = $arr_body['TRANSACTIONID'];

                echo "Payment of $amount $currency is successful. Your Transaction ID is: $transaction_id";
            } else {
                // Payment failed
                echo "Payment failed. ". $response->getMessage();
            }
        } catch(Exception $e) {
            echo $e->getMessage();
        }
    }
}

Here in the constructor we build an object and pass the credentials to it. When a user submits a form, control goes to the ‘store’ method. In this method, Omnipay calls the PayPal API in the background, processes the payment, and gives a final response.

Go ahead and give a try for it. As we are testing payment in sandbox mode, you will need test cards. Click here to get dummy credit card details. After submitting a form, You should see the success message along with your transaction id.

Accept Live Payment with PayPal Payments Pro

Once your payments are working successfully in the sandbox mode, you can go for live mode. For this, you need to replace sandbox credentials with the live details in the .env file. Also, pass a ‘false’ value to the setTestMode() method in the constructor. It will disable the sandbox mode and activate the live mode.

It’s all about accepting credit card payment with PayPal Payments Pro in Laravel. I would like to hear your thoughts and suggestions in the comment section below.

Related Articles

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

2 thoughts on “PayPal Payments Pro Integration in Laravel

  1. This article is really good, thank you very much.. But I have some question..
    I am from Europe and I do not have option to upgrade account to pro Business..
    So my question is, can I make new account and select that I come from USA, but to left empty fields where is credic card (because I want to do this just for testing).. Will it work?
    Thanks in advance, I would really appreciate, if you would set aside time to answer on my question..

Leave a Reply

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