fateel-tech/moyasar-php

Modern PHP SDK for Moyasar Payment Gateway

Installs: 60

Dependents: 0

Suggesters: 0

Security: 0

Stars: 3

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/fateel-tech/moyasar-php

v1.1.0 2025-10-09 20:12 UTC

This package is not auto-updated.

Last update: 2025-12-05 18:52:42 UTC


README

A modern, easy-to-use PHP SDK for Moyasar Payment Gateway with built-in Laravel integration.

PHP Version License

⚠️ Important Notice

We are NOT Moyasar. We are Fateel Tech, an independent IT company that builds solutions for our clients. Since the official Moyasar PHP package was abandoned and no longer maintained, we decided to create and maintain this modern SDK to make integration easier for the community.

Fateel Tech is an official partner with Moyasar, ensuring this package stays up-to-date with their latest API changes and best practices.

🚨 Migration from moyasar/moyasar-php

This SDK is not a drop-in replacement for the abandoned moyasar/moyasar package. While it covers the same core functionality (Payments, Invoices), the API design and usage patterns have been modernized and we have included support for tokenization and webhooks. As a result, existing code using the old SDK will need to be updated.

🔄 Quick Migration Guide

Old Way (moyasar/moyasar-php):

use Moyasar\Providers\PaymentService;
use Moyasar\Providers\InvoiceService;
use Moyasar\Facades\Moyasar;

// Fetch payment
$paymentService = new PaymentService();
$payment = $paymentService->fetch('payment_id');

// Create invoice
$invoiceService = new InvoiceService();
$invoice = $invoiceService->create(['amount' => 1000, 'currency' => 'SAR']);

// Basic Laravel facade
$payment = \Moyasar\Facades\Payment::fetch('id');

// Limited search capabilities
$search = \Moyasar\Search::query()->status('paid')->page(2);
$paginationResult = $paymentService->all($search);

// No tokenization support
// No webhook management
// No metadata search

New Way (fateel-tech/moyasar-php):

use FateelTech\Moyasar\Laravel\Facades\Moyasar;
use FateelTech\Moyasar\Enums\Currency;
use FateelTech\Moyasar\Enums\WebhookEvent;

// Fetch payment
$payment = Moyasar::payments()->find('payment_id');

// Create invoice with enums
$invoice = Moyasar::invoices()->create(
    amount: 1000,
    currency: Currency::SAR
);

// NEW: Tokenization support
$payment = Moyasar::payments()->createWithToken(
    token: 'token_abc123',
    amount: 5000,
    description: 'Payment with saved card'
);

// NEW: Webhook management
$webhook = Moyasar::webhooks()->create(
    url: 'https://yourapp.com/webhooks',
    events: [WebhookEvent::PAYMENT_PAID]
);

// NEW: Enhanced search with metadata filtering
$payments = Moyasar::payments()->list(
    page: 1,
    status: PaymentStatus::PAID,
    metadata: ['order_id' => '12345'],
    cardLastDigits: '1234',
    createdGt: '2024-01-01'
);

// NEW: Artisan commands
php artisan moyasar:make-webhook
php artisan moyasar:webhook list

Key improvements: Modern PHP 8.0+, tokenized card payments, webhook management, metadata search, strongly typed responses, comprehensive Laravel integration.

🛣️ Roadmap

We're actively working to provide complete Moyasar API coverage. The following features are on our roadmap:

  • Settlement API - Completed
  • Sources API
  • Payouts API
  • Transfers API

🤝 Contributions Welcome! If you'd like to help implement any of these features, please feel free to submit a pull request or open an issue to discuss implementation details.

🤝 Need Custom Development?

If you need custom payment integrations, Laravel applications, or any other development services, feel free to reach out to us:

Contact Fateel Tech: https://fateel.sa/contact-us

We specialize in:

  • 💳 Payment gateway integrations
  • 🛠️ Custom Laravel applications
  • 🔧 API development and integrations
  • 📱 Mobile and web applications

✨ Features

  • 💳 Full API Coverage: Payments, Invoices, Tokens, Webhooks, Settlements.
  • 🔒 Strongly Typed: Robust DTOs and enums ensure type safety.
  • 🚀 Laravel Integration: Seamless Laravel integration with DI, Facades, and Artisan commands.
  • 🔔 Webhook Management: Easily generate and manage webhooks with Artisan commands.
  • 🎯 Framework Agnostic: Use with any PHP framework or vanilla PHP.

📦 Installation

composer require fateel-tech/moyasar-php

⚡ Quick Start

Pure PHP

use FateelTech\Moyasar\MoyasarClient;

$moyasar = new MoyasarClient('sk_test_your_key');

// Create payment
$payment = $moyasar->payments()->createWithToken(
    token: 'token_abc123',
    amount: 5000,
    description: 'Test payment'
);

