Looking to hire Laravel developers? Try LaraJobs

laravel maintained by qattapay

Description
Official QattaPay Laravel SDK — group contribution checkout for your storefront
Last update
2026/08/12 16:43 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

QattaPay Laravel SDK

Official QattaPay SDK for Laravel — add group contribution checkout to any storefront.

composer require qattapay/laravel

QattaPay lets groups of people split the cost of a purchase. This package handles:

  • Server-side: creating checkout intents and managing orders with your merchant API key
  • Webhooks: verifying and parsing events when a session is funded
  • Blade: official branded checkout buttons (via the @hadawi/sdk browser bundle)

Parity with the Node SDK @hadawi/sdk.


Requirements

  • PHP 8.2+
  • Laravel 10, 11, or 12

Installation

composer require qattapay/laravel

The service provider and QattaPay facade are auto-discovered.

Publish the config (optional):

php artisan vendor:publish --tag=qattapay-config

Configuration

Add to your .env:

QATTAPAY_API_KEY=your_api_key
QATTAPAY_WEBHOOK_SECRET=whsec_...
QATTAPAY_MODE=dev
# QATTAPAY_BASE_URL=http://localhost:4000   # optional local override
# QATTAPAY_BROWSER_SDK_VERSION=1.1.6        # jsDelivr pin for the button
Key Description
api_key Merchant API key from the QattaPay dashboard
webhook_secret whsec_… signing secret (Developer → Webhook)
mode dev or live (ignored if base_url is set)
base_url Explicit API base (e.g. local) — disables host fallback
browser_sdk_version @hadawi/sdk version loaded for <x-qattapay-button>

Amounts are always integers in the smallest currency unit (halalas for SAR — e.g. 15000 = 150.00 SAR).


Quick start

1 — Create an intent (server)

use QattaPay\Laravel\Facades\QattaPay;

Route::post('/qattapay/intent', function () {
    $result = QattaPay::intents()->create([
        'itemSnapshot' => [
            [
                'name' => 'Luxury Watch',
                'price' => 150000,
                'reference' => 'watch-001',
            ],
        ],
        'totalAmount' => 150000,
        'currency' => 'SAR',
        'metadata' => ['cart_id' => 'abc'],
    ]);

    return [
        'intentId' => $result['intent']['id'],
    ];
})->middleware('web')->name('qattapay.intent');

2 — Mount the branded button (Blade)

{{-- Popup: success-url runs after qattapay:success postMessage --}}
<x-qattapay-button
    intent-url="{{ route('qattapay.intent') }}"
    mode="{{ config('qattapay.mode') }}"
    variant="primary"
    label="split"
    open-mode="popup"
    success-url="{{ url('/thank-you') }}"
    return-url="{{ url('/thank-you') }}"
/>
{{-- Redirect: hosted checkout sends the shopper back to return-url --}}
<x-qattapay-button
    intent-url="{{ route('qattapay.intent') }}"
    mode="{{ config('qattapay.mode') }}"
    variant="primary"
    label="split"
    open-mode="redirect"
    return-url="{{ url('/thank-you') }}"
/>
Attribute Purpose
success-url After popup onSuccess (qattapay:success), navigate here
return-url Passed to hosted checkout as ?returnUrl=. After payment, QattaPay redirects here with intentId, sessionId, and status=success|cancel|failed. Use for redirect mode (and as a popup fallback).
open-mode popup (default) or redirect

Ensure your layout includes the CSRF meta tag:

<meta name="csrf-token" content="{{ csrf_token() }}">

3 — Handle webhooks

use Illuminate\Http\Request;
use QattaPay\Laravel\Facades\QattaPay;

Route::post('/webhooks/qattapay', function (Request $request) {
    $event = $request->attributes->get('qattapay_event');

    if ($event['type'] === 'order.funded') {
        $orderId = $event['payload']['order_id'] ?? null;
        if ($orderId) {
            QattaPay::orders()->fulfill($orderId);
        }
    }

    return response()->noContent();
})->middleware('qattapay.webhook');

API reference

Intents

QattaPay::intents()->create([/* ... */]);
QattaPay::intents()->get($intentId);

Orders

QattaPay::orders()->list();
QattaPay::orders()->get($orderId);
QattaPay::orders()->fulfill($orderId);
QattaPay::orders()->deliver($orderId);

Webhooks

QattaPay::webhooks()->verifySignature($rawBody, $signature);
QattaPay::webhooks()->constructEvent($rawBody, $signature);

Event types: order.funded, order.partially_funded, order.cancelled, order.expired.


Host resolution

Mode Primary Fallback (network errors only)
dev https://dev.qatta.sa/api https://dev.hadawi.sa/api
live https://qatta.sa/api https://beta.hadawi.sa/api

Development

composer install
composer test

Publishing

Package: packagist.org/packages/qattapay/laravel
Latest release: v1.0.1

To ship a new version, bump the changelog, push main, then tag:

git tag v1.0.2
git push origin v1.0.2

Packagist updates automatically via the GitHub webhook. Full checklist: PUBLISHING.md.


License

MIT © Hadawi Engineering