To accept Paystack payments in Laravel, create a PaymentController that uses the Laravel HTTP client to initialize a transaction with the Paystack API. Redirect the user to Paystack checkout. In the callback route, verify the transaction using your secret key and mark the order as paid.
Add your Paystack keys to .env:
PAYSTACK_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxx
PAYSTACK_PUBLIC_KEY=pk_test_xxxxxxxxxxxxxxxxxxxxx
Add them to config/services.php:
// config/services.php
'paystack' => [
'secret_key' => env('PAYSTACK_SECRET_KEY'),
'public_key' => env('PAYSTACK_PUBLIC_KEY'),
],
php artisan make:model Order -m
// database/migrations/create_orders_table.php
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->string('reference')->unique();
$table->string('email');
$table->integer('amount'); // in kobo
$table->string('currency', 3)->default('NGN');
$table->boolean('paid')->default(false);
$table->timestamp('paid_at')->nullable();
$table->timestamps();
});
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
// app/Http/Controllers/PaymentController.php
namespace App\Http\Controllers;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class PaymentController extends Controller
{
public function initialize(Request $request)
{
$request->validate([
'email' => 'required|email',
'amount' => 'required|numeric|min:1',
]);
$reference = 'order_' . Str::random(12);
$order = Order::create([
'reference' => $reference,
'email' => $request->email,
'amount' => (int) ($request->amount * 100),
]);
$response = Http::withToken(config('services.paystack.secret_key'))
->post('https://api.paystack.co/transaction/initialize', [
'email' => $request->email,
'amount' => $order->amount,
'reference' => $reference,
'callback_url' => route('payment.callback'),
]);
$data = $response->json();
if ($data['status'] ?? false) {
return redirect($data['data']['authorization_url']);
}
return back()->with('error', $data['message'] ?? 'Failed');
}
public function callback(Request $request)
{
$reference = $request->query('reference') ?? $request->query('trxref');
if (!$reference) {
return redirect('/')->with('error', 'Missing reference');
}
$response = Http::withToken(config('services.paystack.secret_key'))
->get('https://api.paystack.co/transaction/verify/' . $reference);
$data = $response->json();
if (($data['status'] ?? false) && $data['data']['status'] === 'success') {
$order = Order::where('reference', $reference)->first();
if ($order && $data['data']['amount'] === $order->amount) {
Order::where('reference', $reference)
->where('paid', false)
->update(['paid' => true, 'paid_at' => now()]);
return view('payment.success', ['order' => $order]);
}
}
return view('payment.failed');
}
}
// routes/web.php
use App\Http\Controllers\PaymentController;
Route::post('/pay', [PaymentController::class, 'initialize'])->name('payment.initialize');
Route::get('/payment/callback', [PaymentController::class, 'callback'])->name('payment.callback');
Paystack webhook requests will not have Laravel CSRF tokens. Exempt the webhook route:
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'webhooks/paystack',
];
The callback route is a GET request, so CSRF does not apply to it.
// For API routes (routes/api.php)
Route::post('/pay', function (Request $request) {
$reference = 'order_' . Str::random(12);
$response = Http::withToken(config('services.paystack.secret_key'))
->post('https://api.paystack.co/transaction/initialize', [
'email' => $request->email,
'amount' => (int) ($request->amount * 100),
'reference' => $reference,
]);
$data = $response->json();
if ($data['status'] ?? false) {
return response()->json([
'authorization_url' => $data['data']['authorization_url'],
'access_code' => $data['data']['access_code'],
'reference' => $data['data']['reference'],
]);
}
return response()->json(['error' => $data['message'] ?? 'Failed'], 400);
});
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course