// Find payment
$payment = $moyasar->payments()->find('pay_abc123');

// List payments
$payments = $moyasar->payments()->list();

Laravel

Publish configuration and set keys:

# Publish configuration only
php artisan vendor:publish --tag=moyasar-config

# Or publish everything from the provider
php artisan vendor:publish --provider="FateelTech\Moyasar\Laravel\MoyasarServiceProvider"

.env

MOYASAR_API_KEY=sk_test_your_secret_key
MOYASAR_PUBLISHABLE_API_KEY=pk_test_your_publishable_key
MOYASAR_WEBHOOK_SECRET=your_webhook_secret

🎯 Usage

Dependency Injection

use FateelTech\Moyasar\MoyasarClient;

class PaymentController
{
    public function __construct(private MoyasarClient $moyasar) {}

    public function showPayment(Request $request)
    {
        $payment = $this->moyasar->payments()->find($request->payment_id);

        if ($payment->isCompleted()) {
            // Process successful payment
        }
    }
}

Facade

use FateelTech\Moyasar\Laravel\Facades\Moyasar;

$payment = Moyasar::payments()->createWithToken(
    token: 'token_abc123',
    amount: 5000,
    description: 'Order #1234'
);

Blade Helpers

<!DOCTYPE html>
<html>
<head>
    @moyasarStyles
</head>
<body>
    <div class="mysr-form"></div>

    @moyasarScripts

    <script>
        Moyasar.init({
            element: '.mysr-form',
            amount: {{ $order->total_in_halalas }},
            currency: 'SAR',
            description: 'Order #{{ $order->id }}',
            publishable_api_key: '@moyasarPublishableKey',
            callback_url: '{{ route("payment.callback") }}',
            methods: ['creditcard', 'stcpay'],
            metadata: { order_id: '{{ $order->id }}' }
        });
    </script>
</body>
</html>

🔔 Webhooks - Complete Guide

🚀 Quick Setup with make-webhook Command

The moyasar:make-webhook command does everything for you:

  1. Creates the webhook in Moyasar - Registers with the payment gateway
  2. Generates scaffold controller - Basic event handling structure
  3. Adds route automatically - Ready-to-use webhook endpoint
# Complete webhook setup in one command
php artisan moyasar:make-webhook payment https://yourapp.com/api/webhooks/payment your_webhook_secret --events=payment_paid,payment_failed --controller --route

# This creates:
# - Webhook registered with Moyasar
# - PaymentWebhookController with event handling
# - Route added to routes/web.php
# - Ready for immediate use and customization

📦 Optional: Publish Request Classes

# Publish webhook request classes for custom validation
php artisan vendor:publish --tag=moyasar-requests

🛠️ Manual Webhook Creation

For pure PHP or custom Laravel setups:

use FateelTech\Moyasar\Enums\WebhookEvent;

$webhook = $moyasar->webhooks()->create(
    httpMethod: 'post',
    url: 'https://yourapp.com/api/webhooks/payment',
    sharedSecret: 'your_webhook_secret',
    events: [WebhookEvent::PAYMENT_PAID, WebhookEvent::PAYMENT_FAILED]
);

📊 Available Events

💡 View Complete List: WebhookEvent.php with descriptions and helper methods.

Most Used Payment Events:

WebhookEvent::PAYMENT_PAID        // ✅ Payment completed successfully
WebhookEvent::PAYMENT_FAILED      // ❌ Payment failed
WebhookEvent::PAYMENT_AUTHORIZED  // 🔒 Payment authorized (not captured)
WebhookEvent::PAYMENT_CAPTURED    // 💰 Payment captured

Post-Payment Events:

WebhookEvent::PAYMENT_REFUNDED    // 💸 Payment refunded
WebhookEvent::PAYMENT_VOIDED      // ⚫ Payment voided
WebhookEvent::PAYMENT_ABANDONED   // 🚪 Payment abandoned by customer
WebhookEvent::PAYMENT_CANCELED    // ❌ Payment canceled
WebhookEvent::PAYMENT_EXPIRED     // ⏰ Payment expired
WebhookEvent::PAYMENT_VERIFIED    // ✔️ Payment verified

Payout & Balance Events:

WebhookEvent::PAYOUT_PAID         // 💳 Payout completed
WebhookEvent::PAYOUT_FAILED       // ❌ Payout failed
WebhookEvent::BALANCE_TRANSFERRED // 🏦 Balance transferred to bank

Event Helper Methods:

$event = WebhookEvent::PAYMENT_PAID;

$event->isSuccessEvent();     // true
$event->isFailureEvent();     // false
$event->isPostPaymentEvent(); // false
$event->getDescription();     // "Payment completed successfully"

🛠️ Management Commands (Laravel)

List & View Webhooks:

