Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -174,12 +174,17 @@ class AccountController extends Controller
|
||||
);
|
||||
|
||||
$provider = (string) ($data['gateway_provider'] ?? '');
|
||||
if ($provider !== '' && $this->subscriptions->canUsePaymentGateway($account)) {
|
||||
if ($this->subscriptions->canUsePaymentGateway($account)) {
|
||||
$existing = PaymentGatewaySetting::query()->firstOrNew([
|
||||
'owner_ref' => $account->public_id,
|
||||
]);
|
||||
$existing->provider = $provider;
|
||||
$existing->is_active = $request->boolean('gateway_is_active', true);
|
||||
if ($provider === '' && ! $existing->exists) {
|
||||
return redirect()->route('account.settings')->with('success', 'Settings saved.');
|
||||
}
|
||||
if ($provider !== '') {
|
||||
$existing->provider = $provider;
|
||||
}
|
||||
$existing->is_active = $provider !== '' && $request->boolean('gateway_is_active');
|
||||
if (filled($data['gateway_public_key'] ?? null)) {
|
||||
$existing->public_key = $data['gateway_public_key'];
|
||||
}
|
||||
|
||||
@@ -39,12 +39,13 @@ class PaymentGatewaySetting extends Model
|
||||
return false;
|
||||
}
|
||||
|
||||
$public = trim((string) $this->public_key);
|
||||
$secret = trim((string) $this->secret_key);
|
||||
|
||||
return $secret !== '' && in_array($this->provider, [
|
||||
self::PROVIDER_PAYSTACK,
|
||||
self::PROVIDER_FLUTTERWAVE,
|
||||
self::PROVIDER_HUBTEL,
|
||||
], true);
|
||||
return match ($this->provider) {
|
||||
self::PROVIDER_PAYSTACK => str_starts_with($public, 'pk_') && str_starts_with($secret, 'sk_'),
|
||||
self::PROVIDER_FLUTTERWAVE, self::PROVIDER_HUBTEL => $public !== '' && $secret !== '',
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,30 +133,54 @@ class EventRegistrationService
|
||||
$feeTier = $mode === 'contributions' ? 'donations' : 'sales';
|
||||
$callbackUrl = LadillLink::path($qrCode->short_code, 'register/callback');
|
||||
|
||||
$payOrder = $this->pay->createCheckout([
|
||||
'merchant' => $qrCode->user->public_id,
|
||||
'fee_tier' => $feeTier,
|
||||
'source_service' => 'events',
|
||||
'source_ref' => (string) $qrCode->id,
|
||||
'callback_url' => $callbackUrl,
|
||||
'customer_name' => $name,
|
||||
'customer_email' => $email,
|
||||
'customer_phone' => $registration->attendee_phone,
|
||||
'line_items' => [
|
||||
[
|
||||
$usesOwnerGateway = $this->gateway->shouldUseOwnerGateway($qrCode->user);
|
||||
$payOrder = null;
|
||||
if ($usesOwnerGateway) {
|
||||
try {
|
||||
$payOrder = $this->gateway->initializeCheckout(
|
||||
$qrCode->user,
|
||||
$amountMinor,
|
||||
(string) ($content['currency'] ?? 'GHS'),
|
||||
(string) config('pay.mini_checkout_email', 'pay@ladill.com'),
|
||||
$callbackUrl,
|
||||
'EVTP-'.strtoupper(Str::random(16)),
|
||||
[
|
||||
'title' => $lineName,
|
||||
'registration_id' => $registration->id,
|
||||
'registration_reference' => $registration->reference,
|
||||
'qr_code_id' => $qrCode->id,
|
||||
'mode' => $mode,
|
||||
'attendee_email' => $email,
|
||||
],
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
$usesOwnerGateway = false;
|
||||
}
|
||||
}
|
||||
if (! $usesOwnerGateway) {
|
||||
$payOrder = $this->pay->createCheckout([
|
||||
'merchant' => $qrCode->user->public_id,
|
||||
'fee_tier' => $feeTier,
|
||||
'source_service' => 'events',
|
||||
'source_ref' => (string) $qrCode->id,
|
||||
'callback_url' => $callbackUrl,
|
||||
'customer_name' => $name,
|
||||
'customer_email' => $email,
|
||||
'customer_phone' => $registration->attendee_phone,
|
||||
'line_items' => [[
|
||||
'name' => $lineName,
|
||||
'unit_price_minor' => $amountMinor,
|
||||
'quantity' => 1,
|
||||
]],
|
||||
'metadata' => [
|
||||
'registration_id' => $registration->id,
|
||||
'registration_reference' => $registration->reference,
|
||||
'qr_code_id' => $qrCode->id,
|
||||
'mode' => $mode,
|
||||
'attendee_email' => $email,
|
||||
],
|
||||
],
|
||||
'metadata' => [
|
||||
'registration_id' => $registration->id,
|
||||
'registration_reference' => $registration->reference,
|
||||
'qr_code_id' => $qrCode->id,
|
||||
'mode' => $mode,
|
||||
'attendee_email' => $email,
|
||||
],
|
||||
]);
|
||||
]);
|
||||
}
|
||||
|
||||
$checkoutUrl = (string) ($payOrder['checkout_url'] ?? '');
|
||||
if ($checkoutUrl === '') {
|
||||
@@ -164,10 +188,11 @@ class EventRegistrationService
|
||||
}
|
||||
|
||||
$registration->update([
|
||||
'pay_order_id' => $payOrder['id'] ?? null,
|
||||
'pay_order_id' => $usesOwnerGateway ? null : ($payOrder['id'] ?? null),
|
||||
'payment_reference' => $payOrder['reference'],
|
||||
'metadata' => array_merge((array) $registration->metadata, [
|
||||
'ladill_pay_init' => [
|
||||
($usesOwnerGateway ? 'merchant_gateway_init' : 'ladill_pay_init') => [
|
||||
'provider' => $payOrder['provider'] ?? 'ladill_pay',
|
||||
'platform_fee_minor' => $payOrder['platform_fee_minor'] ?? null,
|
||||
'merchant_amount_minor' => $payOrder['merchant_amount_minor'] ?? null,
|
||||
],
|
||||
|
||||
@@ -19,11 +19,13 @@ class MerchantGatewayService
|
||||
|
||||
public function isConfigured(User|string $owner): bool
|
||||
{
|
||||
if (! $this->ownerMayUseGateway($owner)) {
|
||||
return false;
|
||||
}
|
||||
return $this->shouldUseOwnerGateway($owner);
|
||||
}
|
||||
|
||||
return (bool) $this->settingFor($owner)?->isConfigured();
|
||||
public function shouldUseOwnerGateway(User|string $owner): bool
|
||||
{
|
||||
return $this->ownerMayUseGateway($owner)
|
||||
&& (bool) $this->settingFor($owner)?->isConfigured();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +57,12 @@ class MerchantGatewayService
|
||||
*/
|
||||
public function verify(User|string $owner, string $reference): array
|
||||
{
|
||||
$setting = $this->requireConfigured($owner);
|
||||
// Do not re-check the current plan here: an owner-gateway payment
|
||||
// initiated before a downgrade must remain verifiable.
|
||||
$setting = $this->settingFor($owner);
|
||||
if (! $setting?->isConfigured()) {
|
||||
throw new RuntimeException('The payment gateway used for this transaction is no longer configured.');
|
||||
}
|
||||
|
||||
return match ($setting->provider) {
|
||||
PaymentGatewaySetting::PROVIDER_PAYSTACK => $this->paystackVerify($setting, $reference),
|
||||
|
||||
Reference in New Issue
Block a user