PHP code example of mlquarizm / payment-gateway

1. Go to this page and download the library: Download mlquarizm/payment-gateway library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mlquarizm / payment-gateway example snippets




namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array<int, string>
     */
    protected $except = [
        'payment/callback/*',    // Payment callbacks
        'webhooks/payment/*',    // Payment webhooks
    ];
}

return [
    // Default payment gateway to use when not specified
    'default_gateway' => env('PAYMENT_DEFAULT_GATEWAY', 'tabby'),

    // Fallback URL when gateway-specific redirect_*_url are not set (callback appends ?status=...&gateway=...)
    'redirect_fallback_url' => env('PAYMENT_REDIRECT_FALLBACK_URL', ''),

    // URL the user is sent to after the package status Blade (success/error/cancel). Use {order_id} placeholder; replaced by payable_id (e.g. order id).
    'redirect_after_status_url' => env('PAYMENT_REDIRECT_AFTER_STATUS_URL', ''),

    // When redirect_after_status_url is empty, Blade redirects here after 5s. Use a public URL (e.g. dashboard); avoid auth/login.
    'redirect_after_status_fallback_url' => env('PAYMENT_REDIRECT_AFTER_STATUS_FALLBACK_URL', ''),

    // Callbacks configuration for payment events
    'callbacks' => [
        'tabby' => [
            'on_success' => null, // Callable: fn($transaction) => void
            'on_failure' => null, // Callable: fn($transaction, $reason) => void
        ],
        'tamara' => [
            'on_success' => null, // Callable: fn($transaction) => void
            'on_failure' => null, // Callable: fn($transaction, $reason) => void
        ],
    ],

    // Payment transaction configuration
    'transaction' => [
        'table' => 'payment_transactions', // Database table name
        'polymorphic' => true, // Enable polymorphic relationships
    ],
];

return [
    // Enable/disable sandbox mode (true for testing, false for production)
    'sandbox_mode' => env('TABBY_SANDBOX_MODE', true),

    // Tabby API credentials
    'secret_key' => env('TABBY_SECRET_KEY', ''),
    'public_key' => env('TABBY_PUBLIC_KEY', ''),
    'merchant_code' => env('TABBY_MERCHANT_CODE', ''),

    // Callback URLs (where Tabby redirects after payment)
    'success_url' => env('TABBY_SUCCESS_URL', ''),
    'failure_url' => env('TABBY_FAILURE_URL', ''),
    'cancel_url' => env('TABBY_CANCEL_URL', ''),

    // Redirect URLs (where to redirect user after processing callback)
    'redirect_success_url' => env('TABBY_REDIRECT_SUCCESS_URL', ''),
    'redirect_error_url' => env('TABBY_REDIRECT_FAILURE_URL', ''),
    'redirect_cancel_url' => env('TABBY_REDIRECT_CANCEL_URL', ''),

    // Currency code (default: SAR)
    'currency' => env('TABBY_CURRENCY', 'SAR'),
];

return [
    // Enable/disable sandbox mode (true for testing, false for production)
    'sandbox_mode' => env('TAMARA_SANDBOX_MODE', true),

    // Tamara API credentials
    'api_token' => env('TAMARA_API_TOKEN', ''),
    'notification_token' => env('TAMARA_NOTIFICATION_TOKEN', ''),
    'webhook_token' => env('TAMARA_WEBHOOK_TOKEN', ''),
    'public_key' => env('TAMARA_PUBLIC_KEY', ''),

    // Callback URLs (where Tamara redirects after payment)
    'success_url' => env('TAMARA_SUCCESS_URL', ''),
    'failure_url' => env('TAMARA_FAILURE_URL', ''),
    'cancel_url' => env('TAMARA_CANCEL_URL', ''),

    // Redirect URLs (where to redirect user after processing callback)
    'redirect_success_url' => env('TAMARA_REDIRECT_SUCCESS_URL', ''),
    'redirect_error_url' => env('TAMARA_REDIRECT_FAILURE_URL', ''),
    'redirect_cancel_url' => env('TAMARA_REDIRECT_CANCEL_URL', ''),

    // Payment options
    'default_payment_type' => env('TAMARA_DEFAULT_PAYMENT_TYPE', 'PAY_BY_INSTALMENTS'),
    'default_instalments' => env('TAMARA_DEFAULT_INSTALMENTS', 3),

    // Localization
    'currency' => env('TAMARA_CURRENCY', 'SAR'),
    'country_code' => env('TAMARA_COUNTRY_CODE', 'SA'),
    'locale' => env('TAMARA_LOCALE', 'ar_SA'),
];

