2026-07-28 · 52 مشاهدة · 5 دقائق قراءة

الدليل المتكامل لتركيب واستدعاء Nafezly Payments وربطها بالعميل

شرح عملي خطوة بخطوة لتركيب حزمة Nafezly Payments في لارافيل، إعداد بوابات الدفع، استدعاء عملية الدفع وربطها ببيانات العميل والتحقق من نتيجة العملية.

الدليل المتكامل لتركيب واستدعاء Nafezly Payments وربطها بالعميل

الدليل المتكامل لتركيب واستدعاء Nafezly Payments وربطها بالعميل والأدمن في Laravel

شرح عملي خطوة بخطوة مع قاعدة البيانات ومتحكمات العميل ولوحة تحكم الإدارة (متجاوب بالكامل ومع أزرار نسخ للأكواد).

البوابات المدعومة: Paymob, Fawry, Tap, Kashier, Paytabs, Moyasar, Hyperpay, PayPal, Thawani, Urway, Paystack.
الخطوة 1

تثبيت الحزمة ونشر الملفات

قم بتثبيت الحزمة ونشر ملفات Configuration والـ Views إلى مشروعك:

Terminal
composer require nafezly/payments
php artisan vendor:publish --tag=nafezly-payments-config
php artisan vendor:publish --tag=nafezly-payments-views

ضع بيانات الاعتماد للبوابات في ملف .env:

.env
PAYMOB_API_KEY=your_api_key
PAYMOB_INTEGRATION_ID=your_integration_id
PAYMOB_IFRAME_ID=your_iframe_id
PAYMOB_HMAC_TITLE=your_hmac_secret
NAFEZLY_PAYMENT_CURRENCY=EGP
PAYMENT_REDIRECT_URL=http://localhost:8000/payment/verify
الخطوة 2

إنشاء جدول السجلات في قاعدة البيانات (Migration)

أنشئ Model مع ملف Migration لتخزين عمليات الدفع المربوطة بالعميل:

Terminal
php artisan make:model Payment -m

افتح ملف الـ Migration وأضف هيكل الجدول التالي:

database/migrations/xxxx_create_payments_table.php
id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');$table->string('payment_id')->nullable();
$table->string('driver'); // paymob, fawry, tap...$table->decimal('amount', 10, 2);
$table->string('currency', 3)->default('EGP');$table->enum('status', ['pending', 'paid', 'failed'])->default('pending');
$table->json('process_data')->nullable();$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('payments');
}
};
Terminal
php artisan migrate
الخطوة 3

ربط علاقات الـ Models (User & Payment)

app/Models/Payment.php
 'array',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
app/Models/User.php
// أضف هذه الدالة داخل كلاس User
public function payments()
{
return $this->hasMany(Payment::class);
}
الخطوة 4

متحكم الدفع والربط للعميل (User Controller)

متحكم معالجة إنشاء المعاملة والتحويل للبوابة واستقبال النتيجة:

app/Http/Controllers/PaymentController.php
validate([
'amount' => 'required|numeric|min:1',
'gateway' => 'required|in:paymob,fawry,tap'
]);
$user = auth()->user();
// 1. تسجيل سجل معلق بالعميل
$paymentRecord = Payment::create([
'user_id' => $user->id,
'driver' => $request->gateway,
'amount' => $request->amount,
'currency' => config('nafezly-payments.currency', 'EGP'),
'status' => 'pending',
]);
// 2. استدعاء بوابة الدفع
$gateway = match($request->gateway) {
'paymob' => new PaymobPayment(),
'fawry'  => new FawryPayment(),
'tap'    => new TapPayment(),
};
// 3. التنفيذ عبر مكتبة Nafezly
$response =$gateway->pay(
amount: $request->amount,
user_first_name: $user->name,
user_last_name: 'Customer',
user_email: $user->email,
user_phone: $user->phone ?? '01000000000'
);
if (isset($response['payment_id'])) {
$paymentRecord->update(['payment_id' => $response['payment_id']]);
}
session(['current_payment_db_id' => $paymentRecord->id]);
if (isset($response['redirect_url'])) {
return redirect($response['redirect_url']);
}
return view('payment-redirect', ['payment' => $response]);
}
public function verify(Request $request)
{
$paymentDbId = session('current_payment_db_id');
$paymentRecord = Payment::findOrFail($paymentDbId);
$gateway = match($paymentRecord->driver) {
'paymob' => new PaymobPayment(),
'fawry'  => new FawryPayment(),
'tap'    => new TapPayment(),
};
$response = $gateway->verify($request);
if ($response['success'] === true) {$paymentRecord->update([
'status' => 'paid',
'payment_id' => $response['payment_id'] ?? $paymentRecord->payment_id,
'process_data' => $response['process_data'] ?? null
]);
return redirect()->route('dashboard')
->with('success', 'تم الدفع بنجاح وتسجيل المعاملة!');
}
$paymentRecord->update([
'status' => 'failed',
'process_data' => $response['process_data'] ?? null
]);
return redirect()->route('dashboard')
->with('error', 'فشلت عملية الدفع!');
}
}
الخطوة 5

ربط لوحة التحكم للأدمن (Admin Controller & View)

app/Http/Controllers/Admin/AdminPaymentController.php
latest();
if ($request->filled('status')) {
$query->where('status',$request->status);
}
if ($request->filled('driver')) {
$query->where('driver',$request->driver);
}
$payments = $query->paginate(15);$totalPaid = Payment::where('status', 'paid')->sum('amount');
return view('admin.payments.index', compact('payments', 'totalPaid'));
}
public function show($id)
{
$payment = Payment::with('user')->findOrFail($id);
return view('admin.payments.show', compact('payment'));
}
}

واجهة لوحة الأدمن (Blade View) المتجاوبة بالكامل وبدون حواف خارجية:

resources/views/admin/payments/index.blade.php

إدارة المعاملات المالية

إجمالي المبيعات الناجحة: {{ number_format($totalPaid, 2) }} EGP
@forelse(payments aspayment) @empty @endforelse
# المعاملة العميل البوابة المبلغ الحالة التاريخ التفاصيل
{{ $payment->payment_id ?? $payment->id }} {{ $payment->user->name }}
{{ $payment->user->email }}
{{ strtoupper($payment->driver) }} {{ $payment->amount }} {{$payment->currency }} @if($payment->status == 'paid') ناجح @elseif($payment->status == 'pending') معلق @else فاشل @endif {{ $payment->created_at->format('Y-m-d H:i') }} عرض
لا توجد معاملات حالياً.
{{ $payments->links() }}
الخطوة 6

تعريف المسارات (Routes)

routes/web.php
use App\Http\Controllers\PaymentController;
use App\Http\Controllers\Admin\AdminPaymentController;
// مسارات العملاء
Route::middleware(['auth'])->group(function () {
Route::post('/payment/process', [PaymentController::class, 'pay'])->name('payment.process');
Route::any('/payment/verify', [PaymentController::class, 'verify'])->name('payment.verify');
});
// مسارات الأدمن
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
Route::get('/payments', [AdminPaymentController::class, 'index'])->name('payments.index');
Route::get('/payments/{id}', [AdminPaymentController::class, 'show'])->name('payments.show');
});
العودة لجميع المقالات تواصل لمناقشة مشروع