Your Guide to Laravel Excellence

How to Build a PayPal Payment Gateway API in Laravel 11

How to Build a PayPal Payment Gateway API in Laravel 11

In this article, we will guide you through adding PayPal payment features to your Laravel application. We will start by setting up a PayPal service to connect your app with PayPal’s payment system, including configuring settings and obtaining the necessary credentials. Then, we will walk you through the process of creating PayPal orders, allowing users to make payments through your app.

Integrating PayPal payment functionality into your Laravel application will the users a secure payment platform.

PayPal in Laravel 11

PayPal is a popular payment platform that enables businesses to accept payments online securely. Laravel, a powerful PHP framework, provides a environment to integrate PayPal's API for handling transactions. We will demonstrates how to set up PayPal integration using Laravel, including essential functionalities like creating and capturing orders. For a successful PayPal integration follow the following steps:

Secure Your API Credentials

Make sure that your PayPal API credentials (Client ID and Secret) are stored securely. Use Laravel’s configuration and environment files to keep these credentials safe and do not hardcode them into your application code. For example, place your credentials in the .env file:


PAYPAL_CLIENT_ID=Ad00N2ApuCT7LnIBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdkDvR7-7cHl6Rh5KW
PAYPAL_SECRET=EOb2IEoaPrIr4cQxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7QnIRS1593z08RujCP
PAYPAL_MODE=sandbox
PAYPAL_SANDBOX_URL="https://api-m.sandbox.paypal.com"
PAYPAL_LIVE_URL="https://api-m.paypal.com"

And retrieve them in your config/services.php:


'paypal' => [
    'client_id' => env('PAYPAL_CLIENT_ID'),
    'secret' => env('PAYPAL_SECRET'),
    'api_sandbox_url' => env('PAYPAL_SANDBOX_URL', 'sandbox'),
    'api_live_url' => env('PAYPAL_LIVE_URL', 'live'),
]

Setting Up the PayPal Service

We will create a PayPalService class to handle communication with PayPal's API. This class will include methods to obtain an authentication token, create orders, and capture payments.

Here’s how to define the PayPalService class:

<?php
namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class PayPalService
{

    private $apiUrl;
    private $clientId;
    private $clientSecret;

    public function __construct()
    {

        $this->apiUrl = config('services.paypal.mode') === 'sandbox'
            ?  config('services.paypal.api_sandbox_url')
            :  config('services.paypal.api_live_url');

        $this->clientId = config('services.paypal.client_id');
        $this->clientSecret = config('services.paypal.secret');
    }


    private function getAuthToken()
    {
        $response = Http::asForm()
            ->withHeaders([
                'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret),
                'Content-Type' => 'application/x-www-form-urlencoded',
            ])
            ->post($this->apiUrl . '/v1/oauth2/token', [
                'grant_type' => 'client_credentials'
            ]);
        if ($response->failed()) {
            throw new \Exception('Failed to obtain PayPal access token');
        }
        return $response->json('access_token');
    }


    public function createOrder($amount)
    {

        $token = $this->getAuthToken();
        $response = Http::withToken($token)
            ->post("{$this->apiUrl}/v2/checkout/orders", [
                'intent' => 'CAPTURE',
                'purchase_units' => [
                    [
                        'amount' => [
                            'currency_code' => 'USD',
                            'value' => $amount,
                        ],
                    ],
                ],
                'application_context' => [
                    'return_url' => route('paypal.return'),
                    'cancel_url' => route('paypal.cancel'),
                ],
            ]);
        if ($response->failed()) {
            throw new \Exception('Failed to create PayPal order');
        }
        return $response->json();
    }


    public function captureOrder($orderId)
    {
        $token = $this->getAuthToken();
        $response = Http::withToken($token)
            ->post("{$this->apiUrl}/v2/checkout/orders/{$orderId}/capture", [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'PayPal-Request-Id' => uniqid(), // Optionally use a unique ID for idempotency
                ],
            ]);
        if ($response->failed()) {
            throw new \Exception('Failed to capture PayPal order: ' . $response->body());
        }
        return $response->json();
    }
}

Setting up Routes

We will need to set up the following routes in our Laravel application to handle PayPal transactions:

Route::post('paypal/create-order', [PaypalController::class, 'createOrder']);
Route::get('paypal/return', [PaypalController::class, 'handleReturn'])->name('paypal.return');
Route::get('paypal/cancel', [PaypalController::class, 'handleCancel'])->name('paypal.cancel');

Creating the PaypalPaymentController

The PaypalPaymentController manages order creation and handles return and cancellation scenarios. Here the code for the Paypal Payment Controller:

<?php
namespace App\Http\Controllers;

use App\Services\PayPalService;
use Illuminate\Http\Request;

class PaypalController extends Controller
{

    protected $paypal;
    public function __construct(PayPalService $paypal)
    {
        $this->paypal = $paypal;
    }

    public function createOrder(Request $request)
    {

        $amount = $request->input('amount');
        $response = $this->paypal->createOrder($amount);
        return response()->json([
            'order_id' => $response['id'],
            'status' => $response['status'],
            'links' => $response['links'],
        ]);
    }


    public function handleReturn(Request $request)
    {
       
        // Show success message here or Capture Payment

        $orderId = $request->query('token');
        try {
            $order = $this->paypal->captureOrder($orderId);
            return response()->json(['status' => 'Payment completed successfully', 'order' => $order]);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }


    public function handleCancel()
    {
        return response()->json(['status' => 'Payment cancelled']);
    }
}

Explanation

createOrder(): Will Creates a PayPal order and returns the necessary details.

handleReturn(): Will Capture the order when the user is redirected back to the site after payment.

handleCancel(): Will Handlethe scenarios where the user cancels the payment process.

By following the steps given above, you can integrate PayPal payments into your Laravel application. This will allow you to create and capture orders, providing a good transaction experience for your users. Always ensure you test thoroughly in PayPal's sandbox environment before moving to forward.

After clicking on Approve Link , you will redirected to paypal and it will asks you for login.

Recommeded Posts

Better Error Handling with onFailure Callback in Laravel's DB::transaction() (New in Laravel 12.9)

Better Error Handling with onFailure Callback in Laravel's DB::transaction() (New in Laravel 12.9)

Laravel 12.9 now supports onFailureCallback in DB::transaction(), making database error handling easier with automatic rollback and failure notifications.

1 month ago Read article →
Querying JSON Columns in Laravel 11 Using `whereJsonContains`

Querying JSON Columns in Laravel 11 Using `whereJsonContains`

Querying JSON Columns in Laravel 11 Using `whereJsonContains`

1 month ago Read article →
How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

1 month ago Read article →
Get Started with Bootstrap 5 in Laravel 11: A Step-by-Step Guide

Get Started with Bootstrap 5 in Laravel 11: A Step-by-Step Guide

Get Started with Bootstrap 5 in Laravel 11: A Step-by-Step Guide

1 month ago Read article →