# List all webhooks with summary
php artisan moyasar:webhook list

# Show detailed webhook information
php artisan moyasar:webhook show webhook_abc123

# Delete webhook with confirmation
php artisan moyasar:webhook delete webhook_abc123

Debug Delivery Attempts:

# List all delivery attempts
php artisan moyasar:webhook-attempts list

# Show only failed delivery attempts
php artisan moyasar:webhook-attempts list --failed

# Filter by specific webhook
php artisan moyasar:webhook-attempts list --webhook=webhook_abc123

# View detailed attempt information
php artisan moyasar:webhook-attempts show attempt_abc123

Command Features:

  • 📊 Rich Tables - Formatted output with status indicators
  • 🔍 Detailed Views - Full attempt details including headers/body
  • Smart Filtering - Filter by webhook ID, failed attempts only
  • 📈 Statistics - Success/failure counts and summaries

💰 Settlement API

Track and manage your settlement data with comprehensive settlement operations.

📋 List Settlements

use FateelTech\Moyasar\Laravel\Facades\Moyasar;

// List all settlements
$settlements = Moyasar::settlements()->list();

// List with pagination and filters
$settlements = Moyasar::settlements()->list(
    page: 2,
    id: 'settlement_abc123',
    createdGt: '2024-01-01',
    createdLt: '2024-12-31'
);

// Access settlement data
foreach ($settlements->items as $settlement) {
    echo "Settlement ID: " . $settlement->id . "\n";
    echo "Amount: " . $settlement->amount . " " . $settlement->currency->value . "\n";
    echo "Fee: " . $settlement->fee . "\n";
    echo "Net Amount: " . $settlement->getNetAmount() . "\n";

    if ($settlement->hasInvoice()) {
        echo "Invoice URL: " . $settlement->invoiceUrl . "\n";
    }
}

🔍 Find Settlement

// Find specific settlement
$settlement = Moyasar::settlements()->find('settlement_abc123');

echo "Recipient Type: " . $settlement->recipientType . "\n";
echo "Settlement Count: " . $settlement->settlementCount . "\n";
echo "Created: " . $settlement->createdAt->format('Y-m-d H:i:s') . "\n";

📊 Settlement Lines (Fluent API)

// Find settlement and get its lines in one fluent chain
$settlement = Moyasar::settlements()->find('settlement_abc123');
$lines = $settlement->getLines();

// Or with pagination
$lines = $settlement->getLines(page: 2);

// Access line data
foreach ($lines->items as $line) {
    echo "Payment ID: " . $line->paymentId . "\n";
    echo "Type: " . $line->type . "\n";
    echo "Amount: " . $line->amount . " " . $line->currency->value . "\n";
    echo "Fee: " . $line->fee . "\n";
    echo "Net Amount: " . $line->getNetAmount() . "\n";

    if ($line->hasMetadata()) {
        echo "Metadata: " . json_encode($line->metadata) . "\n";
    }

    if ($line->source) {
        echo "Payment Source: " . $line->source->type->value . "\n";
    }
}

📄 Direct Settlement Lines Access

// Alternative: Direct access to settlement lines
$lines = Moyasar::settlements()->listLines('settlement_abc123');

// With pagination
$lines = Moyasar::settlements()->listLines('settlement_abc123', page: 2);

🔧 Settlement Helper Methods

$settlement = Moyasar::settlements()->find('settlement_abc123');

// Check available resources
if ($settlement->hasInvoice()) {
    $invoiceUrl = $settlement->invoiceUrl;
}

if ($settlement->hasCsvList()) {
    $csvUrl = $settlement->csvListUrl;
}

if ($settlement->hasPdfList()) {
    $pdfUrl = $settlement->pdfListUrl;
}

// Calculate net amount after fees and taxes
$netAmount = $settlement->getNetAmount();

💼 Real-World Examples

E-commerce Payment

Include order metadata for seamless tracking:

$payment = $moyasar->payments()->createWithToken(
    token: $request->payment_token,
    amount: $order->total_in_halalas,
    description: "Order #{$order->id}",
    metadata: ['order_id' => $order->id]
);

Subscription Billing

Monthly billing job example:

class ProcessSubscriptionBilling implements ShouldQueue
{
    public function handle(MoyasarClient $moyasar)
    {
        Subscription::due()->chunk(100, function ($subscriptions) use ($moyasar) {
            foreach ($subscriptions as $subscription) {
                $moyasar->payments()->createWithToken(
                    token: $subscription->payment_token,
                    amount: $subscription->plan->price,
                    metadata: ['subscription_id' => $subscription->id]
                );
            }
        });
    }
}

⚠️ Apple Pay Notice

Apple Pay failures trigger on_completed but NOT callback_url.

Recommendation: Always verify Apple Pay payment status on your server immediately upon completion.

📄 License

MIT License