fix: pay_invoice timeout to prevent blocking (#2875)
* fix: make invoice non blocking * fix with vlad * wallet.js take pending into account * fixup! * add check payment to outgoing * revert * bundle * fix: label * fix: rebase change * feat: configure pay invoice wait time * fix: check payment button * bundle * fix: task in async context --------- Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com>
This commit is contained in:
parent
2f2a3b1092
commit
b06c16ed57
25 changed files with 144 additions and 67 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
@ -17,6 +18,7 @@ from lnbits.db import Connection, Filters
|
||||||
from lnbits.decorators import check_user_extension_access
|
from lnbits.decorators import check_user_extension_access
|
||||||
from lnbits.exceptions import InvoiceError, PaymentError
|
from lnbits.exceptions import InvoiceError, PaymentError
|
||||||
from lnbits.settings import settings
|
from lnbits.settings import settings
|
||||||
|
from lnbits.tasks import create_task
|
||||||
from lnbits.utils.crypto import fake_privkey, random_secret_and_hash
|
from lnbits.utils.crypto import fake_privkey, random_secret_and_hash
|
||||||
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis, satoshis_amount_as_fiat
|
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis, satoshis_amount_as_fiat
|
||||||
from lnbits.wallets import fake_wallet, get_funding_source
|
from lnbits.wallets import fake_wallet, get_funding_source
|
||||||
|
|
@ -61,11 +63,11 @@ async def pay_invoice(
|
||||||
invoice = _validate_payment_request(payment_request, max_sat)
|
invoice = _validate_payment_request(payment_request, max_sat)
|
||||||
assert invoice.amount_msat
|
assert invoice.amount_msat
|
||||||
|
|
||||||
async with db.reuse_conn(conn) if conn else db.connect() as conn:
|
async with db.reuse_conn(conn) if conn else db.connect() as new_conn:
|
||||||
amount_msat = invoice.amount_msat
|
amount_msat = invoice.amount_msat
|
||||||
wallet = await _check_wallet_for_payment(wallet_id, tag, amount_msat, conn)
|
wallet = await _check_wallet_for_payment(wallet_id, tag, amount_msat, new_conn)
|
||||||
|
|
||||||
if await is_internal_status_success(invoice.payment_hash, conn):
|
if await is_internal_status_success(invoice.payment_hash, new_conn):
|
||||||
raise PaymentError("Internal invoice already paid.", status="failed")
|
raise PaymentError("Internal invoice already paid.", status="failed")
|
||||||
|
|
||||||
_, extra = await calculate_fiat_amounts(amount_msat / 1000, wallet, extra=extra)
|
_, extra = await calculate_fiat_amounts(amount_msat / 1000, wallet, extra=extra)
|
||||||
|
|
@ -80,8 +82,10 @@ async def pay_invoice(
|
||||||
extra=extra,
|
extra=extra,
|
||||||
)
|
)
|
||||||
|
|
||||||
payment = await _pay_invoice(wallet, create_payment_model, conn)
|
payment = await _pay_invoice(wallet, create_payment_model, conn)
|
||||||
await _credit_service_fee_wallet(payment, conn)
|
|
||||||
|
async with db.reuse_conn(conn) if conn else db.connect() as new_conn:
|
||||||
|
await _credit_service_fee_wallet(payment, new_conn)
|
||||||
|
|
||||||
return payment
|
return payment
|
||||||
|
|
||||||
|
|
@ -580,13 +584,19 @@ async def _pay_external_invoice(
|
||||||
fee_reserve_msat = fee_reserve(amount_msat, internal=False)
|
fee_reserve_msat = fee_reserve(amount_msat, internal=False)
|
||||||
service_fee_msat = service_fee(amount_msat, internal=False)
|
service_fee_msat = service_fee(amount_msat, internal=False)
|
||||||
|
|
||||||
funding_source = get_funding_source()
|
task = create_task(
|
||||||
|
_fundingsource_pay_invoice(checking_id, payment.bolt11, fee_reserve_msat)
|
||||||
logger.debug(f"fundingsource: sending payment {checking_id}")
|
|
||||||
payment_response: PaymentResponse = await funding_source.pay_invoice(
|
|
||||||
create_payment_model.bolt11, fee_reserve_msat
|
|
||||||
)
|
)
|
||||||
logger.debug(f"backend: pay_invoice finished {checking_id}, {payment_response}")
|
|
||||||
|
# make sure a hold invoice or deferred payment is not blocking the server
|
||||||
|
try:
|
||||||
|
wait_time = max(1, settings.lnbits_funding_source_pay_invoice_wait_seconds)
|
||||||
|
payment_response = await asyncio.wait_for(task, wait_time)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# return pending payment on timeout
|
||||||
|
logger.debug(f"payment timeout, {checking_id} is still pending")
|
||||||
|
return payment
|
||||||
|
|
||||||
if payment_response.checking_id and payment_response.checking_id != checking_id:
|
if payment_response.checking_id and payment_response.checking_id != checking_id:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"backend sent unexpected checking_id (expected: {checking_id} got:"
|
f"backend sent unexpected checking_id (expected: {checking_id} got:"
|
||||||
|
|
@ -622,9 +632,22 @@ async def _pay_external_invoice(
|
||||||
"didn't receive checking_id from backend, payment may be stuck in"
|
"didn't receive checking_id from backend, payment may be stuck in"
|
||||||
f" database: {checking_id}"
|
f" database: {checking_id}"
|
||||||
)
|
)
|
||||||
|
|
||||||
return payment
|
return payment
|
||||||
|
|
||||||
|
|
||||||
|
async def _fundingsource_pay_invoice(
|
||||||
|
checking_id: str, bolt11: str, fee_reserve_msat: int
|
||||||
|
) -> PaymentResponse:
|
||||||
|
logger.debug(f"fundingsource: sending payment {checking_id}")
|
||||||
|
funding_source = get_funding_source()
|
||||||
|
payment_response: PaymentResponse = await funding_source.pay_invoice(
|
||||||
|
bolt11, fee_reserve_msat
|
||||||
|
)
|
||||||
|
logger.debug(f"backend: pay_invoice finished {checking_id}, {payment_response}")
|
||||||
|
return payment_response
|
||||||
|
|
||||||
|
|
||||||
async def _verify_external_payment(
|
async def _verify_external_payment(
|
||||||
payment: Payment, conn: Optional[Connection] = None
|
payment: Payment, conn: Optional[Connection] = None
|
||||||
) -> Payment:
|
) -> Payment:
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-col-gutter-md">
|
<div class="row q-col-gutter-md">
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-3">
|
||||||
|
<p><span v-text="$t('fee_reserve')"></span></p>
|
||||||
|
|
||||||
|
<q-input
|
||||||
|
type="number"
|
||||||
|
filled
|
||||||
|
v-model="formData.lnbits_reserve_fee_min"
|
||||||
|
:label="$t('fee_reserve_msats')"
|
||||||
|
>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3">
|
||||||
|
<p><span v-text="$t('fee_reserve_percent')"></span></p>
|
||||||
|
<q-input
|
||||||
|
type="number"
|
||||||
|
filled
|
||||||
|
name="lnbits_reserve_fee_percent"
|
||||||
|
v-model="formData.lnbits_reserve_fee_percent"
|
||||||
|
:label="$t('reserve_fee_in_percent')"
|
||||||
|
step="0.1"
|
||||||
|
></q-input>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-3">
|
||||||
<p><span v-text="$t('invoice_expiry')"></span></p>
|
<p><span v-text="$t('invoice_expiry')"></span></p>
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
|
|
@ -65,29 +87,18 @@
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-8">
|
<div class="col-12 col-md-3">
|
||||||
<p><span v-text="$t('fee_reserve')"></span></p>
|
<p><span v-text="$t('payment_wait_time')"></span></p>
|
||||||
<div class="row q-col-gutter-md">
|
<q-input
|
||||||
<div class="col-6">
|
type="number"
|
||||||
<q-input
|
filled
|
||||||
type="number"
|
name="lnbits_funding_source_pay_invoice_wait_seconds"
|
||||||
filled
|
v-model="formData.lnbits_funding_source_pay_invoice_wait_seconds"
|
||||||
v-model="formData.lnbits_reserve_fee_min"
|
:label="$t('payment_wait_time')"
|
||||||
:label="$t('fee_reserve_msats')"
|
:hint="$t('payment_wait_time_desc')"
|
||||||
>
|
step="1"
|
||||||
</q-input>
|
min="0"
|
||||||
</div>
|
></q-input>
|
||||||
<div class="col-6">
|
|
||||||
<q-input
|
|
||||||
type="number"
|
|
||||||
filled
|
|
||||||
name="lnbits_reserve_fee_percent"
|
|
||||||
v-model="formData.lnbits_reserve_fee_percent"
|
|
||||||
:label="$t('fee_reserve_percent')"
|
|
||||||
step="0.1"
|
|
||||||
></q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isSuperUser">
|
<div v-if="isSuperUser">
|
||||||
|
|
|
||||||
|
|
@ -553,6 +553,9 @@ class FundingSourcesSettings(
|
||||||
BreezSdkFundingSource,
|
BreezSdkFundingSource,
|
||||||
):
|
):
|
||||||
lnbits_backend_wallet_class: str = Field(default="VoidWallet")
|
lnbits_backend_wallet_class: str = Field(default="VoidWallet")
|
||||||
|
# How long to wait for the payment to be confirmed before returning a pending status
|
||||||
|
# It will not fail the payment, it will make it return pending after the timeout
|
||||||
|
lnbits_funding_source_pay_invoice_wait_seconds: int = Field(default=5)
|
||||||
|
|
||||||
|
|
||||||
class WebPushSettings(LNbitsSettings):
|
class WebPushSettings(LNbitsSettings):
|
||||||
|
|
|
||||||
2
lnbits/static/bundle-components.min.js
vendored
2
lnbits/static/bundle-components.min.js
vendored
File diff suppressed because one or more lines are too long
2
lnbits/static/bundle.min.js
vendored
2
lnbits/static/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -89,7 +89,7 @@ window.localisation.br = {
|
||||||
pay: 'Pagar',
|
pay: 'Pagar',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Data',
|
date: 'Data',
|
||||||
processing_payment: 'Processando pagamento...',
|
payment_processing: 'Processando pagamento...',
|
||||||
not_enough_funds: 'Fundos insuficientes!',
|
not_enough_funds: 'Fundos insuficientes!',
|
||||||
search_by_tag_memo_amount: 'Pesquisar por tag, memo, quantidade',
|
search_by_tag_memo_amount: 'Pesquisar por tag, memo, quantidade',
|
||||||
invoice_waiting: 'Fatura aguardando pagamento',
|
invoice_waiting: 'Fatura aguardando pagamento',
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ window.localisation.cn = {
|
||||||
pay: '付款',
|
pay: '付款',
|
||||||
memo: '备注',
|
memo: '备注',
|
||||||
date: '日期',
|
date: '日期',
|
||||||
processing_payment: '正在处理支付...',
|
payment_processing: '正在处理支付...',
|
||||||
not_enough_funds: '资金不足!',
|
not_enough_funds: '资金不足!',
|
||||||
search_by_tag_memo_amount: '按标签、备注、金额搜索',
|
search_by_tag_memo_amount: '按标签、备注、金额搜索',
|
||||||
invoice_waiting: '待支付的发票',
|
invoice_waiting: '待支付的发票',
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ window.localisation.cs = {
|
||||||
pay: 'Platit',
|
pay: 'Platit',
|
||||||
memo: 'Poznámka',
|
memo: 'Poznámka',
|
||||||
date: 'Datum',
|
date: 'Datum',
|
||||||
processing_payment: 'Zpracování platby...',
|
payment_processing: 'Zpracování platby...',
|
||||||
not_enough_funds: 'Nedostatek prostředků!',
|
not_enough_funds: 'Nedostatek prostředků!',
|
||||||
search_by_tag_memo_amount: 'Hledat podle tagu, poznámky, částky',
|
search_by_tag_memo_amount: 'Hledat podle tagu, poznámky, částky',
|
||||||
invoice_waiting: 'Faktura čeká na platbu',
|
invoice_waiting: 'Faktura čeká na platbu',
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ window.localisation.de = {
|
||||||
pay: 'Zahlen',
|
pay: 'Zahlen',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Datum',
|
date: 'Datum',
|
||||||
processing_payment: 'Zahlung wird verarbeitet ...',
|
payment_processing: 'Zahlung wird verarbeitet ...',
|
||||||
not_enough_funds: 'Geldmittel sind erschöpft!',
|
not_enough_funds: 'Geldmittel sind erschöpft!',
|
||||||
search_by_tag_memo_amount: 'Suche nach Tag, Memo, Betrag',
|
search_by_tag_memo_amount: 'Suche nach Tag, Memo, Betrag',
|
||||||
invoice_waiting: 'Rechnung wartend auf Zahlung',
|
invoice_waiting: 'Rechnung wartend auf Zahlung',
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,11 @@ window.localisation.en = {
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Date',
|
date: 'Date',
|
||||||
path: 'Path',
|
path: 'Path',
|
||||||
processing_payment: 'Processing payment...',
|
payment_processing: 'Processing payment...',
|
||||||
|
payment_processing: 'Processing payment...',
|
||||||
|
payment_successful: 'Payment successful!',
|
||||||
|
payment_pending: 'Payment pending...',
|
||||||
|
payment_check: 'Check payment',
|
||||||
not_enough_funds: 'Not enough funds!',
|
not_enough_funds: 'Not enough funds!',
|
||||||
search_by_tag_memo_amount: 'Search by tag, memo, amount',
|
search_by_tag_memo_amount: 'Search by tag, memo, amount',
|
||||||
invoice_waiting: 'Invoice waiting to be paid',
|
invoice_waiting: 'Invoice waiting to be paid',
|
||||||
|
|
@ -411,8 +415,12 @@ window.localisation.en = {
|
||||||
invoice_expiry: 'Invoice Expiry',
|
invoice_expiry: 'Invoice Expiry',
|
||||||
invoice_expiry_label: 'Invoice expiry (seconds)',
|
invoice_expiry_label: 'Invoice expiry (seconds)',
|
||||||
fee_reserve: 'Fee Reserve',
|
fee_reserve: 'Fee Reserve',
|
||||||
|
fee_reserve_percent: 'Fee Reserve Percent',
|
||||||
fee_reserve_msats: 'Reserve fee in msats',
|
fee_reserve_msats: 'Reserve fee in msats',
|
||||||
fee_reserve_percent: 'Reserve fee in percent',
|
reserve_fee_in_percent: 'Reserve fee in percent',
|
||||||
|
payment_wait_time: 'Payment Wait Time',
|
||||||
|
payment_wait_time_desc:
|
||||||
|
'How long to wait when making a payment before marking it as pending. Set higher values for HODL invoices, Boltz, etc.',
|
||||||
server_management: 'Server Management',
|
server_management: 'Server Management',
|
||||||
base_url: 'Base URL',
|
base_url: 'Base URL',
|
||||||
base_url_label: 'Static/Base url for the server',
|
base_url_label: 'Static/Base url for the server',
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ window.localisation.es = {
|
||||||
pay: 'Pagar',
|
pay: 'Pagar',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Fecha',
|
date: 'Fecha',
|
||||||
processing_payment: 'Procesando pago ...',
|
payment_processing: 'Procesando pago ...',
|
||||||
not_enough_funds: '¡No hay suficientes fondos!',
|
not_enough_funds: '¡No hay suficientes fondos!',
|
||||||
search_by_tag_memo_amount: 'Buscar por etiqueta, memo, cantidad',
|
search_by_tag_memo_amount: 'Buscar por etiqueta, memo, cantidad',
|
||||||
invoice_waiting: 'Factura esperando pago',
|
invoice_waiting: 'Factura esperando pago',
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ window.localisation.fi = {
|
||||||
memo: 'Kuvaus',
|
memo: 'Kuvaus',
|
||||||
date: 'Päiväys',
|
date: 'Päiväys',
|
||||||
path: 'Path',
|
path: 'Path',
|
||||||
processing_payment: 'Maksua käsitellään...',
|
payment_processing: 'Maksua käsitellään...',
|
||||||
not_enough_funds: 'Varat eivät riitä!',
|
not_enough_funds: 'Varat eivät riitä!',
|
||||||
search_by_tag_memo_amount: 'Etsi tunnisteella, muistiolla tai määrällä',
|
search_by_tag_memo_amount: 'Etsi tunnisteella, muistiolla tai määrällä',
|
||||||
invoice_waiting: 'Lasku osottaa maksamista',
|
invoice_waiting: 'Lasku osottaa maksamista',
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ window.localisation.fr = {
|
||||||
pay: 'Payer',
|
pay: 'Payer',
|
||||||
memo: 'Mémo',
|
memo: 'Mémo',
|
||||||
date: 'Date',
|
date: 'Date',
|
||||||
processing_payment: 'Traitement du paiement...',
|
payment_processing: 'Traitement du paiement...',
|
||||||
not_enough_funds: 'Fonds insuffisants !',
|
not_enough_funds: 'Fonds insuffisants !',
|
||||||
search_by_tag_memo_amount: 'Rechercher par tag, mémo, montant',
|
search_by_tag_memo_amount: 'Rechercher par tag, mémo, montant',
|
||||||
invoice_waiting: 'Facture en attente de paiement',
|
invoice_waiting: 'Facture en attente de paiement',
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ window.localisation.it = {
|
||||||
pay: 'Paga',
|
pay: 'Paga',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Dati',
|
date: 'Dati',
|
||||||
processing_payment: 'Elaborazione pagamento...',
|
payment_processing: 'Elaborazione pagamento...',
|
||||||
not_enough_funds: 'Non ci sono abbastanza fondi!',
|
not_enough_funds: 'Non ci sono abbastanza fondi!',
|
||||||
search_by_tag_memo_amount: 'Cerca per tag, memo, importo...',
|
search_by_tag_memo_amount: 'Cerca per tag, memo, importo...',
|
||||||
invoice_waiting: 'Fattura in attesa di pagamento',
|
invoice_waiting: 'Fattura in attesa di pagamento',
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ window.localisation.jp = {
|
||||||
pay: '支払う',
|
pay: '支払う',
|
||||||
memo: 'メモ',
|
memo: 'メモ',
|
||||||
date: '日付',
|
date: '日付',
|
||||||
processing_payment: '支払い処理中',
|
payment_processing: '支払い処理中',
|
||||||
not_enough_funds: '資金が不足しています',
|
not_enough_funds: '資金が不足しています',
|
||||||
search_by_tag_memo_amount: 'タグ、メモ、金額で検索',
|
search_by_tag_memo_amount: 'タグ、メモ、金額で検索',
|
||||||
invoice_waiting: '請求書を待っています',
|
invoice_waiting: '請求書を待っています',
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ window.localisation.kr = {
|
||||||
pay: '지불하기',
|
pay: '지불하기',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: '일시',
|
date: '일시',
|
||||||
processing_payment: '결제 처리 중...',
|
payment_processing: '결제 처리 중...',
|
||||||
not_enough_funds: '자금이 부족합니다!',
|
not_enough_funds: '자금이 부족합니다!',
|
||||||
search_by_tag_memo_amount: '태그, memo, 수량으로 검색하기',
|
search_by_tag_memo_amount: '태그, memo, 수량으로 검색하기',
|
||||||
invoice_waiting: '결제를 기다리는 인보이스',
|
invoice_waiting: '결제를 기다리는 인보이스',
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ window.localisation.nl = {
|
||||||
pay: 'Betalen',
|
pay: 'Betalen',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Datum',
|
date: 'Datum',
|
||||||
processing_payment: 'Verwerking betaling...',
|
payment_processing: 'Verwerking betaling...',
|
||||||
not_enough_funds: 'Onvoldoende saldo!',
|
not_enough_funds: 'Onvoldoende saldo!',
|
||||||
search_by_tag_memo_amount: 'Zoeken op tag, memo, bedrag',
|
search_by_tag_memo_amount: 'Zoeken op tag, memo, bedrag',
|
||||||
invoice_waiting: 'Factuur wachtend op betaling',
|
invoice_waiting: 'Factuur wachtend op betaling',
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ window.localisation.pi = {
|
||||||
pay: 'Pay up or walk the plank, ye scallywag',
|
pay: 'Pay up or walk the plank, ye scallywag',
|
||||||
memo: 'Message in a bottle, argh',
|
memo: 'Message in a bottle, argh',
|
||||||
date: 'Date of the map, me matey',
|
date: 'Date of the map, me matey',
|
||||||
processing_payment: 'Processing yer payment... don´t make me say it again',
|
payment_processing: 'Processing yer payment... don´t make me say it again',
|
||||||
not_enough_funds: 'Arrr, ye don´t have enough doubloons! Walk the plank!',
|
not_enough_funds: 'Arrr, ye don´t have enough doubloons! Walk the plank!',
|
||||||
search_by_tag_memo_amount: 'Search by tag, message, or booty amount, savvy',
|
search_by_tag_memo_amount: 'Search by tag, message, or booty amount, savvy',
|
||||||
invoice_waiting: 'Invoice waiting to be plundered, arrr',
|
invoice_waiting: 'Invoice waiting to be plundered, arrr',
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ window.localisation.pl = {
|
||||||
pay: 'Zapłać',
|
pay: 'Zapłać',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Data',
|
date: 'Data',
|
||||||
processing_payment: 'Przetwarzam płatność...',
|
payment_processing: 'Przetwarzam płatność...',
|
||||||
not_enough_funds: 'Brak wystarczających środków!',
|
not_enough_funds: 'Brak wystarczających środków!',
|
||||||
search_by_tag_memo_amount: 'Szukaj po tagu, memo czy wartości',
|
search_by_tag_memo_amount: 'Szukaj po tagu, memo czy wartości',
|
||||||
invoice_waiting: 'Faktura oczekuje na zapłatę',
|
invoice_waiting: 'Faktura oczekuje na zapłatę',
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ window.localisation.pt = {
|
||||||
pay: 'Pagar',
|
pay: 'Pagar',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Data',
|
date: 'Data',
|
||||||
processing_payment: 'Processando pagamento...',
|
payment_processing: 'Processando pagamento...',
|
||||||
not_enough_funds: 'Fundos insuficientes!',
|
not_enough_funds: 'Fundos insuficientes!',
|
||||||
search_by_tag_memo_amount: 'Pesquisar por tag, memo, quantidade',
|
search_by_tag_memo_amount: 'Pesquisar por tag, memo, quantidade',
|
||||||
invoice_waiting: 'Fatura aguardando pagamento',
|
invoice_waiting: 'Fatura aguardando pagamento',
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ window.localisation.sk = {
|
||||||
pay: 'Platiť',
|
pay: 'Platiť',
|
||||||
memo: 'Poznámka',
|
memo: 'Poznámka',
|
||||||
date: 'Dátum',
|
date: 'Dátum',
|
||||||
processing_payment: 'Spracovávanie platby...',
|
payment_processing: 'Spracovávanie platby...',
|
||||||
not_enough_funds: 'Nedostatok prostriedkov!',
|
not_enough_funds: 'Nedostatok prostriedkov!',
|
||||||
search_by_tag_memo_amount: 'Vyhľadať podľa značky, poznámky, sumy',
|
search_by_tag_memo_amount: 'Vyhľadať podľa značky, poznámky, sumy',
|
||||||
invoice_waiting: 'Faktúra čakajúca na zaplatenie',
|
invoice_waiting: 'Faktúra čakajúca na zaplatenie',
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ window.localisation.we = {
|
||||||
pay: 'Talu',
|
pay: 'Talu',
|
||||||
memo: 'Memo',
|
memo: 'Memo',
|
||||||
date: 'Dyddiad',
|
date: 'Dyddiad',
|
||||||
processing_payment: 'Prosesu taliad...',
|
payment_processing: 'Prosesu taliad...',
|
||||||
not_enough_funds: 'Dim digon o arian!',
|
not_enough_funds: 'Dim digon o arian!',
|
||||||
search_by_tag_memo_amount: 'Chwilio yn ôl tag, memo, swm',
|
search_by_tag_memo_amount: 'Chwilio yn ôl tag, memo, swm',
|
||||||
invoice_waiting: 'Anfoneb yn aros i gael ei thalu',
|
invoice_waiting: 'Anfoneb yn aros i gael ei thalu',
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,26 @@ window.app.component('payment-list', {
|
||||||
LNbits.utils.notifyApiError(err)
|
LNbits.utils.notifyApiError(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
checkPayment(payment_hash) {
|
||||||
|
LNbits.api
|
||||||
|
.getPayment(this.g.wallet, payment_hash)
|
||||||
|
.then(res => {
|
||||||
|
this.update = !this.update
|
||||||
|
if (res.data.status == 'success') {
|
||||||
|
Quasar.Notify.create({
|
||||||
|
type: 'positive',
|
||||||
|
message: this.$t('payment_successful')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (res.data.status == 'pending') {
|
||||||
|
Quasar.Notify.create({
|
||||||
|
type: 'info',
|
||||||
|
message: this.$t('payment_pending')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(LNbits.utils.notifyApiError)
|
||||||
|
},
|
||||||
paymentTableRowKey(row) {
|
paymentTableRowKey(row) {
|
||||||
return row.payment_hash + row.amount
|
return row.payment_hash + row.amount
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -463,22 +463,27 @@ window.WalletPageLogic = {
|
||||||
payInvoice() {
|
payInvoice() {
|
||||||
const dismissPaymentMsg = Quasar.Notify.create({
|
const dismissPaymentMsg = Quasar.Notify.create({
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
message: this.$t('processing_payment')
|
message: this.$t('payment_processing')
|
||||||
})
|
})
|
||||||
|
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.payInvoice(this.g.wallet, this.parse.data.request)
|
.payInvoice(this.g.wallet, this.parse.data.request)
|
||||||
.then(_ => {
|
.then(response => {
|
||||||
clearInterval(this.parse.paymentChecker)
|
dismissPaymentMsg()
|
||||||
setTimeout(() => {
|
this.updatePayments = !this.updatePayments
|
||||||
clearInterval(this.parse.paymentChecker)
|
this.parse.show = false
|
||||||
}, 40000)
|
if (response.data.status == 'success') {
|
||||||
this.parse.paymentChecker = setInterval(() => {
|
Quasar.Notify.create({
|
||||||
if (!this.parse.show) {
|
type: 'positive',
|
||||||
dismissPaymentMsg()
|
message: this.$t('payment_successful')
|
||||||
clearInterval(this.parse.paymentChecker)
|
})
|
||||||
}
|
}
|
||||||
}, 2000)
|
if (response.data.status == 'pending') {
|
||||||
|
Quasar.Notify.create({
|
||||||
|
type: 'info',
|
||||||
|
message: this.$t('payment_pending')
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
dismissPaymentMsg()
|
dismissPaymentMsg()
|
||||||
|
|
|
||||||
|
|
@ -949,6 +949,13 @@
|
||||||
@click="copyText(props.row.bolt11)"
|
@click="copyText(props.row.bolt11)"
|
||||||
:label="$t('copy_invoice')"
|
:label="$t('copy_invoice')"
|
||||||
></q-btn>
|
></q-btn>
|
||||||
|
<q-btn
|
||||||
|
outline
|
||||||
|
color="grey"
|
||||||
|
@click="checkPayment(props.row.payment_hash)"
|
||||||
|
icon="refresh"
|
||||||
|
:label="$t('payment_check')"
|
||||||
|
></q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
v-close-popup
|
v-close-popup
|
||||||
flat
|
flat
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue