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
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
- guzzlehttp/guzzle: ^7.0
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- illuminate/support: ^10.0|^11.0|^12.0
- mockery/mockery: ^1.6
- pestphp/pest: ^2.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.0
Suggests
- illuminate/support: Required for Laravel integration
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.
⚠️ 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:
- Creates the webhook in Moyasar - Registers with the payment gateway
- Generates scaffold controller - Basic event handling structure
- 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