diff --git a/config/ladill_launcher.php b/config/ladill_launcher.php index 3183cd4..2a0d785 100644 --- a/config/ladill_launcher.php +++ b/config/ladill_launcher.php @@ -32,7 +32,6 @@ return [ ['name' => 'Link', 'url' => 'https://link.'.$root.'/sso/connect?redirect='.urlencode('https://link.'.$root.'/dashboard'), 'icon' => 'link.svg'], ['name' => 'Frontdesk', 'url' => 'https://frontdesk.'.$root.'/sso/connect?redirect='.urlencode('https://frontdesk.'.$root.'/dashboard'), 'icon' => 'frontdesk.svg'], ['name' => 'Care', 'url' => 'https://care.'.$root.'/sso/connect?redirect='.urlencode('https://care.'.$root.'/dashboard'), 'icon' => 'care.svg'], - ['name' => 'One', 'url' => 'https://one.'.$root.'/sso/connect?redirect='.urlencode('https://one.'.$root.'/dashboard'), 'icon' => 'one.svg'], ['name' => 'Queue', 'url' => 'https://queue.'.$root.'/sso/connect?redirect='.urlencode('https://queue.'.$root.'/dashboard'), 'icon' => 'queue.svg'], ['name' => 'SMS', 'url' => 'https://sms.'.$root, 'icon' => 'sms.svg'], ['name' => 'Bird', 'url' => 'https://bird.'.$root, 'icon' => 'bird.svg'], diff --git a/resources/js/app.js b/resources/js/app.js index b77cedd..172e334 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -164,6 +164,8 @@ Alpine.data('miniPaymentLanding', (config = {}) => ({ errorMsg: config.errorMsg ?? '', showSheet: false, checkoutUrl: '', + accessCode: '', + returnUrl: '', paymentSheetStyle: '', sheetBleedStyle: '', @@ -240,14 +242,13 @@ Alpine.data('miniPaymentLanding', (config = {}) => ({ this.loading = false; return; } - if (window.innerWidth < 768) { - this.checkoutUrl = data.checkout_url; - this.showSheet = true; - this.loading = false; - } else { - window.location.href = data.checkout_url; - } + this.checkoutUrl = data.checkout_url || data.authorization_url || ''; + this.accessCode = data.access_code || ''; + this.returnUrl = data.callback_url || this.returnUrl || ''; + window.LadillPayCheckout?.prepare?.(); + this.showSheet = true; // loading cleared when payment UI opens (ladill-pay-opened) } catch (e) { + window.LadillPayCheckout?.cancel?.(); this.errorMsg = 'Network error. Please try again.'; this.loading = false; } diff --git a/resources/views/partials/paystack-sheet.blade.php b/resources/views/partials/paystack-sheet.blade.php new file mode 100644 index 0000000..51f3e62 --- /dev/null +++ b/resources/views/partials/paystack-sheet.blade.php @@ -0,0 +1,635 @@ +{{-- + Payment checkout shell. + + Audiences: + - buyer (default): public ticket buyers, donors, shoppers — self-serve checkout + - operator: signed-in staff flows such as wallet top-up + + Optional overrides: $sheetTitle, $sheetSubtitle, $sheetFooter, $sheetAria, $iframeTitle + Requires Alpine ancestor with: + - showSheet (bool) + - checkoutUrl (string) — authorization / waiting URL + - accessCode (string, optional) — Paystack initialize access_code for Inline + - publicKey (string, optional) + - returnUrl (string, optional) — where to go after Inline onSuccess (?reference=) + + checkout.paystack.com cannot be iframed (X-Frame-Options: SAMEORIGIN). + + Paystack Inline owns its secure payment popup. We do not place a Ladill + loading sheet in front of it: that created a needless first screen before + the checkout appeared. The Ladill bottomsheet/modal is reserved for + same-origin waiting pages (such as MoMo) and recoverable errors. +--}} +@php + $audience = $audience ?? 'buyer'; + $defaults = match ($audience) { + 'operator' => [ + 'title' => 'Complete payment', + 'subtitle' => null, + 'aria' => 'Complete payment', + 'iframe' => 'Payment checkout', + 'footer' => null, + ], + default => [ + 'title' => 'Complete your payment', + 'subtitle' => 'Pay securely. You\'ll get a confirmation when it succeeds.', + 'aria' => 'Complete your payment', + 'iframe' => 'Secure payment checkout', + 'footer' => 'Your payment is processed securely. Do not close this window until finished.', + ], + }; + $sheetTitle = $sheetTitle ?? $defaults['title']; + $sheetSubtitle = $sheetSubtitle ?? $defaults['subtitle']; + $sheetAria = $sheetAria ?? $defaults['aria']; + $iframeTitle = $iframeTitle ?? $defaults['iframe']; + $sheetFooter = $sheetFooter ?? $defaults['footer']; +@endphp +@once + +@endonce + diff --git a/resources/views/public/qr/landing.blade.php b/resources/views/public/qr/landing.blade.php index 236f109..e801ae7 100644 --- a/resources/views/public/qr/landing.blade.php +++ b/resources/views/public/qr/landing.blade.php @@ -338,6 +338,7 @@ errorMsg: '', showSheet: false, checkoutUrl: '', + accessCode: '', async give() { if (!this.amount || parseFloat(this.amount) <= 0) { this.errorMsg = 'Enter a valid amount.'; return; } if (!this.name.trim()) { this.errorMsg = 'Enter your name.'; return; } @@ -358,13 +359,10 @@ }); const data = await res.json(); if (data.error) { this.errorMsg = data.error; this.loading = false; return; } - if (window.innerWidth < 768) { - this.checkoutUrl = data.checkout_url; - this.showSheet = true; - this.loading = false; - } else { - window.location.href = data.checkout_url; - } + this.checkoutUrl = data.checkout_url || data.authorization_url || ''; + this.accessCode = data.access_code || ''; + this.returnUrl = data.callback_url || this.returnUrl || ''; + this.showSheet = true; // loading cleared when payment UI opens (ladill-pay-opened) } catch(e) { this.errorMsg = 'Network error. Please try again.'; this.loading = false; @@ -654,6 +652,7 @@ fields: {}, loading: false, errorMsg: '', showSheet: false, checkoutUrl: '', + accessCode: '', selectTier(n, p) { this.tier = n; this.tierPrice = p; }, selectCategory(n) { this.tier = n; }, async submit() { @@ -671,8 +670,7 @@ const data = await res.json(); if (data.error) { this.errorMsg = data.error; this.loading = false; return; } if (!data.paid) { window.location.href = data.success_url; return; } - if (window.innerWidth < 768) { this.checkoutUrl = data.checkout_url; this.showSheet = true; this.loading = false; } - else { window.location.href = data.checkout_url; } + this.checkoutUrl = data.checkout_url || data.authorization_url || ''; this.accessCode = data.access_code || ''; this.returnUrl = data.callback_url || this.returnUrl || ''; this.showSheet = true; // loading cleared when payment UI opens (ladill-pay-opened) } catch(e) { this.errorMsg = 'Network error. Please try again.'; this.loading = false; } } }" class="min-h-screen bg-slate-50 pb-12"> @@ -1157,6 +1155,7 @@ errorMsg: '', showSheet: false, checkoutUrl: '', + accessCode: '', shippingType: @js($shippingType), shippingFee: @js($shippingFee), freeAbove: @js($freeShippingAbove), @@ -1205,13 +1204,10 @@ }); const data = await res.json(); if (data.error) { this.errorMsg = data.error; this.loading = false; return; } - if (window.innerWidth < 768) { - this.checkoutUrl = data.checkout_url; - this.showSheet = true; - this.loading = false; - } else { - window.location.href = data.checkout_url; - } + this.checkoutUrl = data.checkout_url || data.authorization_url || ''; + this.accessCode = data.access_code || ''; + this.returnUrl = data.callback_url || this.returnUrl || ''; + this.showSheet = true; // loading cleared when payment UI opens (ladill-pay-opened) } catch(e) { this.errorMsg = 'Network error. Please try again.'; this.loading = false;