use MLQuarizm\PaymentGateway\Factory\PaymentGatewayFactory;
use MLQuarizm\PaymentGateway\DTOs\TabbyPaymentDTO;
use MLQuarizm\PaymentGateway\DTOs\PaymentOrderDTO;
use MLQuarizm\PaymentGateway\DTOs\BuyerDTO;
use MLQuarizm\PaymentGateway\DTOs\BuyerHistoryDTO;
use MLQuarizm\PaymentGateway\DTOs\AddressDTO;
use MLQuarizm\PaymentGateway\DTOs\OrderItemDTO;

// Build DTOs
$orderDTO = new PaymentOrderDTO(
    id: $order->id,
    referenceId: (string) $order->id,
    amount: 500.00,
    currency: 'SAR',
    description: "Order #{$order->id}"
);

$buyerDTO = new BuyerDTO(
    name: $client->name,
    email: $client->email,   // optional (nullable)
    phone: $client->full_phone // optional (nullable)
);

$addressDTO = new AddressDTO(
    city: $order->city->name,
    address: $order->address,
    zip: $order->postal_code,
    countryCode: 'SA'
);

$itemDTO = new OrderItemDTO(
    referenceId: "service-{$order->service->id}",
    title: $order->service->name,
    description: $order->service->description,
    quantity: 1,
    unitPrice: 500.00
);

$buyerHistoryDTO = new BuyerHistoryDTO(
    registeredSince: $client->created_at->toISOString(),
    loyaltyLevel: 12,
    isPhoneVerified: true,
    isEmailVerified: (bool) $client->email_verified_at
);

