Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
5050b59014 | |||
665cf4c3b1 | |||
98e81ab0fd | |||
6ce70237fc | |||
4f23fc99a1 | |||
d7fccae452 | |||
d7a5021ed2 | |||
63ec832667 | |||
8d95b9fa04 | |||
b497d1871e | |||
c7cd029482 | |||
68f2cba60d | |||
5c4200b036 | |||
bc06114023 | |||
556082c4c9 | |||
6a46d02fc6 | |||
d75e5b8b12 | |||
a97ef2eee8 | |||
be33ebc168 | |||
789193a0c8 | |||
01792cf299 | |||
ff9265f721 | |||
8d61314852 | |||
1ce6ae8727 | |||
f22c8a72cd | |||
f81ca1888d | |||
ed02e0f4d6 | |||
0a83f21af5 | |||
7fdf19ca22 | |||
4e776adb03 | |||
d102c142b9 | |||
f7989541b9 | |||
e1dfbfe3b0 | |||
7c3ddf904c | |||
25208915eb | |||
52e0845fc5 | |||
daf1a0a4bc | |||
bc8978182e |
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM microsoft/dotnet:2.1.300-rc1-sdk-alpine3.7
|
||||
FROM microsoft/dotnet:2.1.300-sdk-alpine3.7
|
||||
WORKDIR /app
|
||||
# caches restore result by copying csproj file separately
|
||||
COPY BTCPayServer.Tests/BTCPayServer.Tests.csproj BTCPayServer.Tests/BTCPayServer.Tests.csproj
|
||||
|
@ -1325,6 +1325,8 @@ namespace BTCPayServer.Tests
|
||||
var repo = tester.PayTester.GetService<InvoiceRepository>();
|
||||
var ctx = tester.PayTester.GetService<ApplicationDbContextFactory>().CreateContext();
|
||||
Assert.Equal(0, invoice.CryptoInfo[0].TxCount);
|
||||
Assert.True(invoice.MinerFees.ContainsKey("BTC"));
|
||||
Assert.Equal(100m, invoice.MinerFees["BTC"].SatoshiPerBytes);
|
||||
Eventually(() =>
|
||||
{
|
||||
var textSearchResult = tester.PayTester.InvoiceRepository.GetInvoices(new InvoiceQuery()
|
||||
|
@ -46,7 +46,7 @@ services:
|
||||
- lightning-charged
|
||||
|
||||
nbxplorer:
|
||||
image: nicolasdorier/nbxplorer:1.0.2.6
|
||||
image: nicolasdorier/nbxplorer:1.0.2.8
|
||||
ports:
|
||||
- "32838:32838"
|
||||
expose:
|
||||
|
34
BTCPayServer/BTCPayNetworkProvider.Polis.cs
Normal file
34
BTCPayServer/BTCPayNetworkProvider.Polis.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using NBitcoin;
|
||||
using NBXplorer;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
public partial class BTCPayNetworkProvider
|
||||
{
|
||||
public void InitPolis()
|
||||
{
|
||||
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("POLIS");
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://insight.polispay.org/tx/{0}" : "https://insight.polispay.org/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
UriScheme = "polis",
|
||||
DefaultRateRules = new[]
|
||||
{
|
||||
"POLIS_X = POLIS_BTC * BTC_X",
|
||||
"POLIS_BTC = cryptopia(POLIS_BTC)"
|
||||
},
|
||||
CryptoImagePath = "imlegacy/polis.png",
|
||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
|
||||
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("1997'") : new KeyPath("1'")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@ namespace BTCPayServer
|
||||
InitDogecoin();
|
||||
InitBitcoinGold();
|
||||
InitMonacoin();
|
||||
InitPolis();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<Version>1.0.2.26</Version>
|
||||
<Version>1.0.2.31</Version>
|
||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@ -37,24 +37,24 @@
|
||||
<PackageReference Include="Hangfire.PostgreSql" Version="1.4.8.2" />
|
||||
<PackageReference Include="LedgerWallet" Version="1.0.1.36" />
|
||||
<PackageReference Include="Meziantou.AspNetCore.BundleTagHelpers" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0-rc1-final" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
||||
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
|
||||
<PackageReference Include="NBitcoin" Version="4.1.1.7" />
|
||||
<PackageReference Include="NBitpayClient" Version="1.0.0.23" />
|
||||
<PackageReference Include="NBitcoin" Version="4.1.1.10" />
|
||||
<PackageReference Include="NBitpayClient" Version="1.0.0.26" />
|
||||
<PackageReference Include="DBreeze" Version="1.87.0" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="1.0.2.8" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1-rc1" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="1.0.2.10" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.2" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.14" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.0" />
|
||||
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
|
||||
<PackageReference Include="Text.Analyzers" Version="2.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-rc1-final" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version=" 2.1.0-rc1-final" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version=" 2.1.0" PrivateAssets="All" />
|
||||
<PackageReference Include="YamlDotNet" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -77,6 +77,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
new PairingCodeResponse()
|
||||
{
|
||||
Policies = new Newtonsoft.Json.Linq.JArray(),
|
||||
PairingCode = pairingEntity.Id,
|
||||
PairingExpiration = pairingEntity.Expiration,
|
||||
DateCreated = pairingEntity.CreatedTime,
|
||||
|
@ -101,7 +101,7 @@ namespace BTCPayServer.Controllers
|
||||
vm.InvoiceUrl = appUrl + "invoices/SkdsDghkdP3D3qkj7bLq3";
|
||||
}
|
||||
|
||||
vm.ExampleCallback = "{\n \"id\":\"SkdsDghkdP3D3qkj7bLq3\",\n \"url\":\"https://btcpay.example.com/invoice?id=SkdsDghkdP3D3qkj7bLq3\",\n \"status\":\"paid\",\n \"price\":10,\n \"currency\":\"EUR\",\n \"invoiceTime\":1520373130312,\n \"expirationTime\":1520374030312,\n \"currentTime\":1520373179327,\n \"exceptionStatus\":false,\n \"buyerFields\":{\n \"buyerEmail\":\"customer@example.com\",\n \"buyerNotify\":false\n },\n \"paymentSubtotals\": {\n \"BTC\":114700\n },\n \"paymentTotals\": {\n \"BTC\":118400\n },\n \"transactionCurrency\": \"BCH\",\n \"amountPaid\": \"1025900\",\n \"exchangeRates\": {\n \"BTC\": {\n \"EUR\": 8721.690715789999,\n \"USD\": 10817.99\n }\n }\n}";
|
||||
vm.ExampleCallback = "{\n \"id\":\"SkdsDghkdP3D3qkj7bLq3\",\n \"url\":\"https://btcpay.example.com/invoice?id=SkdsDghkdP3D3qkj7bLq3\",\n \"status\":\"paid\",\n \"price\":10,\n \"currency\":\"EUR\",\n \"invoiceTime\":1520373130312,\n \"expirationTime\":1520374030312,\n \"currentTime\":1520373179327,\n \"exceptionStatus\":false,\n \"buyerFields\":{\n \"buyerEmail\":\"customer@example.com\",\n \"buyerNotify\":false\n },\n \"paymentSubtotals\": {\n \"BTC\":114700\n },\n \"paymentTotals\": {\n \"BTC\":118400\n },\n \"transactionCurrency\": \"BTC\",\n \"amountPaid\": \"1025900\",\n \"exchangeRates\": {\n \"BTC\": {\n \"EUR\": 8721.690715789999,\n \"USD\": 10817.99\n }\n }\n}";
|
||||
return View(vm);
|
||||
}
|
||||
[HttpPost]
|
||||
@ -254,7 +254,8 @@ namespace BTCPayServer.Controllers
|
||||
BuyerEmail = email,
|
||||
OrderId = orderId,
|
||||
NotificationURL = notificationUrl,
|
||||
RedirectURL = redirectUrl
|
||||
RedirectURL = redirectUrl,
|
||||
FullNotifications = true
|
||||
}, store, HttpContext.Request.GetAbsoluteRoot());
|
||||
return Redirect(invoice.Data.Url);
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
Status = invoice.Status + (invoice.ExceptionStatus == null ? string.Empty : $" ({invoice.ExceptionStatus})"),
|
||||
ShowCheckout = invoice.Status == "new",
|
||||
Date = (DateTimeOffset.UtcNow - invoice.InvoiceTime).Prettify() + " ago",
|
||||
Date = invoice.InvoiceTime,
|
||||
InvoiceId = invoice.Id,
|
||||
OrderId = invoice.OrderId ?? string.Empty,
|
||||
RedirectUrl = invoice.RedirectURL ?? string.Empty,
|
||||
|
@ -36,28 +36,6 @@ namespace BTCPayServer
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string Prettify(this TimeSpan timeSpan)
|
||||
{
|
||||
if (timeSpan.TotalMinutes < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalSeconds} second{Plural((int)timeSpan.TotalSeconds)}";
|
||||
}
|
||||
if (timeSpan.TotalHours < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
||||
}
|
||||
if (timeSpan.Days < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}";
|
||||
}
|
||||
return $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||
}
|
||||
|
||||
private static string Plural(int totalDays)
|
||||
{
|
||||
return totalDays > 1 ? "s" : string.Empty;
|
||||
}
|
||||
|
||||
public static string PrettyPrint(this TimeSpan expiration)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -235,7 +235,7 @@ namespace BTCPayServer.Models
|
||||
public long AmountPaid { get; set; }
|
||||
|
||||
[JsonProperty("minerFees")]
|
||||
public long MinerFees { get; set; }
|
||||
public Dictionary<string, NBitpayClient.MinerFeeInfo> MinerFees { get; set; }
|
||||
|
||||
[JsonProperty("exchangeRates")]
|
||||
public Dictionary<string, Dictionary<string, decimal>> ExchangeRates { get; set; }
|
||||
|
@ -33,10 +33,7 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
|
||||
public class InvoiceModel
|
||||
{
|
||||
public string Date
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public DateTimeOffset Date { get; set; }
|
||||
|
||||
public string OrderId { get; set; }
|
||||
public string RedirectUrl { get; set; }
|
||||
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Models
|
||||
{
|
||||
@ -44,6 +45,9 @@ namespace BTCPayServer.Models
|
||||
|
||||
public class PairingCodeResponse
|
||||
{
|
||||
[JsonProperty(PropertyName = "policies")]
|
||||
public JArray Policies { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "pairingCode")]
|
||||
public string PairingCode
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ using NBXplorer;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
using BTCPayServer.Payments;
|
||||
using NBitpayClient;
|
||||
using BTCPayServer.Payments.Bitcoin;
|
||||
|
||||
namespace BTCPayServer.Services.Invoices
|
||||
{
|
||||
@ -348,6 +349,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
dto.Url = ServerUrl.WithTrailingSlash() + $"invoice?id=" + Id;
|
||||
dto.CryptoInfo = new List<NBitpayClient.InvoiceCryptoInfo>();
|
||||
dto.MinerFees = new Dictionary<string, MinerFeeInfo>();
|
||||
foreach (var info in this.GetPaymentMethods(networkProvider))
|
||||
{
|
||||
var accounting = info.Calculate();
|
||||
@ -381,6 +383,10 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
if (paymentId.PaymentType == PaymentTypes.BTCLike)
|
||||
{
|
||||
var minerInfo = new MinerFeeInfo();
|
||||
minerInfo.TotalFee = accounting.NetworkFee.Satoshi;
|
||||
minerInfo.SatoshiPerBytes = ((BitcoinLikeOnChainPaymentMethod)info.GetPaymentMethodDetails()).FeeRate.GetFee(1).Satoshi;
|
||||
dto.MinerFees.TryAdd(paymentId.CryptoCode, minerInfo);
|
||||
var cryptoSuffix = cryptoInfo.CryptoCode == "BTC" ? "" : "/" + cryptoInfo.CryptoCode;
|
||||
cryptoInfo.PaymentUrls = new NBitpayClient.InvoicePaymentUrls()
|
||||
{
|
||||
|
@ -48,16 +48,16 @@
|
||||
}
|
||||
@if(Model.Example2 != null)
|
||||
{
|
||||
<span>For a specific item or your template</span>
|
||||
<span>For a specific item of your template</span>
|
||||
<pre><code class="html">@Model.Example2</code></pre>
|
||||
}
|
||||
<p>A <code>POST</code> callback will be sent to notification with the following form will be sent to <code>notificationUrl</code>:</p>
|
||||
<p>A <code>POST</code> callback will be sent to notification with the following form will be sent to <code>notificationUrl</code> once the enough is paid and once again once there is enough confirmations to the payment:</p>
|
||||
<pre><code class="json">@Model.ExampleCallback</code></pre>
|
||||
<p><strong>Never</strong> trust anything but <code>id</code>, <strong>ignore</strong> the other fields completely, an attacker can spoof those, they are present only for backward compatibility reason:</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li><strong>Build the invoice's url by yourself</strong> do not trust the <code>url</code> field, this can be spoofed to use attacker's server.</li>
|
||||
<li>Send a the <code>GET</code> request to the invoice's url with <code>Content-Type: application/json</code></li>
|
||||
<li>Send a <code>GET</code> request to the invoice's url with <code>Content-Type: application/json</code></li>
|
||||
<li>Verify that the <code>orderId</code> is from your backend, that the <code>price</code> is correct and that <code>status</code> is either <code>confirmed</code> or <code>complete</code></li>
|
||||
<li>You can then ship your order</li>
|
||||
</ul>
|
||||
|
@ -53,15 +53,15 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Created date</th>
|
||||
<td>@Model.CreatedDate</td>
|
||||
<td>@Model.CreatedDate.ToBrowserDate()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Expiration date</th>
|
||||
<td>@Model.ExpirationDate</td>
|
||||
<td>@Model.ExpirationDate.ToBrowserDate()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Monitoring date</th>
|
||||
<td>@Model.MonitoringDate</td>
|
||||
<td>@Model.MonitoringDate.ToBrowserDate()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Transaction speed</th>
|
||||
@ -289,7 +289,7 @@
|
||||
@foreach(var evt in Model.Events)
|
||||
{
|
||||
<tr>
|
||||
<td>@evt.Timestamp</td>
|
||||
<td>@evt.Timestamp.ToBrowserDate()</td>
|
||||
<td>@evt.Message</td>
|
||||
</tr>
|
||||
}
|
||||
|
@ -66,7 +66,7 @@
|
||||
@foreach(var invoice in Model.Invoices)
|
||||
{
|
||||
<tr>
|
||||
<td>@invoice.Date</td>
|
||||
<td>@invoice.Date.ToTimeAgo()</td>
|
||||
<td>
|
||||
@if(invoice.RedirectUrl != string.Empty)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<th>Quota period</th>
|
||||
<td>@Model.RateLimits.TotalPeriod.Prettify()</td>
|
||||
<td>@Model.RateLimits.TotalPeriod.TimeString()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Requests quota</th>
|
||||
@ -48,7 +48,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Quota reset in</th>
|
||||
<td>@Model.RateLimits.CounterReset.Prettify()</td>
|
||||
<td>@Model.RateLimits.CounterReset.TimeString()</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<div class="alert alert-warning alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<p>
|
||||
<span>A connection to a lightning charge node or clightning unix socket is required to generate lignting network enabled invoices. <br /></span>
|
||||
<span>A connection to a lightning charge node or clightning unix socket is required to generate lightning network enabled invoices. <br /></span>
|
||||
<span>This is experimental and not advised for production so keep in mind:</span>
|
||||
</p>
|
||||
<ul>
|
||||
|
@ -96,7 +96,7 @@
|
||||
<div class="form-group">
|
||||
<h5>Lightning nodes (Experimental)</h5>
|
||||
<p>
|
||||
<span>A connection to a lightning charge node is required to generate lignting network enabled invoices.<br /></span>
|
||||
<span>A connection to a lightning charge node is required to generate lightning network enabled invoices.<br /></span>
|
||||
<span>This is experimental and not advised for production.</span>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
|
||||
namespace BTCPayServer.Views
|
||||
@ -22,5 +24,39 @@ namespace BTCPayServer.Views
|
||||
var activePage = (T)viewData[ACTIVE_PAGE_KEY];
|
||||
return page.Equals(activePage) ? "active" : null;
|
||||
}
|
||||
|
||||
public static HtmlString ToBrowserDate(this DateTimeOffset date)
|
||||
{
|
||||
var hello = date.ToString("o", CultureInfo.InvariantCulture);
|
||||
return new HtmlString($"<span class='localizeDate'>{hello}</span>");
|
||||
}
|
||||
|
||||
public static string ToTimeAgo(this DateTimeOffset date)
|
||||
{
|
||||
var formatted = (DateTimeOffset.UtcNow - date).TimeString() + " ago";
|
||||
return formatted;
|
||||
}
|
||||
|
||||
public static string TimeString(this TimeSpan timeSpan)
|
||||
{
|
||||
if (timeSpan.TotalMinutes < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalSeconds} second{Plural((int)timeSpan.TotalSeconds)}";
|
||||
}
|
||||
if (timeSpan.TotalHours < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
||||
}
|
||||
if (timeSpan.Days < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}";
|
||||
}
|
||||
return $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||
}
|
||||
|
||||
private static string Plural(int totalDays)
|
||||
{
|
||||
return totalDays > 1 ? "s" : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@
|
||||
"wwwroot/vendor/jquery-easing/jquery.easing.js",
|
||||
"wwwroot/vendor/scrollreveal/scrollreveal.min.js",
|
||||
"wwwroot/vendor/magnific-popup/jquery.magnific-popup.js",
|
||||
"wwwroot/vendor/bootstrap4-creativestart/*.js"
|
||||
"wwwroot/vendor/bootstrap4-creativestart/*.js",
|
||||
"wwwroot/main/**/*.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -5,7 +5,7 @@ const locales_es = {
|
||||
"Awaiting Payment...": "En espera de pago...",
|
||||
"Pay with": "Pagar con",
|
||||
"Contact and Refund Email": "Contacto y correo electrónico de reembolso",
|
||||
"Contact_Body": "Por favor provee una dirección de correo electrónico a continuación. Nos pondremos en contacto contigo en esta dirección si hay un problema con tu pago.",
|
||||
"Contact_Body": "Por favor indica una dirección de correo electrónico a continuación. Nos pondremos en contacto contigo en esta dirección si hay algún problema con tu pago.",
|
||||
"Your email": "Tu correo electrónico",
|
||||
"Continue": "Continuar",
|
||||
"Please enter a valid email address": "Por favor ingresa un correo electrónico válido",
|
||||
@ -18,15 +18,15 @@ const locales_es = {
|
||||
"Copy": "Copiar",
|
||||
"Conversion": "Conversión",
|
||||
// Scan tab
|
||||
"Open in wallet": "Abrir en billetera",
|
||||
"Open in wallet": "Abrir en la billetera",
|
||||
// Copy tab
|
||||
"CompletePay_Body": "Para completar tu pago, envía {{btcDue}} {{cryptoCode}} a la siguiente dirección.",
|
||||
"CompletePay_Body": "Para completar tu pago, envía {{btcDue}} {{cryptoCode}} a la siguiente dirección:",
|
||||
"Amount": "Cantidad",
|
||||
"Address": "Dirección",
|
||||
"Copied": "Copiado",
|
||||
// Conversion tab
|
||||
"ConversionTab_BodyTop": "Puedes pagar {{btcDue}} {{cryptoCode}} usando altcoins que no sean los que el comercio soporta directamente.",
|
||||
"ConversionTab_BodyDesc": "Este servicio es provisto por terceros. Ten en cuenta que no tenemos control sobre cómo estos terceros enviarán los fondos. La factura solo se marcará como abonada una vez que se reciban los fondos en la cadena de bloques de {{cryptoCode}} .",
|
||||
"ConversionTab_BodyTop": "Puedes pagar {{btcDue}} {{cryptoCode}} usando Altcoins que este comercio no soporta directamente.",
|
||||
"ConversionTab_BodyDesc": "Este servicio es provisto por terceros. Ten en cuenta que no tenemos control sobre cómo estos terceros envían los fondos. La factura solo se marcará como pagada una vez se reciban los fondos en la cadena de bloques de {{cryptoCode}} .",
|
||||
"Shapeshift_Button_Text": "Pagar con Altcoins",
|
||||
"ConversionTab_Lightning": "No hay proveedores de conversión disponibles para los pagos de Lightning Network.",
|
||||
// Invoice expired
|
||||
@ -36,8 +36,8 @@ const locales_es = {
|
||||
"InvoiceExpired_Body_1": "Esta factura ha expirado. Una factura solo es válida por {{maxTimeMinutes}} minutos. Puedes regresar a {{storeName}} si deseas volver a enviar tu pago.",
|
||||
"InvoiceExpired_Body_2": "Si intentaste enviar un pago, aún no ha sido aceptado por la red de Bitcoin. Todavía no hemos recibido tus fondos.",
|
||||
"InvoiceExpired_Body_3": "Si la transacción no es aceptada por la red de Bitcoin, los fondos se podrán gastar nuevamente en tu billetera. Dependiendo de tu billetera, esto puede tomar 48-72 horas.",
|
||||
"Invoice ID": "ID de factura",
|
||||
"Order ID": "ID de pedido",
|
||||
"Invoice ID": "ID de la factura",
|
||||
"Order ID": "ID del pedido",
|
||||
"Return to StoreName": "Regresar a {{storeName}}",
|
||||
// Invoice paid
|
||||
"This invoice has been paid": "Esta factura ha sido pagada",
|
||||
|
BIN
BTCPayServer/wwwroot/imlegacy/polis.png
Normal file
BIN
BTCPayServer/wwwroot/imlegacy/polis.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
9
BTCPayServer/wwwroot/main/site.js
Normal file
9
BTCPayServer/wwwroot/main/site.js
Normal file
@ -0,0 +1,9 @@
|
||||
$(function () {
|
||||
$(".localizeDate").each(function (index) {
|
||||
var serverDate = $(this).text();
|
||||
var localDate = new Date(serverDate);
|
||||
|
||||
var dateString = localDate.toLocaleDateString() + " " + localDate.toLocaleTimeString();
|
||||
$(this).text(dateString);
|
||||
});
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
FROM microsoft/dotnet:2.1.300-rc1-sdk-alpine3.7 AS builder
|
||||
FROM microsoft/dotnet:2.1.300-sdk-alpine3.7 AS builder
|
||||
WORKDIR /source
|
||||
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer.csproj
|
||||
# Cache some dependencies
|
||||
@ -6,7 +6,7 @@ RUN dotnet restore
|
||||
COPY BTCPayServer/. .
|
||||
RUN dotnet publish --output /app/ --configuration Release
|
||||
|
||||
FROM microsoft/dotnet:2.1.0-rc1-aspnetcore-runtime-alpine3.7
|
||||
FROM microsoft/dotnet:2.1.0-aspnetcore-runtime-alpine3.7
|
||||
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
|
||||
RUN apk add --no-cache icu-libs
|
||||
|
@ -5,4 +5,4 @@
|
||||
<add key="aspnetcidev" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json"/>
|
||||
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json"/>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
Reference in New Issue
Block a user