Compare commits

..

No commits in common. "8203c54feb6e9c9ca3caa47b65a192329acaecd7" and "3e5eeaf7a9a997669e6b43e1a1f7e20814494fea" have entirely different histories.

4 changed files with 6 additions and 26 deletions

View file

@ -5,15 +5,7 @@ import { toast } from 'vue-sonner'
export interface PaymentResult { export interface PaymentResult {
payment_hash: string payment_hash: string
/** fee_msat: number
* Routing fee in millisats, always positive.
*
* LNbits returns this as `fee`, not `fee_msat`, and signs it negative for
* outgoing payments (like `amount`). This interface previously declared
* `fee_msat: number`, a field the API never sends, so every consumer read
* `undefined` while the compiler vouched for a number.
*/
feeMsat: number
preimage: string preimage: string
} }
@ -238,16 +230,7 @@ export class PaymentService extends BaseService {
throw new Error(errorMessage) throw new Error(errorMessage)
} }
// Normalize at the boundary rather than handing the raw LNbits payload return await response.json()
// to callers: `fee` is signed millisats, and consumers all want a
// positive magnitude. Doing it here means no call site can pick the
// wrong field name or forget the sign.
const raw = await response.json()
return {
payment_hash: raw.payment_hash,
feeMsat: Math.abs(Number(raw.fee ?? 0)),
preimage: raw.preimage ?? ''
}
} }
/** /**
@ -283,7 +266,7 @@ export class PaymentService extends BaseService {
this.debug('Payment successful', { this.debug('Payment successful', {
paymentHash: paymentResult.payment_hash, paymentHash: paymentResult.payment_hash,
feeMsat: paymentResult.feeMsat feeMsat: paymentResult.fee_msat
}) })
// Show success notification if enabled // Show success notification if enabled

View file

@ -84,9 +84,7 @@ export class LnbitsPaymentProvider implements PaymentProvider {
const data = await response.json() const data = await response.json()
return { return {
paymentHash: data.payment_hash, paymentHash: data.payment_hash,
// LNbits sends `fee` (signed millisats), never `fee_msat`. Reading the feeMsat: data.fee_msat ?? 0,
// latter meant every payment recorded a zero fee.
feeMsat: Math.abs(Number(data.fee ?? 0)),
preimage: data.preimage ?? '', preimage: data.preimage ?? '',
} }
} }

View file

@ -42,7 +42,7 @@ export function useLightningPayment() {
status: 'paid' as const, status: 'paid' as const,
paidAt: Math.floor(Date.now() / 1000), paidAt: Math.floor(Date.now() / 1000),
paymentHash: paymentResult.payment_hash, paymentHash: paymentResult.payment_hash,
feeMsat: paymentResult.feeMsat, feeMsat: paymentResult.fee_msat,
items: [...order.items], // Convert readonly to mutable items: [...order.items], // Convert readonly to mutable
shippingZone: order.shippingZone ? { shippingZone: order.shippingZone ? {
...order.shippingZone, ...order.shippingZone,
@ -88,7 +88,7 @@ export function useLightningPayment() {
status: 'paid' as const, status: 'paid' as const,
paidAt: Math.floor(Date.now() / 1000), paidAt: Math.floor(Date.now() / 1000),
paymentHash: result.payment_hash, paymentHash: result.payment_hash,
feeMsat: result.feeMsat, feeMsat: result.fee_msat,
items: [...order.items], // Convert readonly to mutable items: [...order.items], // Convert readonly to mutable
shippingZone: order.shippingZone ? { shippingZone: order.shippingZone ? {
...order.shippingZone, ...order.shippingZone,

View file

@ -129,7 +129,6 @@ export interface Order {
originalOrderId?: string originalOrderId?: string
lightningInvoice?: any lightningInvoice?: any
paymentHash?: string paymentHash?: string
feeMsat?: number // Routing fee paid on the Lightning payment, in millisats
paidAt?: number paidAt?: number
paymentStatus?: 'pending' | 'paid' | 'expired' paymentStatus?: 'pending' | 'paid' | 'expired'
paid?: boolean // Direct boolean field matching nostrmarket reference paid?: boolean // Direct boolean field matching nostrmarket reference