$tabbyDTO = new TabbyPaymentDTO(
    order: $orderDTO,
    buyer: $buyerDTO,
    shippingAddress: $addressDTO,    // optional (nullable)
    items: [$itemDTO],
    buyerHistory: $buyerHistoryDTO,  // 

$paymentInfo = $gateway->initiatePayment($tabbyDTO);

if (!$paymentInfo[‘success’]) {
    // Session was rejected by Tabby’s pre-scoring
    return back()->withErrors([‘payment’ => $paymentInfo[‘message’]]);
}

// Only record transaction and redirect if session was created successfully
PaymentGateway::recordTransaction(...);
return redirect($paymentInfo[‘url’]);

[
    ‘url’ => null,
    ‘session_id’ => null,
    ‘payment_id’ => null,
    ‘success’ => false,
    ‘message’ => ‘Sorry, Tabby is unable to approve this purchase. Please use an alternative payment method for your order.’,
    ‘rejection_reason’ => ‘not_available’,        // or ‘order_amount_too_high’, ‘order_amount_too_low’
    ‘rejection_reason_code’ => ‘...’,              // Tabby internal code (nullable)
    ‘status’ => ‘rejected’,
]

use MLQuarizm\PaymentGateway\Builders\TabbyPaymentDTOBuilder;
use MLQuarizm\PaymentGateway\Factory\PaymentGatewayFactory;

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(
        id: $order->id,
        referenceId: (string) $order->id,
        amount: 500.00,
        currency: 'SAR',
        description: "Order #{$order->id}"
    )
    ->buyer(
        name: $client->name,
        email: $client->email,
        phone: $client->full_phone
    )
    ->shippingAddress(
        city: $order->city->name,
        address: $order->address,
        zip: $order->postal_code,
        countryCode: 'SA'
    )
    ->orderHistory([
        [
            'purchased_at' => $previousOrder->created_at->toISOString(),
            'amount' => '350.00',
            'status' => 'new',
            'buyer' => [
                'name' => $client->name,
                'email' => $client->email,
                'phone' => $client->full_phone,
            ],
            'shipping_address' => [
                'city' => $previousOrder->city->name,
                'address' => $previousOrder->address,
                'zip' => $previousOrder->postal_code,
            ],
            'payment_method' => $previousOrder->payment_method,
            'items' => [
                [
                    'reference_id' => "service-{$previousOrder->service->id}",
                    'title' => $previousOrder->service->name,
                    'description' => $previousOrder->service->description ?? '',
                    'quantity' => 1,
                    'unit_price' => '350.00',
                    'discount_amount' => '0.00',
                    'category' => 'Building inspection',
                ],
            ],
        ],
    ])
    ->buyerHistory(
        registeredSince: $client->created_at->toISOString(),
        loyaltyLevel: 12,
        isPhoneVerified: true,
        isEmailVerified: (bool) $client->email_verified_at,
    )
    ->item(
        referenceId: "service-{$order->service->id}",
        title: $order->service->name,
        description: $order->service->description,
        quantity: 1,
        unitPrice: 500.00
    )
    ->build();

$factory = new PaymentGatewayFactory();
$gateway = $factory->make('tabby');
$paymentInfo = $gateway->initiatePayment($tabbyDTO);

// Always check for rejection before redirecting (see "Handling Tabby Pre-scoring Rejection" below)
if (!$paymentInfo['success']) {
    return back()->withErrors(['payment' => $paymentInfo['message']]);
}

use MLQuarizm\PaymentGateway\DTOs\OrderHistoryDTO;
use MLQuarizm\PaymentGateway\DTOs\BuyerDTO;
use MLQuarizm\PaymentGateway\DTOs\AddressDTO;
use MLQuarizm\PaymentGateway\DTOs\OrderItemDTO;

$orderHistoryItems = [
    new OrderHistoryDTO(
        purchasedAt: $previousOrder->created_at->toISOString(),
        amount: '350.00',
        status: 'new',
        buyer: new BuyerDTO(
            name: $client->name,
            email: $client->email,
            phone: $client->full_phone,
        ),
        shippingAddress: new AddressDTO(
            city: $previousOrder->city->name,
            address: $previousOrder->address,
            zip: $previousOrder->postal_code,
        ),
        paymentMethod: 'credit_card',
        items: [
            new OrderItemDTO(
                referenceId: "service-{$previousOrder->service->id}",
                title: $previousOrder->service->name,
                description: $previousOrder->service->description ?? '',
                quantity: 1,
                unitPrice: 350.00,
            ),
        ],
    ),
];

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(...)
    ->buyer(...)
    ->orderHistory($orderHistoryItems)
    ->buyerHistory(...)
    ->item(...)
    ->build();

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(
        id: $order->id,
        referenceId: (string) $order->id,
        amount: 500.00,
    )
    ->buyer(name: $client->name)
    ->orderHistory([])  // name,
        unitPrice: 500.00
    )
    ->build();

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(...)
    ->buyer(...)
    ->shippingAddress(...)
    ->item(
        referenceId: "service-1",
        title: "Service 1",
        description: "Description 1",
        quantity: 1,
        unitPrice: 200.00
    )
    ->item(
        referenceId: "service-2",
        title: "Service 2",
        description: "Description 2",
        quantity: 2,
        unitPrice: 150.00
    )
    ->build();

use MLQuarizm\PaymentGateway\DTOs\OrderItemDTO;

