Compare commits
28 Commits
v1.10.0-rc
...
changlog
Author | SHA1 | Date | |
---|---|---|---|
6d0f9120b8 | |||
aafb4a7f2a | |||
ae432ff237 | |||
cdc318c71a | |||
94d1cec8a9 | |||
c0bc19ea59 | |||
6f07714cd9 | |||
a9d2cac23c | |||
693b46126b | |||
bbff9710bf | |||
358e122775 | |||
3818468932 | |||
3d2554fbe1 | |||
4309603317 | |||
f733c9ea77 | |||
775ee01171 | |||
33ec790137 | |||
0c575c888c | |||
24f7e51e3a | |||
0a0cf97c55 | |||
16b988d097 | |||
5edc0ff6ef | |||
375b96e508 | |||
1e72b12074 | |||
4a6d52f78e | |||
35dd580e74 | |||
79836ef1de | |||
8cb06f9c6c |
@ -12,6 +12,8 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryUrl>https://github.com/btcpayserver/btcpayserver</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Configurations>Debug;Release;Altcoins-Debug;Altcoins-Release</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Version Condition=" '$(Version)' == '' ">1.7.2</Version>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.2.3" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.2.5" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Altcoins)' != 'true'">
|
||||
|
@ -306,6 +306,8 @@ retry:
|
||||
foreach ((CurrencyPair key, Task<RateResult> value) in result)
|
||||
{
|
||||
var rateResult = value.GetAwaiter().GetResult();
|
||||
if (key.ToString() == "BTG_USD")
|
||||
continue; // shitcoin not supported by bitfinex anymore
|
||||
TestLogs.LogInformation($"Testing {key}");
|
||||
if (brokenShitcoins.Contains(key.ToString()))
|
||||
continue;
|
||||
|
@ -73,7 +73,7 @@ services:
|
||||
- "sshd_datadir:/root/.ssh"
|
||||
|
||||
devlnd:
|
||||
image: btcpayserver/bitcoin:24.1-1
|
||||
image: btcpayserver/bitcoin:25.0
|
||||
environment:
|
||||
BITCOIN_NETWORK: regtest
|
||||
BITCOIN_WALLETDIR: "/data/wallets"
|
||||
@ -135,7 +135,7 @@ services:
|
||||
|
||||
bitcoind:
|
||||
restart: unless-stopped
|
||||
image: btcpayserver/bitcoin:24.1-1
|
||||
image: btcpayserver/bitcoin:25.0
|
||||
environment:
|
||||
BITCOIN_NETWORK: regtest
|
||||
BITCOIN_WALLETDIR: "/data/wallets"
|
||||
|
@ -70,7 +70,7 @@ services:
|
||||
- "sshd_datadir:/root/.ssh"
|
||||
|
||||
devlnd:
|
||||
image: btcpayserver/bitcoin:24.1-1
|
||||
image: btcpayserver/bitcoin:25.0
|
||||
environment:
|
||||
BITCOIN_NETWORK: regtest
|
||||
BITCOIN_WALLETDIR: "/data/wallets"
|
||||
@ -121,7 +121,7 @@ services:
|
||||
|
||||
bitcoind:
|
||||
restart: unless-stopped
|
||||
image: btcpayserver/bitcoin:24.1-1
|
||||
image: btcpayserver/bitcoin:25.0
|
||||
environment:
|
||||
BITCOIN_NETWORK: regtest
|
||||
BITCOIN_WALLETDIR: "/data/wallets"
|
||||
|
@ -23,15 +23,17 @@
|
||||
@if (Model.Balance.OffchainBalance != null)
|
||||
{
|
||||
<div class="balance">
|
||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOffchain" data-sensitive>@Model.TotalOffchain</h3>
|
||||
<span class="text-secondary fw-semibold text-nowrap">
|
||||
<span class="currency">@Model.CryptoCode</span> in channels
|
||||
</span>
|
||||
<div class="d-flex align-items-baseline gap-1">
|
||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOffchain" data-sensitive>@Model.TotalOffchain</h3>
|
||||
<span class="text-secondary fw-semibold text-nowrap">
|
||||
<span class="currency">@Model.CryptoCode</span> in channels
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="balance-details collapse" id="balanceDetailsOffchain">
|
||||
@if (Model.Balance.OffchainBalance.Opening != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OffchainBalance.Opening" data-sensitive>
|
||||
@Model.Balance.OffchainBalance.Opening
|
||||
</span>
|
||||
@ -42,7 +44,7 @@
|
||||
}
|
||||
@if (Model.Balance.OffchainBalance.Local != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OffchainBalance.Local" data-sensitive>
|
||||
@Model.Balance.OffchainBalance.Local
|
||||
</span>
|
||||
@ -53,7 +55,7 @@
|
||||
}
|
||||
@if (Model.Balance.OffchainBalance.Remote != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OffchainBalance.Remote" data-sensitive>
|
||||
@Model.Balance.OffchainBalance.Remote
|
||||
</span>
|
||||
@ -64,7 +66,7 @@
|
||||
}
|
||||
@if (Model.Balance.OffchainBalance.Closing != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OffchainBalance.Closing" data-sensitive>
|
||||
@Model.Balance.OffchainBalance.Closing
|
||||
</span>
|
||||
@ -79,14 +81,16 @@
|
||||
@if (Model.Balance.OnchainBalance != null)
|
||||
{
|
||||
<div class="balance">
|
||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOnchain" data-sensitive>@Model.TotalOnchain</h3>
|
||||
<span class="text-secondary fw-semibold text-nowrap">
|
||||
<span class="currency">@Model.CryptoCode</span> on-chain
|
||||
</span>
|
||||
<div class="d-flex align-items-baseline gap-1">
|
||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOnchain" data-sensitive>@Model.TotalOnchain</h3>
|
||||
<span class="text-secondary fw-semibold text-nowrap">
|
||||
<span class="currency">@Model.CryptoCode</span> on-chain
|
||||
</span>
|
||||
</div>
|
||||
<div class="balance-details collapse" id="balanceDetailsOnchain">
|
||||
@if (Model.Balance.OnchainBalance.Confirmed != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OnchainBalance.Confirmed" data-sensitive>
|
||||
@Model.Balance.OnchainBalance.Confirmed
|
||||
</span>
|
||||
@ -97,7 +101,7 @@
|
||||
}
|
||||
@if (Model.Balance.OnchainBalance.Unconfirmed != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OnchainBalance.Unconfirmed" data-sensitive>
|
||||
@Model.Balance.OnchainBalance.Unconfirmed
|
||||
</span>
|
||||
@ -108,7 +112,7 @@
|
||||
}
|
||||
@if (Model.Balance.OnchainBalance.Reserved != null)
|
||||
{
|
||||
<div class="mt-2">
|
||||
<div class="mt-2 d-flex align-items-baseline gap-1">
|
||||
<span class="fw-semibold" data-balance="@Model.Balance.OnchainBalance.Reserved" data-sensitive>
|
||||
@Model.Balance.OnchainBalance.Reserved
|
||||
</span>
|
||||
|
@ -3,7 +3,6 @@
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Services
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@inject BTCPayServerEnvironment Env
|
||||
@inject IFileService FileService
|
||||
@model BTCPayServer.Components.StoreSelector.StoreSelectorViewModel
|
||||
@ -33,8 +32,7 @@
|
||||
else
|
||||
{
|
||||
<a asp-controller="UIStores" asp-action="Dashboard" permission="@Policies.CanModifyStoreSettings" asp-route-storeId="@Model.CurrentStoreId" id="StoreSelectorHome" class="navbar-brand py-2">@{await LogoContent();}</a>
|
||||
|
||||
<a asp-controller="UIInvoice" asp-action="ListInvoices" not-permission="@Policies.CanModifyStoreSettings" asp-route-storeId="@Model.CurrentStoreId" id="StoreSelectorHome" class="navbar-brand py-2">@{await LogoContent();}</a>
|
||||
<a asp-controller="UIInvoice" asp-action="ListInvoices" not-permission="@Policies.CanModifyStoreSettings" asp-route-storeId="@Model.CurrentStoreId" id="StoreSelectorHome" class="navbar-brand py-2">@{await LogoContent();}</a>
|
||||
}
|
||||
@if (Model.Options.Any())
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
@ -38,12 +39,14 @@ namespace BTCPayServer.Components.StoreSelector
|
||||
.FirstOrDefault()?
|
||||
.Network.CryptoCode;
|
||||
var walletId = cryptoCode != null ? new WalletId(store.Id, cryptoCode) : null;
|
||||
var role = store.GetStoreRoleOfUser(userId);
|
||||
return new StoreSelectorOption
|
||||
{
|
||||
Text = store.StoreName,
|
||||
Value = store.Id,
|
||||
Selected = store.Id == currentStore?.Id,
|
||||
WalletId = walletId
|
||||
WalletId = walletId,
|
||||
IsOwner = role != null && role.Permissions.Contains(Policies.CanModifyStoreSettings)
|
||||
};
|
||||
})
|
||||
.OrderBy(s => s.Text)
|
||||
|
@ -17,7 +17,7 @@
|
||||
<header class="mb-3">
|
||||
@if (Model.Balance != null)
|
||||
{
|
||||
<div class="balance">
|
||||
<div class="balance d-flex align-items-baseline gap-1">
|
||||
<h3 class="d-inline-block me-1" data-balance="@Model.Balance" data-sensitive>@Model.Balance</h3>
|
||||
<span class="text-secondary fw-semibold currency">@Model.CryptoCode</span>
|
||||
</div>
|
||||
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Amazon.S3.Transfer;
|
||||
using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
@ -167,9 +166,17 @@ namespace BTCPayServer.Controllers
|
||||
[FromServices] StoreRepository storeRepository,
|
||||
string role)
|
||||
{
|
||||
await storeRepository.SetDefaultRole(role);
|
||||
|
||||
TempData[WellKnownTempData.SuccessMessage] = "Role set default";
|
||||
var resolved = await storeRepository.ResolveStoreRoleId(null, role);
|
||||
if (resolved is null)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = "Role could not be set as default";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
await storeRepository.SetDefaultRole(role);
|
||||
TempData[WellKnownTempData.SuccessMessage] = "Role set default";
|
||||
}
|
||||
|
||||
return RedirectToAction(nameof(ListRoles));
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -250,7 +251,7 @@ namespace BTCPayServer.Controllers
|
||||
CryptoCode = cryptoCode,
|
||||
Method = method,
|
||||
SetupRequest = request,
|
||||
Confirmation = string.IsNullOrEmpty(request.ExistingMnemonic),
|
||||
Confirmation = !isImport,
|
||||
Network = network,
|
||||
Source = isImport ? "SeedImported" : "NBXplorerGenerated",
|
||||
IsHotWallet = isImport ? request.SavePrivateKeys : method == WalletSetupMethod.HotWallet,
|
||||
@ -311,7 +312,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
var result = await UpdateWallet(vm);
|
||||
|
||||
if (!ModelState.IsValid || !(result is RedirectToActionResult))
|
||||
if (!ModelState.IsValid || result is not RedirectToActionResult)
|
||||
return result;
|
||||
|
||||
if (!isImport)
|
||||
|
@ -141,7 +141,7 @@ namespace BTCPayServer.Controllers
|
||||
"Delete"));
|
||||
}
|
||||
|
||||
[HttpPost("{storeId}/roles/{roleId}/delete")]
|
||||
[HttpPost("{storeId}/roles/{role}/delete")]
|
||||
public async Task<IActionResult> DeleteRolePost(
|
||||
string storeId,
|
||||
[FromServices] StoreRepository storeRepository,
|
||||
|
@ -111,12 +111,6 @@ namespace BTCPayServer.Hosting
|
||||
settings.DeprecatedLightningConnectionStringCheck = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
if (!settings.UnreachableStoreCheck)
|
||||
{
|
||||
await UnreachableStoreCheck();
|
||||
settings.UnreachableStoreCheck = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
if (!settings.ConvertMultiplierToSpread)
|
||||
{
|
||||
await ConvertMultiplierToSpread();
|
||||
@ -657,13 +651,6 @@ WHERE cte.""Id""=p.""Id""
|
||||
settings1.TargetCurrency = app.StoreData.GetStoreBlob().DefaultCurrency;
|
||||
app.SetSettings(settings1);
|
||||
}
|
||||
items = AppService.Parse(settings1.PerksTemplate);
|
||||
newTemplate = AppService.SerializeTemplate(items);
|
||||
if (settings1.PerksTemplate != newTemplate)
|
||||
{
|
||||
settings1.PerksTemplate = newTemplate;
|
||||
app.SetSettings(settings1);
|
||||
};
|
||||
break;
|
||||
|
||||
case PointOfSaleAppType.AppType:
|
||||
@ -674,13 +661,6 @@ WHERE cte.""Id""=p.""Id""
|
||||
settings2.Currency = app.StoreData.GetStoreBlob().DefaultCurrency;
|
||||
app.SetSettings(settings2);
|
||||
}
|
||||
items = AppService.Parse(settings2.Template);
|
||||
newTemplate = AppService.SerializeTemplate(items);
|
||||
if (settings2.Template != newTemplate)
|
||||
{
|
||||
settings2.Template = newTemplate;
|
||||
app.SetSettings(settings2);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1068,11 +1048,6 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
private Task UnreachableStoreCheck()
|
||||
{
|
||||
return _StoreRepository.CleanUnreachableStores();
|
||||
}
|
||||
|
||||
private async Task DeprecatedLightningConnectionStringCheck()
|
||||
{
|
||||
using var ctx = _DBContextFactory.CreateContext();
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using NBXplorer.Models;
|
||||
|
||||
namespace BTCPayServer.Models.StoreViewModels
|
||||
|
@ -60,6 +60,11 @@ namespace BTCPayServer.Plugins.PayButton.Controllers
|
||||
}
|
||||
|
||||
var apps = await _appService.GetAllApps(_userManager.GetUserId(User), false, store.Id);
|
||||
// unset app store data, because we don't need it and inclusion leads to circular references when serializing to JSON
|
||||
foreach (var app in apps)
|
||||
{
|
||||
app.App.StoreData = null;
|
||||
}
|
||||
var appUrl = HttpContext.Request.GetAbsoluteRoot().WithTrailingSlash();
|
||||
var model = new PayButtonViewModel
|
||||
{
|
||||
|
@ -240,6 +240,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
}
|
||||
|
||||
var store = await _appService.GetStore(app);
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var posFormId = settings.FormId;
|
||||
var formData = await FormDataService.GetForm(posFormId);
|
||||
|
||||
@ -297,7 +298,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
RedirectAutomatically = settings.RedirectAutomatically,
|
||||
SupportedTransactionCurrencies = paymentMethods,
|
||||
RequiresRefundEmail = requiresRefundEmail == RequiresRefundEmail.InheritFromStore
|
||||
? store.GetStoreBlob().RequiresRefundEmail
|
||||
? storeBlob.RequiresRefundEmail
|
||||
: requiresRefundEmail == RequiresRefundEmail.On,
|
||||
}, store, HttpContext.Request.GetAbsoluteRoot(),
|
||||
new List<string> { AppService.GetAppInternalTag(appId) },
|
||||
@ -355,6 +356,10 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
meta.Merge(formResponseJObject);
|
||||
entity.Metadata = InvoiceMetadata.FromJObject(meta);
|
||||
});
|
||||
if (price is 0 && storeBlob.ReceiptOptions?.Enabled is true)
|
||||
{
|
||||
return RedirectToAction(nameof(UIInvoiceController.InvoiceReceipt), "UIInvoice", new { invoiceId = invoice.Data.Id });
|
||||
}
|
||||
return RedirectToAction(nameof(UIInvoiceController.Checkout), "UIInvoice", new { invoiceId = invoice.Data.Id });
|
||||
}
|
||||
catch (BitpayHttpException e)
|
||||
|
@ -51,7 +51,6 @@ namespace BTCPayServer.Plugins.PointOfSale
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
private readonly IOptions<BTCPayServerOptions> _btcPayServerOptions;
|
||||
private readonly DisplayFormatter _displayFormatter;
|
||||
private readonly HtmlSanitizer _htmlSanitizer;
|
||||
public const string AppType = "PointOfSale";
|
||||
|
||||
public PointOfSaleAppType(
|
||||
@ -65,7 +64,6 @@ namespace BTCPayServer.Plugins.PointOfSale
|
||||
_linkGenerator = linkGenerator;
|
||||
_btcPayServerOptions = btcPayServerOptions;
|
||||
_displayFormatter = displayFormatter;
|
||||
_htmlSanitizer = htmlSanitizer;
|
||||
}
|
||||
|
||||
public override Task<string> ConfigureLink(AppData app)
|
||||
|
@ -176,7 +176,7 @@ namespace BTCPayServer.Services.Apps
|
||||
res.Add(new InvoiceStatsItem
|
||||
{
|
||||
ItemCode = item.Id,
|
||||
FiatPrice = lineItem.Price.Value,
|
||||
FiatPrice = lineItem.Price,
|
||||
Date = e.InvoiceTime.Date
|
||||
});
|
||||
}
|
||||
|
@ -34,44 +34,44 @@ namespace BTCPayServer.Services.Apps
|
||||
new()
|
||||
{
|
||||
Id = "rooibos",
|
||||
Title = "Rooibos",
|
||||
Title = "Rooibos (limited)",
|
||||
Description =
|
||||
"Rooibos is a dramatic red tea made from a South African herb that contains polyphenols and flavonoids. Often called 'African redbush tea', Rooibos herbal tea delights the senses and delivers potential health benefits with each caffeine-free sip.",
|
||||
Image = "~/img/pos-sample/rooibos.jpg",
|
||||
PriceType = ViewPointOfSaleViewModel.ItemPriceType.Fixed,
|
||||
Price = 1.2m
|
||||
Price = 1.2m,
|
||||
Inventory = 5,
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = "pu-erh",
|
||||
Title = "Pu Erh",
|
||||
Title = "Pu Erh (free)",
|
||||
Description =
|
||||
"This loose pur-erh tea is produced in Yunnan Province, China. The process in a relatively high humidity environment has mellowed the elemental character of the tea when compared to young Pu-erh.",
|
||||
Image = "~/img/pos-sample/pu-erh.jpg",
|
||||
PriceType = ViewPointOfSaleViewModel.ItemPriceType.Fixed,
|
||||
Price = 2
|
||||
Price = 0
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = "herbal-tea",
|
||||
Title = "Herbal Tea",
|
||||
Title = "Herbal Tea (minimum)",
|
||||
Description =
|
||||
"Chamomile tea is made from the flower heads of the chamomile plant. The medicinal use of chamomile dates back to the ancient Egyptians, Romans and Greeks. Pay us what you want!",
|
||||
Image = "~/img/pos-sample/herbal-tea.jpg",
|
||||
PriceType = ViewPointOfSaleViewModel.ItemPriceType.Minimum,
|
||||
Price = 1.8m,
|
||||
Disabled = true
|
||||
Disabled = false
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = "fruit-tea",
|
||||
Title = "Fruit Tea",
|
||||
Title = "Fruit Tea (any amount)",
|
||||
Description =
|
||||
"The Tibetan Himalayas, the land is majestic and beautiful—a spiritual place where, despite the perilous environment, many journey seeking enlightenment. Pay us what you want!",
|
||||
Image = "~/img/pos-sample/fruit-tea.jpg",
|
||||
PriceType = ViewPointOfSaleViewModel.ItemPriceType.Topup,
|
||||
Inventory = 5,
|
||||
Disabled = true
|
||||
Disabled = false
|
||||
}
|
||||
});
|
||||
DefaultView = PosViewType.Static;
|
||||
|
@ -834,20 +834,13 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
public bool CanMarkComplete()
|
||||
{
|
||||
return (Status == InvoiceStatusLegacy.Paid) ||
|
||||
(Status == InvoiceStatusLegacy.New) ||
|
||||
((Status == InvoiceStatusLegacy.New || Status == InvoiceStatusLegacy.Expired) && ExceptionStatus == InvoiceExceptionStatus.PaidPartial) ||
|
||||
((Status == InvoiceStatusLegacy.New || Status == InvoiceStatusLegacy.Expired) && ExceptionStatus == InvoiceExceptionStatus.PaidLate) ||
|
||||
(Status != InvoiceStatusLegacy.Complete && ExceptionStatus == InvoiceExceptionStatus.Marked) ||
|
||||
(Status == InvoiceStatusLegacy.Invalid);
|
||||
return Status is InvoiceStatusLegacy.New or InvoiceStatusLegacy.Paid or InvoiceStatusLegacy.Expired or InvoiceStatusLegacy.Invalid ||
|
||||
(Status != InvoiceStatusLegacy.Complete && ExceptionStatus == InvoiceExceptionStatus.Marked);
|
||||
}
|
||||
|
||||
public bool CanMarkInvalid()
|
||||
{
|
||||
return (Status == InvoiceStatusLegacy.Paid) ||
|
||||
(Status == InvoiceStatusLegacy.New) ||
|
||||
((Status == InvoiceStatusLegacy.New || Status == InvoiceStatusLegacy.Expired) && ExceptionStatus == InvoiceExceptionStatus.PaidPartial) ||
|
||||
((Status == InvoiceStatusLegacy.New || Status == InvoiceStatusLegacy.Expired) && ExceptionStatus == InvoiceExceptionStatus.PaidLate) ||
|
||||
return Status is InvoiceStatusLegacy.New or InvoiceStatusLegacy.Paid or InvoiceStatusLegacy.Expired ||
|
||||
(Status != InvoiceStatusLegacy.Invalid && ExceptionStatus == InvoiceExceptionStatus.Marked);
|
||||
}
|
||||
|
||||
|
@ -521,8 +521,14 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
invoiceData.Status = legacyStatus.ToLowerInvariant();
|
||||
invoiceData.ExceptionStatus = InvoiceExceptionStatus.Marked.ToString().ToLowerInvariant();
|
||||
_eventAggregator.Publish(new InvoiceEvent(ToEntity(invoiceData), eventName));
|
||||
await context.SaveChangesAsync();
|
||||
try
|
||||
{
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_eventAggregator.Publish(new InvoiceEvent(ToEntity(invoiceData), eventName));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -34,7 +34,7 @@ public class PosAppCartItem
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "price")]
|
||||
public PosAppCartItemPrice Price { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "title")]
|
||||
public string Title { get; set; }
|
||||
@ -54,8 +54,6 @@ public class PosAppCartItemPrice
|
||||
[JsonProperty(PropertyName = "formatted")]
|
||||
public string Formatted { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "value")]
|
||||
public decimal Value { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "type")]
|
||||
public ViewPointOfSaleViewModel.ItemPriceType Type { get; set; }
|
||||
|
@ -7,7 +7,6 @@ namespace BTCPayServer.Services
|
||||
[JsonProperty("MigrateHotwalletProperty2")]
|
||||
public bool MigrateHotwalletProperty { get; set; }
|
||||
public bool MigrateU2FToFIDO2 { get; set; }
|
||||
public bool UnreachableStoreCheck { get; set; }
|
||||
public bool DeprecatedLightningConnectionStringCheck { get; set; }
|
||||
public bool ConvertMultiplierToSpread { get; set; }
|
||||
public bool ConvertNetworkFeeProperty { get; set; }
|
||||
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Amazon.S3;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
@ -229,17 +230,19 @@ namespace BTCPayServer.Services.Stores
|
||||
/// <param name="storeId"></param>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<StoreRoleId?> ResolveStoreRoleId(string storeId, string? role)
|
||||
public async Task<StoreRoleId?> ResolveStoreRoleId(string? storeId, string? role)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(role))
|
||||
return null;
|
||||
if (role.Contains("::", StringComparison.OrdinalIgnoreCase) || storeId.Contains("::", StringComparison.OrdinalIgnoreCase))
|
||||
if (storeId?.Contains("::", StringComparison.OrdinalIgnoreCase) is true)
|
||||
return null;
|
||||
var roleId = StoreRoleId.Parse(role);
|
||||
if (roleId.StoreId != null && roleId.StoreId != storeId)
|
||||
return null;
|
||||
if ((await GetStoreRole(roleId)) != null)
|
||||
return roleId;
|
||||
if (string.IsNullOrEmpty(storeId))
|
||||
return null;
|
||||
if (roleId.IsServerRole)
|
||||
roleId = new StoreRoleId(storeId, role);
|
||||
if ((await GetStoreRole(roleId)) != null)
|
||||
|
@ -157,8 +157,6 @@ namespace BTCPayServer.Services
|
||||
{
|
||||
_logger.LogError($"Failed to delete user {user.Id}");
|
||||
}
|
||||
|
||||
await _storeRepository.CleanUnreachableStores();
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<input asp-for="Role" required="required" class="form-control" readonly />
|
||||
<input type="hidden" asp-for="Role"/>
|
||||
<input required="required" class="form-control" disabled value="@Model.Role" />
|
||||
}
|
||||
<span asp-validation-for="Role" class="text-danger"></span>
|
||||
</div>
|
||||
|
@ -38,7 +38,7 @@
|
||||
@Safe.Raw("or more")
|
||||
}
|
||||
}
|
||||
else if (item.PriceType != ViewPointOfSaleViewModel.ItemPriceType.Fixed )
|
||||
else if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup )
|
||||
{
|
||||
@Safe.Raw("Any amount")
|
||||
}else if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Fixed)
|
||||
|
@ -318,15 +318,17 @@
|
||||
<div class="card-title d-flex justify-content-between" :class="{ 'mb-0': !perk.description }">
|
||||
<span class="h5" :class="{ 'mb-0': !perk.description }">{{perk.title ? perk.title : perk.id}}</span>
|
||||
<span class="text-muted">
|
||||
<template v-if="perk.price && perk.price.value">
|
||||
{{formatAmount(perk.price.value.noExponents(), srvModel.currencyData.divisibility)}}
|
||||
{{targetCurrency}}
|
||||
<template v-if="perk.price.type == 1">or more</template>
|
||||
</template>
|
||||
<template v-else-if="perk.price.type === 2 && !perk.price.value">
|
||||
|
||||
<template v-if="perk.priceType === 'Fixed' && amount ==0">
|
||||
Free
|
||||
</template>
|
||||
<template v-else-if="perk.price.type === 0 || (!perk.price.value && perk.price.type === 1)">
|
||||
<template v-else-if="amount">
|
||||
{{formatAmount(perk.price.noExponents(), srvModel.currencyData.divisibility)}}
|
||||
{{targetCurrency}}
|
||||
<template v-if="perk.price.type === 'Minimum'">or more</template>
|
||||
</template>
|
||||
|
||||
<template v-else-if="perk.priceType === 'Topup' || (!amount && perk.priceType === 'Minimum')">
|
||||
Any amount
|
||||
</template>
|
||||
</span>
|
||||
@ -334,19 +336,18 @@
|
||||
<p class="card-text overflow-hidden" v-if="perk.description" v-html="perk.description"></p>
|
||||
|
||||
<div class="input-group" style="max-width:500px;" v-if="expanded" :id="'perk-form'+ perk.id">
|
||||
<template v-if="perk.price.type !== 0 && !(perk.price.type === 2 && !perk.price.value)">
|
||||
<template v-if="perk.priceType !== 'Topup' && !(perk.priceType === 'Fixed' && amount == 0)">
|
||||
<input
|
||||
|
||||
:disabled="!active"
|
||||
:readonly="perk.price.type !== 1"
|
||||
:readonly="perk.priceType === 'Fixed'"
|
||||
class="form-control hide-number-spin"
|
||||
type="number"
|
||||
v-model="amount"
|
||||
:min="perk.price.value"
|
||||
:min="perk.price"
|
||||
step="any"
|
||||
placeholder="Contribution Amount"
|
||||
required>
|
||||
<span class="input-group-text" >{{targetCurrency}}</span>
|
||||
<span class="input-group-text">{{targetCurrency}}</span>
|
||||
</template>
|
||||
<button
|
||||
class="btn btn-primary d-flex align-items-center "
|
||||
|
@ -5,6 +5,7 @@
|
||||
@inject ThemeSettings Theme
|
||||
@inject IFileService FileService
|
||||
|
||||
<script>if (window.localStorage.getItem('btcpay-hide-sensitive-info') === 'true') { document.documentElement.setAttribute('data-hide-sensitive-info', 'true')}</script>
|
||||
@if (Theme.CustomTheme && !string.IsNullOrEmpty(Theme.CssUri))
|
||||
{ // legacy customization with CSS URI - keep it for backwards-compatibility
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(Theme.CssUri)" rel="stylesheet" asp-append-version="true" />
|
||||
@ -25,7 +26,6 @@ else
|
||||
{
|
||||
<link href="~/main/themes/default.css" asp-append-version="true" rel="stylesheet" />
|
||||
<link href="~/main/themes/default-dark.css" asp-append-version="true" rel="stylesheet" id="DarkThemeLinkTag" />
|
||||
<script>if (window.localStorage.getItem('btcpay-hide-sensitive-info') === 'true') { document.documentElement.setAttribute('data-hide-sensitive-info', 'true')}</script>
|
||||
<script src="~/js/theme-switch.js" asp-append-version="true"></script>
|
||||
<noscript><style>.btcpay-theme-switch { display: none !important; }</style></noscript>
|
||||
}
|
||||
|
@ -236,6 +236,10 @@
|
||||
@for (var index = 0; index < Model.Items.Length; index++)
|
||||
{
|
||||
var item = Model.Items[index];
|
||||
if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var image = item.Image;
|
||||
var description = item.Description;
|
||||
|
||||
@ -255,7 +259,7 @@
|
||||
|
||||
<span class="text-muted small">
|
||||
@{
|
||||
var buttonText = string.IsNullOrEmpty(item.BuyButtonText) ? item.PriceType != ViewPointOfSaleViewModel.ItemPriceType.Fixed ? Model.CustomButtonText : Model.ButtonText : item.BuyButtonText;
|
||||
var buttonText = string.IsNullOrEmpty(item.BuyButtonText) ? item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup ? Model.CustomButtonText : Model.ButtonText : item.BuyButtonText;
|
||||
if (item.PriceType != ViewPointOfSaleViewModel.ItemPriceType.Topup)
|
||||
{
|
||||
var formatted = DisplayFormatter.Currency(item.Price ?? 0, Model.CurrencyCode, DisplayFormatter.CurrencyFormat.Symbol);
|
||||
|
@ -116,7 +116,7 @@
|
||||
</div>
|
||||
<button type="button" class="btn btn-link py-0 px-2 mt-2 mb-2 gap-1 add fw-semibold d-inline-flex align-items-center" v-on:click.stop="$emit('add-field', $event, path)">
|
||||
<vc:icon symbol="new" />
|
||||
Add Form Element
|
||||
Add Form Field
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -43,7 +43,7 @@
|
||||
Write them down on a piece of paper in the exact order:
|
||||
</p>
|
||||
</div>
|
||||
<ol id="RecoveryPhrase" data-mnemonic="@Model.Mnemonic" class="my-5 mx-auto">
|
||||
<ol id="RecoveryPhrase" data-mnemonic="@Model.Mnemonic" class="d-inline-block my-5 mx-auto ps-4">
|
||||
@foreach (var word in Model.Words)
|
||||
{
|
||||
<li class="text-start text-muted py-2">
|
||||
|
@ -12,6 +12,7 @@
|
||||
Layout = null;
|
||||
ViewData["Title"] = $"Receipt from {Model.StoreName}";
|
||||
var isProcessing = Model.Status == InvoiceStatus.Processing;
|
||||
var isFreeInvoice = (Model.Status == InvoiceStatus.New && Model.Amount == 0);
|
||||
var isSettled = Model.Status == InvoiceStatus.Settled;
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
@ -22,8 +23,14 @@
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
@if (isProcessing)
|
||||
{
|
||||
<script type="text/javascript">
|
||||
setTimeout(() => { window.location.reload(); }, 10000);
|
||||
<script type="text/javascript">
|
||||
setTimeout(() => { window.location.reload(); }, 10000);
|
||||
</script>
|
||||
}
|
||||
else if (isFreeInvoice)
|
||||
{
|
||||
<script type="text/javascript">
|
||||
setTimeout(() => { window.location.reload(); }, 2000);
|
||||
</script>
|
||||
}
|
||||
<style>
|
||||
|
@ -62,27 +62,36 @@
|
||||
</div>
|
||||
<hr class="border" />
|
||||
}
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="RateThenOption" asp-for="SelectedRefundOption" type="radio" value="RateThen" class="form-check-input"/>
|
||||
<label for="RateThenOption" class="form-check-label">@Model.RateThenText</label>
|
||||
<div class="form-text">The crypto currency price, at the rate the invoice got paid.</div>
|
||||
@if (Model.CryptoAmountThen > 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="RateThenOption" asp-for="SelectedRefundOption" type="radio" value="RateThen" class="form-check-input" />
|
||||
<label for="RateThenOption" class="form-check-label">@Model.RateThenText</label>
|
||||
<div class="form-text">The crypto currency price, at the rate the invoice got paid.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="CurrentRateOption" asp-for="SelectedRefundOption" type="radio" value="CurrentRate" class="form-check-input"/>
|
||||
<label for="CurrentRateOption" class="form-check-label">@Model.CurrentRateText</label>
|
||||
<div class="form-text">The crypto currency price, at the current rate.</div>
|
||||
}
|
||||
@if (Model.CryptoAmountNow > 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="CurrentRateOption" asp-for="SelectedRefundOption" type="radio" value="CurrentRate" class="form-check-input" />
|
||||
<label for="CurrentRateOption" class="form-check-label">@Model.CurrentRateText</label>
|
||||
<div class="form-text">The crypto currency price, at the current rate.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="FiatOption" asp-for="SelectedRefundOption" type="radio" value="Fiat" class="form-check-input"/>
|
||||
<label for="FiatOption" class="form-check-label">@Model.FiatText</label>
|
||||
<div class="form-text">The invoice currency, at the rate when the refund will be sent.</div>
|
||||
}
|
||||
@if (Model.FiatAmount > 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="FiatOption" asp-for="SelectedRefundOption" type="radio" value="Fiat" class="form-check-input" />
|
||||
<label for="FiatOption" class="form-check-label">@Model.FiatText</label>
|
||||
<div class="form-text">The invoice currency, at the rate when the refund will be sent.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input id="CustomOption" asp-for="SelectedRefundOption" type="radio" value="Custom" class="form-check-input"/>
|
||||
|
@ -140,7 +140,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (Model.AdditionalOptions is not null)
|
||||
{
|
||||
@foreach (var dictKeys in Model.AdditionalOptions)
|
||||
{
|
||||
<input type="hidden" asp-for="AdditionalOptions[dictKeys.Key]" />
|
||||
}
|
||||
}
|
||||
<button type="submit" class="btn btn-primary" id="Continue">@(isImport ? "Continue" : "Create")</button>
|
||||
</form>
|
||||
|
||||
|
@ -19,3 +19,5 @@
|
||||
}
|
||||
|
||||
@RenderBody()
|
||||
|
||||
<vc:ui-extension-point location="onchain-wallet-setup-post-body" model="@Model"/>
|
||||
|
@ -112,7 +112,7 @@ Cart.prototype.getTotalProducts = function() {
|
||||
typeof this.content[key] != 'undefined' &&
|
||||
!this.content[key].disabled
|
||||
) {
|
||||
const price = this.toCents(this.content[key].price.value ||0);
|
||||
const price = this.toCents(this.content[key].price ||0);
|
||||
amount += (this.content[key].count * price);
|
||||
}
|
||||
}
|
||||
@ -438,7 +438,7 @@ Cart.prototype.listItems = function() {
|
||||
'title': this.escape(item.title),
|
||||
'count': this.escape(item.count),
|
||||
'inventory': this.escape(item.inventory < 0? 99999: item.inventory),
|
||||
'price': this.escape(item.price.formatted || 0)
|
||||
'price': this.escape(item.price || 0)
|
||||
});
|
||||
list.push($(tableTemplate));
|
||||
}
|
||||
|
@ -50,19 +50,22 @@ document.addEventListener("DOMContentLoaded",function (ev) {
|
||||
}
|
||||
},
|
||||
setAmount: function (amount) {
|
||||
this.amount = this.perk.price.type === 0? null : (amount || 0).noExponents();
|
||||
if(typeof amount === "string"){
|
||||
amount = parseFloat(amount);
|
||||
}
|
||||
this.amount = this.perk.priceType === "Topup"? null : (amount || 0).noExponents();
|
||||
this.expanded = false;
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.setAmount(this.perk.price.value);
|
||||
this.setAmount(this.perk.price);
|
||||
},
|
||||
watch: {
|
||||
perk: function (newValue, oldValue) {
|
||||
if(newValue.price.type ===0){
|
||||
if(newValue.price.type === "Topup"){
|
||||
this.setAmount();
|
||||
}else if (newValue.price.value != oldValue.price.value) {
|
||||
this.setAmount(newValue.price.value);
|
||||
}else if (newValue.price != oldValue.price) {
|
||||
this.setAmount(newValue.price);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,9 +150,9 @@ document.addEventListener("DOMContentLoaded",function (ev) {
|
||||
return result;
|
||||
},
|
||||
perks: function(){
|
||||
var result = [];
|
||||
for (var i = 0; i < this.srvModel.perks.length; i++) {
|
||||
var currentPerk = this.srvModel.perks[i];
|
||||
const result = [];
|
||||
for (let i = 0; i < this.srvModel.perks.length; i++) {
|
||||
const currentPerk = this.srvModel.perks[i];
|
||||
if(this.srvModel.perkCount.hasOwnProperty(currentPerk.id)){
|
||||
currentPerk.sold = this.srvModel.perkCount[currentPerk.id];
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
Number.prototype.noExponents= function(){
|
||||
var data= String(this).split(/[eE]/);
|
||||
String.prototype.noExponents= function(){
|
||||
const data = String(this).split(/[eE]/);
|
||||
if(data.length== 1) return data[0];
|
||||
|
||||
var z= '', sign= this<0? '-':'',
|
||||
@ -14,4 +14,8 @@ Number.prototype.noExponents= function(){
|
||||
mag -= str.length;
|
||||
while(mag--) z += '0';
|
||||
return str + z;
|
||||
}
|
||||
|
||||
Number.prototype.noExponents= function(){
|
||||
return String(this).noExponents();
|
||||
};
|
||||
|
@ -11,20 +11,20 @@
|
||||
"pay_in_wallet": "Πληρωμή στο πορτοφόλι",
|
||||
"pay_by_nfc": "Πληρωμή μέσω NFC",
|
||||
"pay_by_lnurl": "Πληρωμή με LNURL-Withdraw",
|
||||
"invoice_id": "ID Παραστατικού Πληρωμής",
|
||||
"order_id": "ID Παραγγελίας",
|
||||
"invoice_id": "ID παραστατικού πληρωμής",
|
||||
"order_id": "ID παραγγελίας",
|
||||
"total_price": "Συνολική τιμή",
|
||||
"total_fiat": "Συνολική τιμή σε νόμισμα",
|
||||
"exchange_rate": "Ισοτιμία",
|
||||
"amount_paid": "Πληρωθέν ποσό",
|
||||
"amount_due": "Οφειλόμενο ποσό",
|
||||
"recommended_fee": "Συνιστώμενη Αμοιβή",
|
||||
"recommended_fee": "Συνιστώμενη αμοιβή",
|
||||
"fee_rate": "{{feeRate}} sat/byte",
|
||||
"network_cost": "Κόστος Δικτύου",
|
||||
"network_cost": "Κόστος δικτύου",
|
||||
"tx_count": "{{count}} συναλλαγή",
|
||||
"qr_text": "Σαρώστε τον κωδικό QR ή πατήστε για να αντιγράψετε τη διεύθυνση.",
|
||||
"address": "Διεύθυνση",
|
||||
"lightning": "Αστραπή (Lightning)",
|
||||
"lightning": "Lightning",
|
||||
"payment_link": "Σύνδεσμος πληρωμής",
|
||||
"invoice_paid": "Εξοφλημένο τιμολόγιο",
|
||||
"invoice_expired": "Η τιμολόγηση έληξε",
|
||||
|
@ -3,16 +3,16 @@
|
||||
"code": "el-GR",
|
||||
"currentLanguage": "Ελληνικά",
|
||||
"lang": "Γλώσσα",
|
||||
"Awaiting Payment...": "Αναμονή Πληρωμής...",
|
||||
"Awaiting Payment...": "Αναμονή πληρωμής...",
|
||||
"Pay with": "Πληρώστε με",
|
||||
"Contact and Refund Email": "Email Επικοινωνίας & Επιστροφής Πληρωμής",
|
||||
"Contact_Body": "Παρακαλούμε εισάγετε το email σας παρακάτω. Θα επικοινωνήσουμε μαζί σας σε αυτή τη διεύθυνση ηλεκτρονικής αλληλογραφίας εαν προκύψει κάποιο θέμα με την πληρωμή σας.",
|
||||
"Contact and Refund Email": "Email επικοινωνίας & επιστροφής πληρωμής",
|
||||
"Contact_Body": "Παρακαλούμε εισάγετε το email σας παρακάτω. Θα επικοινωνήσουμε μαζί σας σε αυτή τη διεύθυνση ηλεκτρονικής αλληλογραφίας εάν προκύψει κάποιο θέμα με την πληρωμή σας.",
|
||||
"Your email": "Το email σας",
|
||||
"Continue": "Συνέχεια",
|
||||
"Please enter a valid email address": "Παρακαλούμε εισάγετε μια έγκυρη διεύθυνση email",
|
||||
"Order Amount": "Ποσό Παραγγελίας",
|
||||
"Network Cost": "Κόστος Δικτύου",
|
||||
"Already Paid": "Πληρώθηκαν Ήδη",
|
||||
"Order Amount": "Ποσό παραγγελίας",
|
||||
"Network Cost": "Κόστος δικτύου",
|
||||
"Already Paid": "Πληρώθηκαν ήδη",
|
||||
"Due": "Οφειλόμενα",
|
||||
"Scan": "Σάρωση",
|
||||
"Copy": "Αντιγραφή",
|
||||
@ -34,14 +34,14 @@
|
||||
"InvoiceExpired_Body_1": "Το παρών παραστατικό πληρωμής έχει λήξει. Ένα παραστατικό πληρωμής ισχύει μόνο για {{maxTimeMinutes}} λεπτά.\nΜπορείτε να επιστρέψετε στο {{storeName}} εάν θα θέλατε να υποβάλετε ξανά την πληρωμή σας.",
|
||||
"InvoiceExpired_Body_2": "Εάν επιχειρήσατε να στείλετε την πληρωμή σας, αυτή ακόμη δεν έχει γίνει αποδεκτή απο το δίκτυο. Δέν έχουμε λάβει ακόμη την πληρωμή σας.",
|
||||
"InvoiceExpired_Body_3": "Εάν την λάβουμε αργότερα, είτε θα εκτέλεσουμε την παραγγελία σας ή θα επικοινωνήσουμε μαζί σας για να οργανώσουμε την επιστροφή των χρημάτων σας...",
|
||||
"Invoice ID": "ID Παραστατικού Πληρωμής",
|
||||
"Order ID": "ID Παραγγελίας",
|
||||
"Invoice ID": "ID παραστατικού πληρωμής",
|
||||
"Order ID": "ID παραγγελίας",
|
||||
"Return to StoreName": "Επιστροφή στο {{storeName}}",
|
||||
"This invoice has been paid": "Αυτό το παραστατικό έχει πληρωθεί",
|
||||
"This invoice has been archived": "Αυτό το παραστατικό έχει αρχειοθετηθεί",
|
||||
"Archived_Body": "Παρακαλούμε επικοινωνήστε με το κατάστημα για πληροφορίες σχετικά με την παραγγελία ή εάν χρειάζεστε βοήθεια",
|
||||
"BOLT 11 Invoice": "Παραστατικό BOLT 11",
|
||||
"Node Info": "Πληροφορίες Κόμβου",
|
||||
"Node Info": "Πληροφορίες κόμβου",
|
||||
"txCount": "{{count}} συναλλαγή",
|
||||
"txCount_plural": "{{count}} συναλλαγών",
|
||||
"Pay with CoinSwitch": "Πληρώστε με CoinSwitch",
|
||||
|
@ -10,18 +10,17 @@
|
||||
|
||||
/* Hide sensitive info */
|
||||
[data-hide-sensitive-info="true"] [data-sensitive] {
|
||||
visibility: hidden;
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[data-hide-sensitive-info="true"] [data-sensitive]:before {
|
||||
content: '***';
|
||||
content: '***********************';
|
||||
visibility: visible;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
[data-hide-sensitive-info="true"] .text-end [data-sensitive]:before {
|
||||
right: 0;
|
||||
top: .2em;
|
||||
}
|
||||
|
||||
[data-hide-sensitive-info="true"] .store-wallet-balance .ct-label.ct-vertical.ct-start {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>1.10.0</Version>
|
||||
<Version>1.10.2</Version>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
20
Changelog.md
20
Changelog.md
@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## 1.10.2
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Fix: Stale data when fetching invoice after webhook (#5049) @Kukks
|
||||
* Fix: Crash on migation of old instances (#5051) @NicolasDorier
|
||||
* Fix: Hide sensitive info feature not working with custom theme (#5044) @dennisreimann
|
||||
* Fix: Pay button not rendering on the invoice page (#5043) @dennisreimann
|
||||
|
||||
## 1.10.1
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Point of Sale bug after filling out form Shop + cart (#5031) @Kukks
|
||||
|
||||
### Improvements
|
||||
|
||||
* Language translation update for el-GR
|
||||
|
||||
## 1.10.0
|
||||
|
||||
Notice: Due to the substantial disk space consumption, we are removing all data pertaining to past webhook deliveries (#5005).
|
||||
@ -32,6 +51,7 @@ This data, generally used for debugging integrations, will be regularly purged.
|
||||
* Improve create first store case (#4951) @dennisreimann @dstrukt
|
||||
* Improve Refund UI/UX (#4934 #3839 #4812) @dennisreimann @dstrukt
|
||||
* Prune old webhook delivery data (#5005) @NicolasDorier
|
||||
* Can mark expired invoices as complete or invalid (#5006) @dennisreimann
|
||||
|
||||
## 1.9.3
|
||||
|
||||
|
Reference in New Issue
Block a user