Merge pull request 'fix(lightning): cash-in commission charged twice (send gross principal, not net)' (#81) from fix/cashin-double-fee into dev

Reviewed-on: #81
This commit is contained in:
padreug 2026-07-30 01:04:19 +00:00
commit 543f21a060

View file

@ -725,7 +725,17 @@ function createATMServices(
* over nostr, we trigger dispense. * over nostr, we trigger dispense.
*/ */
generateLnurlWithdraw: async (context: ATMContext): Promise<string> => { generateLnurlWithdraw: async (context: ATMContext): Promise<string> => {
console.log('[ATM Service] Generating LNURL-withdraw for', context.satsAmount, 'sats') // GROSS principal (fiat × rate, BEFORE commission). The server derives
// fee + NET from this, so we must NOT send the already-fee'd
// context.satsAmount — doing so double-applies the commission (client
// subtracts it in calculateSats, then the server subtracts it again,
// e.g. 12% → 22.6% effective; the customer is short-changed while the
// quote/receipt still read 12%). Mirror calculateSats's principal.
const grossPrincipalSats = Math.floor((context.fiatCents / 100) * context.exchangeRate)
console.log(
`[ATM Service] Generating LNURL-withdraw: gross principal=${grossPrincipalSats} sats ` +
`(net after ${(context.feeFraction * 100).toFixed(2)}% ≈ ${context.satsAmount})`
)
try { try {
if (context.cashInSessionId) { if (context.cashInSessionId) {
@ -738,7 +748,7 @@ function createATMServices(
// the amount or extra. We display the returned LNURL (for NET) and // the amount or extra. We display the returned LNURL (for NET) and
// watch link_id for settlement. // watch link_id for settlement.
const link = await lnbits.createWithdraw(lnbitsWalletId, { const link = await lnbits.createWithdraw(lnbitsWalletId, {
principal_sats: context.satsAmount, principal_sats: grossPrincipalSats,
fiat_amount: context.fiatCents / 100, fiat_amount: context.fiatCents / 100,
fiat_code: context.currency, fiat_code: context.currency,
title: `bitSpire Cash-In ${context.cashInSessionId?.slice(0, 8) || 'session'}`, title: `bitSpire Cash-In ${context.cashInSessionId?.slice(0, 8) || 'session'}`,