$items = [
    new OrderItemDTO(
        referenceId: "service-1",
        title: "Service 1",
        description: "Description 1",
        quantity: 1,
        unitPrice: 200.00
    ),
    new OrderItemDTO(
        referenceId: "service-2",
        title: "Service 2",
        description: "Description 2",
        quantity: 2,
        unitPrice: 150.00
    ),
];

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(...)
    ->buyer(...)
    ->shippingAddress(...)
    ->items($items)
    ->build();

$items = [
    [
        'referenceId' => "service-1",
        'title' => "Service 1",
        'description' => "Description 1",
        'quantity' => 1,
        'unitPrice' => 200.00
    ],
    [
        'referenceId' => "service-2",
        'title' => "Service 2",
        'description' => "Description 2",
        'quantity' => 2,
        'unitPrice' => 150.00
    ],
];

$tabbyDTO = TabbyPaymentDTOBuilder::new()
    ->order(...)
    ->buyer(...)
    ->shippingAddress(...)
    ->items($items)
    ->build();

use MLQuarizm\PaymentGateway\Builders\TamaraPaymentDTOBuilder;
use MLQuarizm\PaymentGateway\Factory\PaymentGatewayFactory;

$tamaraDTO = TamaraPaymentDTOBuilder::new()
    ->order(
        id: $order->id,
        referenceId: (string) $order->id,
        amount: 500.00,
        currency: 'SAR',
        description: "Order #{$order->id}"
    )
    ->consumer(
        firstName: $client->name,
        lastName: '',
        phoneNumber: $client->full_phone,
        email: $client->email,
        dateOfBirth: '1990-01-01'
    )
    ->billingAddress(
        city: $order->city->name,
        line1: $order->address,
        zip: $order->postal_code,
        countryCode: 'SA'
    )
    ->shippingAddress(
        city: $order->city->name,
        line1: $order->address,
        zip: $order->postal_code,
        countryCode: 'SA'
    )
    ->item(
        referenceId: "service-{$order->service->id}",
        type: 'Physical',
        name: $order->service->name,
        sku: "SERVICE-{$order->service->id}",
        unitPrice: 500.00,
        totalAmount: 500.00
    )
    ->build();

$factory = new PaymentGatewayFactory();
$gateway = $factory->make('tamara');
$paymentInfo = $gateway->initiatePayment($tamaraDTO);

// Check for rejection before redirecting
if (!$paymentInfo['success']) {
    return back()->withErrors(['payment' => $paymentInfo['message'] ?? 'Payment rejected']);
}

// Record the transaction and redirect (same as Tabby)
PaymentGateway::recordTransaction($order, (string) $order->id, $paymentInfo['payment_id'] ?? null, 'tamara', 500.00, $paymentInfo);
return redirect($paymentInfo['url']);

$tamaraDTO = TamaraPaymentDTOBuilder::new()
    ->order(...)
    ->consumer(...)
    ->billingAddress(...)
    ->shippingAddress(...)
    ->item(
        referenceId: "service-1",
        type: 'Physical',
        name: "Service 1",
        sku: "SERVICE-1",
        unitPrice: 200.00,
        totalAmount: 200.00
    )
    ->item(
        referenceId: "service-2",
        type: 'Physical',
        name: "Service 2",
        sku: "SERVICE-2",
        unitPrice: 150.00,
        totalAmount: 300.00,
        quantity: 2
    )
    ->build();

use MLQuarizm\PaymentGateway\DTOs\TamaraOrderItemDTO;

$items = [
    new TamaraOrderItemDTO(
        referenceId: "service-1",
        type: 'Physical',
        name: "Service 1",
        sku: "SERVICE-1",
        unitPrice: 200.00,
        totalAmount: 200.00
    ),
    new TamaraOrderItemDTO(
        referenceId: "service-2",
        type: 'Physical',
        name: "Service 2",
        sku: "SERVICE-2",
        unitPrice: 150.00,
        totalAmount: 300.00,
        quantity: 2
    ),
];

$tamaraDTO = TamaraPaymentDTOBuilder::new()
    ->order(...)
    ->consumer(...)
    ->billingAddress(...)
    ->shippingAddress(...)
    ->items($items)
    ->build();

use MLQuarizm\PaymentGateway\Events\PaymentSuccess;
use MLQuarizm\PaymentGateway\Events\PaymentFailed;
use MLQuarizm\PaymentGateway\Events\PaymentCancelled;
use App\Listeners\HandlePaymentSuccess;
use App\Listeners\HandlePaymentFailure;
use App\Listeners\HandlePaymentCancellation;

protected $listen = [
    PaymentSuccess::class => [
        HandlePaymentSuccess::class,
    ],
    PaymentFailed::class => [
        HandlePaymentFailure::class,
    ],
    PaymentCancelled::class => [
        HandlePaymentCancellation::class,
    ],
];



namespace App\Listeners;

use MLQuarizm\PaymentGateway\Events\PaymentSuccess;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class HandlePaymentSuccess implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Handle the event.
     */
    public function handle(PaymentSuccess $event): void
    {
        $transaction = $event->transaction;
        $order = $transaction->payable; // Your Order model or any payable model
        
        // Update order status
        $order->update(['payment_status' => 'paid']);
        
        // Send notifications
        $order->client->notify(new PaymentSuccessfulNotification($order));
        
        // Dispatch jobs, etc.
        dispatch(new ProcessSuccessfulPaymentJob($order));
    }
}

use Illuminate\Support\Facades\Event;
use MLQuarizm\PaymentGateway\Events\PaymentSuccess;
use MLQuarizm\PaymentGateway\Events\PaymentFailed;

public function boot(): void
{
    Event::listen(PaymentSuccess::class, function (PaymentSuccess $event) {
        $transaction = $event->transaction;
        $order = $transaction->payable;
        
        $order->update(['payment_status' => 'paid']);
        // Handle success...
    });

    Event::listen(PaymentFailed::class, function (PaymentFailed $event) {
        $transaction = $event->transaction;
        $reason = $event->reason;
        
        // Log failure, notify admin, etc.
        Log::error('Payment failed', [
            'transaction_id' => $transaction->id,
            'reason' => $reason
        ]);
    });
}

   protected $except = [
       'payment/callback/*',
       'webhooks/payment/*',
   ];
   

use Illuminate\Support\Facades\Event;
use MLQuarizm\PaymentGateway\Events\PaymentSuccess;
use MLQuarizm\PaymentGateway\Events\PaymentFailed;
use MLQuarizm\PaymentGateway\Events\PaymentCancelled;
use MLQuarizm\PaymentGateway\Events\PaymentPending;

// In a service provider or dedicated listener class
Event::listen(PaymentSuccess::class, function (PaymentSuccess $event) {
    $transaction = $event->transaction;
    // Update order, send notification, etc.
});

Event::listen(PaymentFailed::class, function (PaymentFailed $event) {
    $transaction = $event->transaction;
    $reason = $event->reason;
});

Event::listen(PaymentCancelled::class, function (PaymentCancelled $event) {
    $transaction = $event->transaction;
});

PaymentTransaction::create([
    'payable_type' => Order::class, // or any model
    'payable_id' => $order->id,
    'track_id' => (string) $order->id,
    'payment_id' => $paymentInfo['payment_id'],
    'payment_gateway' => 'tabby',
    'amount' => 500.00,
    'status' => 'pending',
]);
bash
php artisan vendor:publish --tag=payment-gateway-config
php artisan vendor:publish --tag=payment-gateway-migrations
bash
php artisan migrate
bash
php artisan make:listener HandlePaymentSuccess
php artisan make:listener HandlePaymentFailure
php artisan make:listener HandlePaymentCancellation