diff --git a/src/modules/restaurant/components/OrderInvoiceCard.vue b/src/modules/restaurant/components/OrderInvoiceCard.vue index 64d613b..c94c8fe 100644 --- a/src/modules/restaurant/components/OrderInvoiceCard.vue +++ b/src/modules/restaurant/components/OrderInvoiceCard.vue @@ -5,7 +5,7 @@ */ import { onMounted, onUnmounted, ref, watch } from 'vue' import QRCode from 'qrcode' -import { Copy, Check } from 'lucide-vue-next' +import { Copy, Check, Zap } from 'lucide-vue-next' import { Button } from '@/components/ui/button' import { Card, CardContent } from '@/components/ui/card' import type { OrderInvoice } from '../types/restaurant' @@ -58,6 +58,18 @@ function copy() { setTimeout(() => (copied.value = false), 1500) } +/** + * The `lightning:` URI scheme is the cross-platform handoff to a + * native LN wallet — iOS / Android route it to whichever wallet the + * user has set as default (Phoenix, Zeus, Wallet of Satoshi, etc.). + * Desktop browsers usually no-op or prompt to pick an app; we still + * surface the button so mobile-web flows work end-to-end without an + * LNbits account. + */ +function openInWallet() { + window.location.href = `lightning:${props.invoice.bolt11}` +} + function fmtCountdown(seconds: number) { const m = Math.floor(seconds / 60) const s = seconds % 60 @@ -89,16 +101,27 @@ function fmtCountdown(seconds: number) { {{ Math.ceil(invoice.amount_msat / 1000) }} sat - +
+ + +
diff --git a/src/modules/restaurant/views/CheckoutPage.vue b/src/modules/restaurant/views/CheckoutPage.vue index 096ee85..ab831e8 100644 --- a/src/modules/restaurant/views/CheckoutPage.vue +++ b/src/modules/restaurant/views/CheckoutPage.vue @@ -47,6 +47,7 @@ import OrderInvoiceCard from '../components/OrderInvoiceCard.vue' import { useCartStore } from '../stores/cart' import { useCheckout, type PlacedOrder } from '../composables/useCheckout' import { friendlyOrderStatus } from '../types/restaurant' +import { useAuth } from '@/composables/useAuthService' import { injectService, tryInjectService, @@ -60,6 +61,17 @@ const cart = useCartStore() const { state, placeOrders, payAll, reset } = useCheckout() const storage = tryInjectService(SERVICE_TOKENS.STORAGE_SERVICE) const api = injectService(SERVICE_TOKENS.RESTAURANT_API) +const { user } = useAuth() + +// The LNbits "pay from my wallet" CTA only makes sense when the +// customer is logged in *and* has a wallet with an admin key — both +// are required for the POST /api/v1/payments call. Anonymous +// customers (and logged-in users without a wallet) still get the QR +// + "Open in wallet" deeplink in OrderInvoiceCard, which routes to a +// native LN wallet on mobile. +const canPayFromLnbits = computed( + () => !!user.value?.wallets?.[0]?.adminkey +) // ----------------------------------------------------------------- // // review phase // @@ -427,7 +439,7 @@ function buildOrderInvoice(p: PlacedOrder) {