diff --git a/nostr_publisher.py b/nostr_publisher.py index 2588fcb..8374a62 100644 --- a/nostr_publisher.py +++ b/nostr_publisher.py @@ -17,7 +17,7 @@ from datetime import datetime, timezone from lnbits.core.signers import NostrSigner from loguru import logger -from .models import Event +from .models import Event, effective_payment_methods from .nostr.event import NostrEvent from .nostr_timestamp import monotonic_created_at @@ -110,6 +110,11 @@ def build_nip52_event(event: Event, pubkey: str) -> NostrEvent: tags.append(["tickets_allow_fiat", "true"]) if event.fiat_currency: tags.append(["tickets_fiat_currency", event.fiat_currency]) + # Rails the organizer accepts, resolved through the same helper the + # ticket endpoint enforces with, so a client can render exactly the + # buttons that will be accepted (e.g. a card-only event) without a REST + # round-trip. Comma-separated, lowercase. + tags.append(["tickets_payment_methods", ",".join(effective_payment_methods(event))]) # NIP-52 calendar events are replaceable: this d-tag is republished # whenever inventory changes (a ticket sells). Use a strictly-monotonic diff --git a/static/js/display.js b/static/js/display.js index d8be8e9..ad7e358 100644 --- a/static/js/display.js +++ b/static/js/display.js @@ -35,13 +35,29 @@ window.PageEventsDisplay = { async created() { this.eventId = this.$route.params.id this.event = await this.getEvent() + // Default to the first rail the organizer accepts (a card-only event + // must not submit "lightning"). + this.formDialog.data.payment_method = this.paymentMethods[0] || 'lightning' }, computed: { formatDescription() { return LNbits.utils.convertMarkdown(this.event?.info || '') }, + paymentMethods() { + // Mirrors `effective_payment_methods` on the backend: an explicit + // extra.payment_methods list wins, else Lightning + fiat-if-allow_fiat. + const explicit = this.event?.extra?.payment_methods || [] + if (explicit.length) return explicit + return ['lightning', ...(this.event?.allow_fiat ? ['fiat'] : [])] + }, allowFiatCheckout() { - return Boolean(this.event?.allow_fiat) + return this.paymentMethods.includes('fiat') + }, + paymentMethodOptions() { + return this.paymentMethods.map(method => ({ + value: method, + label: method === 'fiat' ? this.fiatCheckoutLabel : 'Lightning' + })) }, fiatCheckoutLabel() { if (!this.allowFiatCheckout) return 'Fiat' @@ -78,7 +94,8 @@ window.PageEventsDisplay = { this.formDialog.data.email = '' this.formDialog.data.refund = '' this.formDialog.data.nostr_identifier = '' - this.formDialog.data.payment_method = 'lightning' + this.formDialog.data.payment_method = + this.paymentMethods[0] || 'lightning' }, closeReceiveDialog() { @@ -112,7 +129,8 @@ window.PageEventsDisplay = { this.formDialog.data.email = '' this.formDialog.data.refund = '' this.formDialog.data.nostr_identifier = '' - this.formDialog.data.payment_method = 'lightning' + this.formDialog.data.payment_method = + this.paymentMethods[0] || 'lightning' Quasar.Notify.create({ type: 'positive', message: 'Sent, thank you!', diff --git a/static/js/display.vue b/static/js/display.vue index 9b27783..5a2ed68 100644 --- a/static/js/display.vue +++ b/static/js/display.vue @@ -90,20 +90,18 @@ :hint="`If minimum tickets (${event.extra?.min_tickets}) are not met, refund will be sent.`" >