spiderwebtr/payment-kit
PaymentKit
Laravel için çok sağlayıcılı ödeme altyapısı. Sipay, Param/TurkPOS, iyzico, AHL Pay ve RubikPara'yı tek bir arayüz arkasında toplar; 3D Secure ödemeleri kendi sayfalarınızdan başlatabilir, ayrıca — Horizon/Pulse gibi ayrı bir panodan — test edip izleyebilirsiniz.
Gereksinimler
- PHP 8.3+
- Laravel 13+
- Livewire 3.5+
Kurulum
composer require spiderwebtr/payment-kit
# config + migration dosyalarını yayınla (tek tag ikisini birden):
php artisan vendor:publish --tag=payment-kit
php artisan migrate
Yalnızca config ya da yalnızca migration için
--tag=payment-kit-config/--tag=payment-kit-migrationskullanabilirsiniz. Migration'lar yayınlanırken güncel timestamp alır (uygulama migration'larıyla doğru sırada çalışır).
Pano varsayılan olarak /payment-kit adresinde yayınlanır (config/payment-kit.php → path).
Kapatma
PAYMENT_KIT_ENABLED=false ile paketin tüm route'ları (pano, process, callback, logo)
tek anahtarla devre dışı bırakılabilir.
Erişim
- Yerel ortamda (
APP_ENV=local) panoya doğrudan girilir. - Diğer ortamlarda erişim, Laravel'in
viewPaymentKitgate'i ile kontrol edilir (Pulse'ınviewPulsedeseni).AppServiceProvider::boot()içinde tanımlayın:
use Illuminate\Support\Facades\Gate;
Gate::define('viewPaymentKit', fn ($user) => in_array($user->email, [
'admin@example.com',
]));
Gate tanımlı değilse (yerel dışı) erişim reddedilir.
Sağlayıcı kimlik bilgileri
.env üzerinden verilir (ör. SIPAY_*, AHLPAY_*, RUBIKPARA_*...). Ayrıntı için
config/payment-kit.php dosyasındaki providers bölümüne bakın.
Kendi sayfanızdan kullanım
API + Next.js (headless) kuruyorsanız: adım adım entegrasyon için docs/headless-integration.md.
Pano dışında, kendi ödeme sayfanızdan (ör. bağış formu) da ödeme başlatabilirsiniz.
Formunuz kart alanlarını card_data[...] adlarıyla göndersin; 3DS sonrası kullanıcı
returnUrl ile verdiğiniz sayfaya döner:
use Spiderwebtr\PaymentKit\Facades\PaymentKit;
use Spiderwebtr\PaymentKit\Models\Payment;
use Spiderwebtr\PaymentKit\Payments\CardData;
use Spiderwebtr\PaymentKit\Payments\PaymentService;
public function store(Request $request, PaymentService $payments)
{
$result = $payments->createTransaction(
providerKey: 'rubikpara',
amount: (float) $order->total_amount, // float, decimal string ya da PaymentAmount
description: 'Bağış',
returnUrl: fn (Payment $payment) => route('donation.thanks', $payment),
card: CardData::fromArray((array) $request->input('card_data', [])),
installmentCount: (int) $request->input('installment_count', 1),
);
return PaymentKit::redirectToProcess($result['response']); // 3DS ekranı
}
returnUrl string|Closure|null kabul eder:
returnUrl: 'https://site.test/odeme/tamam', // sabit URL
returnUrl: fn (Payment $payment) => route('thanks', $payment), // ödemeye özel URL
Closure, oluşturulan Payment ile çağrılır — ödeme createTransaction içinde
yaratıldığından, URL'i kurarken id/uuid'sine ancak bu sayede erişirsiniz (ör.
/thanks/42). Verilmezse kullanıcı paket işlem detayına döner.
Sonuç sayfanızda ödemeyi Payment modelinden okuyun (status, note, reference_id).
Ödeme sahibi (owner)
Ödemeyi herhangi bir modele bağlayabilirsiniz — polymorphic ve opsiyonel.
Sahip illa giriş yapmış bir kullanıcı olmak zorunda değil; giriş yapılmamış bir
ödeme bile bir Order'a (ya da Subscription, Invoice, Cart...) bağlanabilir:
// Misafir ödemesi, bir siparişe bağlı:
$payments->createTransaction('rubikpara', $order->total, owner: $order, card: ...);
// Ya da giriş yapmış kullanıcıya:
$payments->createTransaction('rubikpara', 100.0, owner: $request->user(), card: ...);
Kayıtlı kartla ödemede sahip verilmezse otomatik olarak kartın sahibine düşer. Sorgulama:
Payment::forOwner($order)->get(); // bu siparişin ödemeleri
$order->morphMany(Payment::class, 'owner'); // ilişki kurmak isterseniz
Eventler
PaymentCompleted / PaymentCanceled / PaymentRefunded event'leri yayınlanır.
Laravel'in event auto-discovery'si (varsayılan açık) ile bir Listener'da handle()
parametresini type-hint etmeniz dinlemek için yeterlidir:
namespace App\Listeners;
use Spiderwebtr\PaymentKit\Events\PaymentCompleted;
class MarkOrderPaid
{
public function handle(PaymentCompleted $event): void
{
// $event->payment
}
}
(Auto-discovery kapalıysa Event::listen(PaymentCompleted::class, ...) ile manuel kaydedin.)
Kart saklama (tokenization)
Kartın kendisi sağlayıcıda saklanır; veritabanında yalnızca sağlayıcı token'ı
(şifreli) ve kartı tanımaya yetecek maskeli bilgiler (bin + son 4, marka/tip) tutulur.
Her saklanan kartın bir sahibi (owner) zorunludur — User dahil herhangi bir
host modeli olabilir (polymorphic). Sahipsiz kart saklanamaz (panoda misafir
kullanıcı kart kaydedemez):
use Spiderwebtr\PaymentKit\Payments\CardVault;
$card = app(CardVault::class)->store($user, 'rubikpara', [
'holder_name' => 'Ad Soyad',
'number' => '5218...9752',
'expiry_month' => 12,
'expiry_year' => 30,
'cvv' => '000',
], label: 'İş kartım');
// Kayıtlı karttan ödeme (kart alanları gerekmez):
$payments->createTransaction('rubikpara', '100.00', storedCard: $card);
Sağlayıcının desteklemesi için handler'ı SupportsCardStorage arayüzünü uygulamalıdır
(şu an: RubikPara). Pano, destekleyen sağlayıcılarda "kartı kaydet" seçeneği ve
kayıtlı kart listesi sunar.
Yeni sağlayıcı ekleme
Tek bir handler class'ı + DB satırı + public/images/providers/{key} logosu yeterlidir.
Durum
PaymentKit yalnızca bir test panosu değil; aynı zamanda çok sağlayıcılı bir ödeme altyapısı / boilerplate sunar (kendi sayfalarınızdan gerçek 3DS ödemesi, kart saklama, taksit, event'ler). Ancak henüz stabil değildir — API'ler değişebilir.
⚠️ Bu sürüm production'da kullanılmamalıdır. Stabil bir sürüme kadar yalnızca test/geliştirme ortamlarında değerlendirin.