Handling Webhook for PayPal REST API on eCommerce Platforms

This is the continuation article for the previous article about PayPal REST API integration with PHP apps.

This article assumes that you have completed a full-fledged PayPal integration using the library explained in the previous article.

Please Read: How to Integrate PayPal REST API for Online Payments

Let's begin by adding the route needed to access the web app with a POST request from the PayPal webhook service.

/**
 * PayPal REST API Webhook
 */
Route::post('/checkout/webhook/paypal/rest', [
    'as' => 'checkout.webhook.paypal.rest',
    'name' => 'PayPal Rest Webhook',
    'uses' => 'App\Controllers\Webhook\PayPalRestController@validate',
]);

 

Now, let's set up a controller that can accept the HTTP request from the PayPal webhook service. This controller will handle both the headers data and the payload.

<?php

namespace App\Controllers\Webhook;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Event;

/**
 * Class PayPalRestController
 * @package App\Controllers\Webhook
 */
class PayPalRestController extends Controller
{
    /**
     * @param Request $request
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * @return \Illuminate\Http\Response
     */
    public function validate()
    {
        $data = $this->request->all();

        $headers = $this->request->headers->all();

        $event_type = $data['event_type'] ?? null;

        $verify_payload = [
            'auth_algo' => $this->request->headers->get('PAYPAL-AUTH-ALGO'),
            'cert_url' => $this->request->headers->get('PAYPAL-CERT-URL'),
            'transmission_id' => $this->request->headers->get('PAYPAL-TRANSMISSION-ID'),
            'transmission_sig' => $this->request->headers->get('PAYPAL-TRANSMISSION-SIG'),
            'transmission_time' => $this->request->headers->get('PAYPAL-TRANSMISSION-TIME'),
            'webhook_id' => 'REPLACE-WITH-YOUR-OWN',
            'webhook_event' => $data,
        ];

        $gateway = Omnipay::create('PayPalRest_Rest');

        $gateway->setClientId('xxxxxxxxxxxxxx');
        $gateway->setSecret('xxxxxxxxxxxxxx');
        $gateway->setTestMode(true);

        $response = $gateway->verifyWebhookSignature($verify_payload);

        if ($response->isSuccessful()) {
            // webhook verified by PayPal
            // handle the webhook event as necessary
            
            return \Response::make(null);
        }

        // verification failed.
    }
}

 

It's important to verify the webhook request sent by PayPal to confirm that the PayPal data hasn't been altered and that the request itself originates from PayPal.

Once it's verified, you can proceed to handle the event types that you've subscribed to under the webhook links added to the PayPal dashboard, associated with the credentials of your PayPal apps.

If you are managing webhook records through the API, it's essential to use the corresponding webhook ID for verifying the webhook signatures. For manual handling, you should provide the webhook ID generated in the PayPal dashboard and pass it into the provided codebase above.

Closing

Thank you for reading the article all the way to the end. Please share it within your circle, and continue visiting our website for more articles in the future.