mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-21 22:11:48 +01:00
Remove Changelly
This commit is contained in:
parent
7ca0a8c56c
commit
50a9772388
22 changed files with 6 additions and 1054 deletions
|
@ -1,242 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.Changelly.Models;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using BTCPayServer.Tests.Logging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace BTCPayServer.Tests
|
||||
{
|
||||
public class ChangellyTests
|
||||
{
|
||||
public const int TestTimeout = 60_000;
|
||||
public ChangellyTests(ITestOutputHelper helper)
|
||||
{
|
||||
Logs.Tester = new XUnitLog(helper) { Name = "Tests" };
|
||||
Logs.LogProvider = new XUnitLogProvider(helper);
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async void CanSetChangellyPaymentMethod()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
await tester.StartAsync();
|
||||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
var controller = tester.PayTester.GetController<StoresController>(user.UserId, user.StoreId);
|
||||
|
||||
|
||||
var storeBlob = controller.CurrentStore.GetStoreBlob();
|
||||
Assert.Null(storeBlob.ChangellySettings);
|
||||
|
||||
var updateModel = new UpdateChangellySettingsViewModel()
|
||||
{
|
||||
ApiSecret = "secret",
|
||||
ApiKey = "key",
|
||||
ApiUrl = "http://gozo.com",
|
||||
ChangellyMerchantId = "aaa",
|
||||
};
|
||||
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await controller.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
var store = await tester.PayTester.StoreRepository.FindStore(user.StoreId);
|
||||
storeBlob = controller.CurrentStore.GetStoreBlob();
|
||||
Assert.NotNull(storeBlob.ChangellySettings);
|
||||
Assert.NotNull(storeBlob.ChangellySettings);
|
||||
Assert.IsType<ChangellySettings>(storeBlob.ChangellySettings);
|
||||
Assert.Equal(storeBlob.ChangellySettings.ApiKey, updateModel.ApiKey);
|
||||
Assert.Equal(storeBlob.ChangellySettings.ApiSecret,
|
||||
updateModel.ApiSecret);
|
||||
Assert.Equal(storeBlob.ChangellySettings.ApiUrl, updateModel.ApiUrl);
|
||||
Assert.Equal(storeBlob.ChangellySettings.ChangellyMerchantId,
|
||||
updateModel.ChangellyMerchantId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async Task CanToggleChangellyPaymentMethod()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
await tester.StartAsync();
|
||||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
var controller = tester.PayTester.GetController<StoresController>(user.UserId, user.StoreId);
|
||||
|
||||
var updateModel = new UpdateChangellySettingsViewModel()
|
||||
{
|
||||
ApiSecret = "secret",
|
||||
ApiKey = "key",
|
||||
ApiUrl = "http://gozo.com",
|
||||
ChangellyMerchantId = "aaa",
|
||||
Enabled = true
|
||||
};
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await controller.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
|
||||
var store = await tester.PayTester.StoreRepository.FindStore(user.StoreId);
|
||||
|
||||
Assert.True(store.GetStoreBlob().ChangellySettings.Enabled);
|
||||
|
||||
updateModel.Enabled = false;
|
||||
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await controller.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
store = await tester.PayTester.StoreRepository.FindStore(user.StoreId);
|
||||
|
||||
Assert.False(store.GetStoreBlob().ChangellySettings.Enabled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async void CannotUseChangellyApiWithoutChangellyPaymentMethodSet()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
await tester.StartAsync();
|
||||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
var changellyController =
|
||||
tester.PayTester.GetController<ChangellyController>(user.UserId, user.StoreId);
|
||||
changellyController.IsTest = true;
|
||||
|
||||
//test non existing payment method
|
||||
Assert.IsType<BitpayErrorModel>(Assert
|
||||
.IsType<BadRequestObjectResult>(await changellyController.GetCurrencyList(user.StoreId))
|
||||
.Value);
|
||||
|
||||
var updateModel = CreateDefaultChangellyParams(false);
|
||||
var storesController = tester.PayTester.GetController<StoresController>(user.UserId, user.StoreId);
|
||||
//set payment method but disabled
|
||||
|
||||
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await storesController.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
|
||||
Assert.IsType<BitpayErrorModel>(Assert
|
||||
.IsType<BadRequestObjectResult>(await changellyController.GetCurrencyList(user.StoreId))
|
||||
.Value);
|
||||
|
||||
updateModel.Enabled = true;
|
||||
//test with enabled method
|
||||
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await storesController.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
|
||||
Assert.IsNotType<BitpayErrorModel>(Assert
|
||||
.IsType<OkObjectResult>(await changellyController.GetCurrencyList(user.StoreId))
|
||||
.Value);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateChangellySettingsViewModel CreateDefaultChangellyParams(bool enabled)
|
||||
{
|
||||
return new UpdateChangellySettingsViewModel()
|
||||
{
|
||||
ApiKey = "6ed02cdf1b614d89a8c0ceb170eebb61",
|
||||
ApiSecret = "8fbd66a2af5fd15a6b5f8ed0159c5842e32a18538521ffa145bd6c9e124d3483",
|
||||
ChangellyMerchantId = "804298eb5753",
|
||||
Enabled = enabled
|
||||
};
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async void CanGetCurrencyListFromChangelly()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
await tester.StartAsync();
|
||||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
|
||||
//save changelly settings
|
||||
var updateModel = CreateDefaultChangellyParams(true);
|
||||
var storesController = tester.PayTester.GetController<StoresController>(user.UserId, user.StoreId);
|
||||
|
||||
//confirm saved
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await storesController.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
var factory = UnitTest1.CreateBTCPayRateFactory();
|
||||
var fetcher = new RateFetcher(factory);
|
||||
var httpClientFactory = TestUtils.CreateHttpFactory();
|
||||
var changellyController = new ChangellyController(
|
||||
new ChangellyClientProvider(tester.PayTester.StoreRepository, httpClientFactory),
|
||||
tester.NetworkProvider, fetcher);
|
||||
changellyController.IsTest = true;
|
||||
var result = Assert
|
||||
.IsType<OkObjectResult>(await changellyController.GetCurrencyList(user.StoreId))
|
||||
.Value as IEnumerable<CurrencyFull>;
|
||||
Assert.True(result.Any());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async void CanCalculateToAmountForChangelly()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
await tester.StartAsync();
|
||||
var user = tester.NewAccount();
|
||||
user.GrantAccess();
|
||||
|
||||
var updateModel = CreateDefaultChangellyParams(true);
|
||||
var storesController = tester.PayTester.GetController<StoresController>(user.UserId, user.StoreId);
|
||||
|
||||
Assert.Equal("UpdateStore", Assert.IsType<RedirectToActionResult>(
|
||||
await storesController.UpdateChangellySettings(user.StoreId, updateModel, "save")).ActionName);
|
||||
|
||||
var factory = UnitTest1.CreateBTCPayRateFactory();
|
||||
var fetcher = new RateFetcher(factory);
|
||||
var httpClientFactory = TestUtils.CreateHttpFactory();
|
||||
var changellyController = new ChangellyController(
|
||||
new ChangellyClientProvider(tester.PayTester.StoreRepository, httpClientFactory),
|
||||
tester.NetworkProvider, fetcher);
|
||||
changellyController.IsTest = true;
|
||||
Assert.IsType<decimal>(Assert
|
||||
.IsType<OkObjectResult>(await changellyController.CalculateAmount(user.StoreId, "ltc", "btc", 1.0m, default))
|
||||
.Value);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Fast", "Fast")]
|
||||
public void CanComputeBaseAmount()
|
||||
{
|
||||
Assert.Equal(1, ChangellyCalculationHelper.ComputeBaseAmount(1, 1));
|
||||
Assert.Equal(0.5m, ChangellyCalculationHelper.ComputeBaseAmount(1, 0.5m));
|
||||
Assert.Equal(2, ChangellyCalculationHelper.ComputeBaseAmount(0.5m, 1));
|
||||
Assert.Equal(4m, ChangellyCalculationHelper.ComputeBaseAmount(1, 4));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Fast", "Fast")]
|
||||
public void CanComputeCorrectAmount()
|
||||
{
|
||||
Assert.Equal(1, ChangellyCalculationHelper.ComputeCorrectAmount(0.5m, 1, 2));
|
||||
Assert.Equal(0.25m, ChangellyCalculationHelper.ComputeCorrectAmount(0.5m, 1, 0.5m));
|
||||
Assert.Equal(20, ChangellyCalculationHelper.ComputeCorrectAmount(10, 1, 2));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Rating;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
[Route("[controller]/{storeId}")]
|
||||
public class ChangellyController : Controller
|
||||
{
|
||||
private readonly ChangellyClientProvider _changellyClientProvider;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly RateFetcher _RateProviderFactory;
|
||||
|
||||
public ChangellyController(ChangellyClientProvider changellyClientProvider,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
RateFetcher rateProviderFactory)
|
||||
{
|
||||
_RateProviderFactory = rateProviderFactory ?? throw new ArgumentNullException(nameof(rateProviderFactory));
|
||||
|
||||
_changellyClientProvider = changellyClientProvider;
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("currencies")]
|
||||
public async Task<IActionResult> GetCurrencyList(string storeId)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var client = await TryGetChangellyClient(storeId);
|
||||
|
||||
return Ok(await client.GetCurrenciesFull());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(new BitpayErrorModel()
|
||||
{
|
||||
Error = e.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("calculate")]
|
||||
public async Task<IActionResult> CalculateAmount(string storeId, string fromCurrency, string toCurrency,
|
||||
decimal toCurrencyAmount, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = await TryGetChangellyClient(storeId);
|
||||
|
||||
if (fromCurrency.Equals("usd", StringComparison.InvariantCultureIgnoreCase)
|
||||
|| fromCurrency.Equals("eur", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return await HandleCalculateFiatAmount(fromCurrency, toCurrency, toCurrencyAmount, cancellationToken);
|
||||
}
|
||||
|
||||
var callCounter = 0;
|
||||
var baseRate = await client.GetExchangeAmount(fromCurrency, toCurrency, 1);
|
||||
var currentAmount = ChangellyCalculationHelper.ComputeBaseAmount(baseRate, toCurrencyAmount);
|
||||
while (true)
|
||||
{
|
||||
if (callCounter > 10)
|
||||
{
|
||||
BadRequest();
|
||||
}
|
||||
|
||||
var computedAmount = await client.GetExchangeAmount(fromCurrency, toCurrency, currentAmount);
|
||||
callCounter++;
|
||||
if (computedAmount < toCurrencyAmount)
|
||||
{
|
||||
currentAmount =
|
||||
ChangellyCalculationHelper.ComputeCorrectAmount(currentAmount, computedAmount,
|
||||
toCurrencyAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Ok(currentAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(new BitpayErrorModel()
|
||||
{
|
||||
Error = e.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Changelly> TryGetChangellyClient(string storeId)
|
||||
{
|
||||
var store = IsTest ? null : HttpContext.GetStoreData();
|
||||
storeId = storeId ?? store?.Id;
|
||||
|
||||
return await _changellyClientProvider.TryGetChangellyClient(storeId, store);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> HandleCalculateFiatAmount(string fromCurrency, string toCurrency,
|
||||
decimal toCurrencyAmount, CancellationToken cancellationToken)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
var rules = store.GetStoreBlob().GetRateRules(_btcPayNetworkProvider);
|
||||
var rate = await _RateProviderFactory.FetchRate(new CurrencyPair(toCurrency, fromCurrency), rules, cancellationToken);
|
||||
if (rate.BidAsk == null)
|
||||
return BadRequest();
|
||||
var flatRate = rate.BidAsk.Center;
|
||||
return Ok(flatRate * toCurrencyAmount);
|
||||
}
|
||||
|
||||
public bool IsTest { get; set; } = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -114,7 +114,6 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
//we do not include the default payment method in this model and instead opt to set it in the stores/storeid/payment-methods endpoints
|
||||
//blob
|
||||
//we do not include DefaultCurrencyPairs,Spread, PreferredExchange, RateScripting, RateScript in this model and instead opt to set it in stores/storeid/rates endpoints
|
||||
//we do not include ChangellySettings in this model and instead opt to set it in stores/storeid/changelly endpoints
|
||||
//we do not include CoinSwitchSettings in this model and instead opt to set it in stores/storeid/coinswitch endpoints
|
||||
//we do not include ExcludedPaymentMethods in this model and instead opt to set it in stores/storeid/payment-methods endpoints
|
||||
//we do not include EmailSettings in this model and instead opt to set it in stores/storeid/email endpoints
|
||||
|
@ -150,7 +149,6 @@ namespace BTCPayServer.Controllers.GreenField
|
|||
//we do not include the default payment method in this model and instead opt to set it in the stores/storeid/payment-methods endpoints
|
||||
//blob
|
||||
//we do not include DefaultCurrencyPairs;Spread; PreferredExchange; RateScripting; RateScript in this model and instead opt to set it in stores/storeid/rates endpoints
|
||||
//we do not include ChangellySettings in this model and instead opt to set it in stores/storeid/changelly endpoints
|
||||
//we do not include CoinSwitchSettings in this model and instead opt to set it in stores/storeid/coinswitch endpoints
|
||||
//we do not include ExcludedPaymentMethods in this model and instead opt to set it in stores/storeid/payment-methods endpoints
|
||||
//we do not include EmailSettings in this model and instead opt to set it in stores/storeid/email endpoints
|
||||
|
|
|
@ -15,7 +15,6 @@ using BTCPayServer.HostedServices;
|
|||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.InvoicingModels;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.CoinSwitch;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Rating;
|
||||
|
@ -467,10 +466,6 @@ namespace BTCPayServer.Controllers
|
|||
var currency = invoice.Currency;
|
||||
var accounting = paymentMethod.Calculate();
|
||||
|
||||
ChangellySettings changelly = (storeBlob.ChangellySettings != null && storeBlob.ChangellySettings.Enabled &&
|
||||
storeBlob.ChangellySettings.IsConfigured())
|
||||
? storeBlob.ChangellySettings
|
||||
: null;
|
||||
|
||||
CoinSwitchSettings coinswitch = (storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled &&
|
||||
storeBlob.CoinSwitchSettings.IsConfigured())
|
||||
|
@ -478,11 +473,6 @@ namespace BTCPayServer.Controllers
|
|||
: null;
|
||||
|
||||
|
||||
var changellyAmountDue = changelly != null
|
||||
? (accounting.Due.ToDecimal(MoneyUnit.BTC) *
|
||||
(1m + (changelly.AmountMarkupPercentage / 100m)))
|
||||
: (decimal?)null;
|
||||
|
||||
var paymentMethodHandler = _paymentMethodHandlerDictionary[paymentMethodId];
|
||||
|
||||
var divisibility = _CurrencyNameTable.GetNumberFormatInfo(paymentMethod.GetId().CryptoCode, false)?.CurrencyDecimalDigits;
|
||||
|
@ -521,9 +511,6 @@ namespace BTCPayServer.Controllers
|
|||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
NetworkFee = paymentMethodDetails.GetNextNetworkFee(),
|
||||
IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1,
|
||||
ChangellyEnabled = changelly != null,
|
||||
ChangellyMerchantId = changelly?.ChangellyMerchantId,
|
||||
ChangellyAmountDue = changellyAmountDue,
|
||||
CoinSwitchEnabled = coinswitch != null,
|
||||
CoinSwitchAmountMarkupPercentage = coinswitch?.AmountMarkupPercentage ?? 0,
|
||||
CoinSwitchMerchantId = coinswitch?.MerchantId,
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
public partial class StoresController
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("{storeId}/changelly")]
|
||||
public IActionResult UpdateChangellySettings(string storeId)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
UpdateChangellySettingsViewModel vm = new UpdateChangellySettingsViewModel();
|
||||
SetExistingValues(store, vm);
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
private void SetExistingValues(StoreData store, UpdateChangellySettingsViewModel vm)
|
||||
{
|
||||
|
||||
var existing = store.GetStoreBlob().ChangellySettings;
|
||||
if (existing == null)
|
||||
return;
|
||||
vm.ApiKey = existing.ApiKey;
|
||||
vm.ApiSecret = existing.ApiSecret;
|
||||
vm.ApiUrl = existing.ApiUrl;
|
||||
vm.ChangellyMerchantId = existing.ChangellyMerchantId;
|
||||
vm.Enabled = existing.Enabled;
|
||||
vm.AmountMarkupPercentage = existing.AmountMarkupPercentage;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}/changelly")]
|
||||
public async Task<IActionResult> UpdateChangellySettings(string storeId, UpdateChangellySettingsViewModel vm,
|
||||
string command)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
if (vm.Enabled)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
var changellySettings = new ChangellySettings()
|
||||
{
|
||||
ApiKey = vm.ApiKey,
|
||||
ApiSecret = vm.ApiSecret,
|
||||
ApiUrl = vm.ApiUrl,
|
||||
ChangellyMerchantId = vm.ChangellyMerchantId,
|
||||
Enabled = vm.Enabled,
|
||||
AmountMarkupPercentage = vm.AmountMarkupPercentage
|
||||
};
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case "save":
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
storeBlob.ChangellySettings = changellySettings;
|
||||
store.SetStoreBlob(storeBlob);
|
||||
await _Repo.UpdateStore(store);
|
||||
TempData[WellKnownTempData.SuccessMessage] = "Changelly settings modified";
|
||||
_changellyClientProvider.InvalidateClient(storeId);
|
||||
return RedirectToAction(nameof(UpdateStore), new
|
||||
{
|
||||
storeId
|
||||
});
|
||||
case "test":
|
||||
try
|
||||
{
|
||||
var client = new Changelly(_httpClientFactory.CreateClient(), changellySettings.ApiKey, changellySettings.ApiSecret,
|
||||
changellySettings.ApiUrl);
|
||||
var result = await client.GetCurrenciesFull();
|
||||
TempData[WellKnownTempData.SuccessMessage] = "Test Successful";
|
||||
return View(vm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = ex.Message;
|
||||
return View(vm);
|
||||
}
|
||||
default:
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ using BTCPayServer.HostedServices;
|
|||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Rating;
|
||||
using BTCPayServer.Security;
|
||||
|
@ -57,7 +56,6 @@ namespace BTCPayServer.Controllers
|
|||
ExplorerClientProvider explorerProvider,
|
||||
IFeeProviderFactory feeRateProvider,
|
||||
LanguageService langService,
|
||||
ChangellyClientProvider changellyClientProvider,
|
||||
IWebHostEnvironment env, IHttpClientFactory httpClientFactory,
|
||||
PaymentMethodHandlerDictionary paymentMethodHandlerDictionary,
|
||||
SettingsRepository settingsRepository,
|
||||
|
@ -71,7 +69,6 @@ namespace BTCPayServer.Controllers
|
|||
_TokenRepository = tokenRepo;
|
||||
_UserManager = userManager;
|
||||
_LangService = langService;
|
||||
_changellyClientProvider = changellyClientProvider;
|
||||
_TokenController = tokenController;
|
||||
_WalletProvider = walletProvider;
|
||||
_Env = env;
|
||||
|
@ -102,7 +99,6 @@ namespace BTCPayServer.Controllers
|
|||
readonly TokenRepository _TokenRepository;
|
||||
readonly UserManager<ApplicationUser> _UserManager;
|
||||
private readonly LanguageService _LangService;
|
||||
private readonly ChangellyClientProvider _changellyClientProvider;
|
||||
readonly IWebHostEnvironment _Env;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly PaymentMethodHandlerDictionary _paymentMethodHandlerDictionary;
|
||||
|
@ -537,13 +533,6 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
var changellyEnabled = storeBlob.ChangellySettings != null && storeBlob.ChangellySettings.Enabled;
|
||||
vm.ThirdPartyPaymentMethods.Add(new StoreViewModel.AdditionalPaymentMethod()
|
||||
{
|
||||
Enabled = changellyEnabled,
|
||||
Action = nameof(UpdateChangellySettings),
|
||||
Provider = "Changelly"
|
||||
});
|
||||
|
||||
var coinSwitchEnabled = storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled;
|
||||
vm.ThirdPartyPaymentMethods.Add(new StoreViewModel.AdditionalPaymentMethod()
|
||||
|
|
|
@ -7,7 +7,6 @@ using BTCPayServer.Client.JsonConverters;
|
|||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.CoinSwitch;
|
||||
using BTCPayServer.Rating;
|
||||
using BTCPayServer.Services.Mails;
|
||||
|
@ -108,10 +107,8 @@ namespace BTCPayServer.Data
|
|||
|
||||
public bool AnyoneCanInvoice { get; set; }
|
||||
|
||||
public ChangellySettings ChangellySettings { get; set; }
|
||||
public CoinSwitchSettings CoinSwitchSettings { get; set; }
|
||||
|
||||
|
||||
string _LightningDescriptionTemplate;
|
||||
public string LightningDescriptionTemplate
|
||||
{
|
||||
|
|
|
@ -10,7 +10,6 @@ using BTCPayServer.Logging;
|
|||
using BTCPayServer.PaymentRequest;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Bitcoin;
|
||||
using BTCPayServer.Payments.Changelly;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Payments.PayJoin;
|
||||
using BTCPayServer.Security;
|
||||
|
@ -218,8 +217,6 @@ namespace BTCPayServer.Hosting
|
|||
|
||||
services.AddSingleton<PaymentMethodHandlerDictionary>();
|
||||
|
||||
services.AddSingleton<ChangellyClientProvider>();
|
||||
|
||||
services.AddSingleton<NotificationManager>();
|
||||
services.AddScoped<NotificationSender>();
|
||||
|
||||
|
|
|
@ -62,12 +62,8 @@ namespace BTCPayServer.Models.InvoicingModels
|
|||
public string PaymentMethodId { get; set; }
|
||||
public string PaymentMethodName { get; set; }
|
||||
public string CryptoImage { get; set; }
|
||||
|
||||
public bool ChangellyEnabled { get; set; }
|
||||
public string StoreId { get; set; }
|
||||
public string PeerInfo { get; set; }
|
||||
public string ChangellyMerchantId { get; set; }
|
||||
public decimal? ChangellyAmountDue { get; set; }
|
||||
|
||||
public bool CoinSwitchEnabled { get; set; }
|
||||
public string CoinSwitchMode { get; set; }
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BTCPayServer.Models.StoreViewModels
|
||||
{
|
||||
public class UpdateChangellySettingsViewModel
|
||||
{
|
||||
[Required] public string ApiKey { get; set; }
|
||||
|
||||
[Required] public string ApiSecret { get; set; }
|
||||
|
||||
[Required] public string ApiUrl { get; set; } = "https://api.changelly.com";
|
||||
|
||||
[Display(Name = "Optional, Changelly Merchant Id")]
|
||||
public string ChangellyMerchantId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(0, 100)]
|
||||
[Display(Name =
|
||||
"Percentage to multiply amount requested at Changelly to avoid underpaid situations due to Changelly not guaranteeing rates. ")]
|
||||
public decimal AmountMarkupPercentage { get; set; } = new decimal(2);
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Payments.Changelly.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SshNet.Security.Cryptography;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly
|
||||
{
|
||||
public class Changelly
|
||||
{
|
||||
private readonly string _apisecret;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public Changelly(HttpClient httpClient, string apiKey, string apiSecret, string apiUrl)
|
||||
{
|
||||
_apisecret = apiSecret;
|
||||
_httpClient = httpClient;
|
||||
_httpClient.BaseAddress = new Uri(apiUrl);
|
||||
_httpClient.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
}
|
||||
|
||||
|
||||
private static string ToHexString(byte[] array)
|
||||
{
|
||||
var hex = new StringBuilder(array.Length * 2);
|
||||
foreach (var b in array)
|
||||
{
|
||||
hex.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", b);
|
||||
}
|
||||
|
||||
return hex.ToString();
|
||||
}
|
||||
|
||||
private async Task<ChangellyResponse<T>> PostToApi<T>(string message)
|
||||
{
|
||||
using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(_apisecret));
|
||||
var hashMessage = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
|
||||
var sign = ToHexString(hashMessage);
|
||||
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, "");
|
||||
request.Headers.Add("sign", sign);
|
||||
request.Content = new StringContent(message, Encoding.UTF8, "application/json");
|
||||
|
||||
var result = await _httpClient.SendAsync(request);
|
||||
|
||||
if (!result.IsSuccessStatusCode)
|
||||
throw new ChangellyException(result.ReasonPhrase);
|
||||
var content =
|
||||
await result.Content.ReadAsStringAsync();
|
||||
return JObject.Parse(content).ToObject<ChangellyResponse<T>>();
|
||||
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<CurrencyFull>> GetCurrenciesFull()
|
||||
{
|
||||
const string message = @"{
|
||||
""jsonrpc"": ""2.0"",
|
||||
""id"": 1,
|
||||
""method"": ""getCurrenciesFull"",
|
||||
""params"": []
|
||||
}";
|
||||
|
||||
var result = await PostToApi<IEnumerable<CurrencyFull>>(message);
|
||||
|
||||
return result.Result;
|
||||
}
|
||||
|
||||
public virtual async Task<decimal> GetExchangeAmount(string fromCurrency,
|
||||
string toCurrency,
|
||||
decimal amount)
|
||||
{
|
||||
var message =
|
||||
$"{{\"id\": \"test\",\"jsonrpc\": \"2.0\",\"method\": \"getExchangeAmount\",\"params\":{{\"from\": \"{fromCurrency}\",\"to\": \"{toCurrency}\",\"amount\": \"{amount}\"}}}}";
|
||||
|
||||
var result = await PostToApi<string>(message);
|
||||
|
||||
return Convert.ToDecimal(result.Result, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
namespace BTCPayServer.Payments.Changelly
|
||||
{
|
||||
public static class ChangellyCalculationHelper
|
||||
{
|
||||
public static decimal ComputeBaseAmount(decimal baseRate, decimal toAmount)
|
||||
{
|
||||
return (1m / baseRate) * toAmount;
|
||||
}
|
||||
|
||||
public static decimal ComputeCorrectAmount(decimal currentFromAmount, decimal currentAmount,
|
||||
decimal expectedAmount)
|
||||
{
|
||||
return (currentFromAmount / currentAmount) * expectedAmount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly
|
||||
{
|
||||
public class ChangellyClientProvider
|
||||
{
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
private readonly ConcurrentDictionary<string, Changelly> _clientCache =
|
||||
new ConcurrentDictionary<string, Changelly>();
|
||||
|
||||
public ChangellyClientProvider(StoreRepository storeRepository, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
public void InvalidateClient(string storeId)
|
||||
{
|
||||
if (_clientCache.ContainsKey(storeId))
|
||||
{
|
||||
_clientCache.Remove(storeId, out var value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<Changelly> TryGetChangellyClient(string storeId, StoreData storeData = null)
|
||||
{
|
||||
if (_clientCache.ContainsKey(storeId))
|
||||
{
|
||||
return _clientCache[storeId];
|
||||
}
|
||||
|
||||
if (storeData == null)
|
||||
{
|
||||
storeData = await _storeRepository.FindStore(storeId);
|
||||
if (storeData == null)
|
||||
{
|
||||
throw new ChangellyException("Store not found");
|
||||
}
|
||||
}
|
||||
|
||||
var blob = storeData.GetStoreBlob();
|
||||
var changellySettings = blob.ChangellySettings;
|
||||
|
||||
|
||||
if (changellySettings == null || !changellySettings.IsConfigured())
|
||||
{
|
||||
throw new ChangellyException("Changelly not configured for this store");
|
||||
}
|
||||
|
||||
if (!changellySettings.Enabled)
|
||||
{
|
||||
throw new ChangellyException("Changelly not enabled for this store");
|
||||
}
|
||||
|
||||
var changelly = new Changelly(_httpClientFactory.CreateClient("Changelly"), changellySettings.ApiKey,
|
||||
changellySettings.ApiSecret,
|
||||
changellySettings.ApiUrl);
|
||||
_clientCache.AddOrReplace(storeId, changelly);
|
||||
return changelly;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly
|
||||
{
|
||||
public class ChangellyException : Exception
|
||||
{
|
||||
public ChangellyException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
namespace BTCPayServer.Payments.Changelly
|
||||
{
|
||||
public class ChangellySettings
|
||||
{
|
||||
public string ApiKey { get; set; }
|
||||
public string ApiSecret { get; set; }
|
||||
public string ApiUrl { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public string ChangellyMerchantId { get; set; }
|
||||
public decimal AmountMarkupPercentage { get; set; }
|
||||
|
||||
public bool IsConfigured()
|
||||
{
|
||||
return
|
||||
!string.IsNullOrEmpty(ApiKey) ||
|
||||
!string.IsNullOrEmpty(ApiSecret) ||
|
||||
!string.IsNullOrEmpty(ApiUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly.Models
|
||||
{
|
||||
|
||||
public class ChangellyResponse<T>
|
||||
{
|
||||
[JsonProperty("jsonrpc")]
|
||||
public string JsonRPC { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public object Id { get; set; }
|
||||
[JsonProperty("result")]
|
||||
public T Result { get; set; }
|
||||
[JsonProperty("error")]
|
||||
public Error Error { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly.Models
|
||||
{
|
||||
public class CurrencyFull
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("fullName")]
|
||||
public string FullName { get; set; }
|
||||
[JsonProperty("enabled")]
|
||||
public bool Enable { get; set; }
|
||||
[JsonProperty("payinConfirmations")]
|
||||
public int PayInConfirmations { get; set; }
|
||||
[JsonProperty("image")]
|
||||
public string ImageLink { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Payments.Changelly.Models
|
||||
{
|
||||
public class Error
|
||||
{
|
||||
[JsonProperty("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
[JsonProperty("message")]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
|
@ -83,7 +83,7 @@
|
|||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
@if (Model.ChangellyEnabled || Model.CoinSwitchEnabled)
|
||||
@if (Model.CoinSwitchEnabled)
|
||||
{
|
||||
<div id="altcoins" class="bp-view payment manual-flow" v-bind:class="{ 'active': currentTab == 'altcoins'}">
|
||||
<nav v-if="srvModel.isLightning">
|
||||
|
@ -102,17 +102,16 @@
|
|||
</span>
|
||||
</div>
|
||||
<center>
|
||||
@if (Model.CoinSwitchEnabled && Model.ChangellyEnabled)
|
||||
@if (Model.CoinSwitchEnabled)
|
||||
{
|
||||
<template v-if="!selectedThirdPartyProcessor">
|
||||
<button v-on:click="selectedThirdPartyProcessor = 'coinswitch'" class="action-button">{{$t("Pay with CoinSwitch")}}</button>
|
||||
<button v-on:click="selectedThirdPartyProcessor = 'changelly'" class="action-button">{{$t("Pay with Changelly")}}</button>
|
||||
</template>
|
||||
}
|
||||
@if (Model.CoinSwitchEnabled)
|
||||
{
|
||||
<coinswitch inline-template
|
||||
v-if="!srvModel.changellyEnabled || selectedThirdPartyProcessor === 'coinswitch'"
|
||||
v-if="selectedThirdPartyProcessor === 'coinswitch'"
|
||||
:mode="srvModel.coinSwitchMode"
|
||||
:merchant-id="srvModel.coinSwitchMerchantId"
|
||||
:to-currency="srvModel.paymentMethodId"
|
||||
|
@ -121,10 +120,6 @@
|
|||
:to-currency-address="srvModel.btcAddress">
|
||||
<div>
|
||||
<a v-on:click="openDialog($event)" :href="url" class="action-button" v-show="url && !opened">{{$t("Pay with CoinSwitch")}}</a>
|
||||
@if (Model.ChangellyEnabled)
|
||||
{
|
||||
<button v-show="!opened" v-on:click="$parent.selectedThirdPartyProcessor = 'changelly'" class="btn-link mt-2">{{$t("Pay with Changelly")}}</button>
|
||||
}
|
||||
<iframe
|
||||
v-if="showInlineIFrame"
|
||||
v-on:load="onLoadIframe"
|
||||
|
@ -135,45 +130,6 @@
|
|||
</div>
|
||||
</coinswitch>
|
||||
}
|
||||
@if (Model.ChangellyEnabled)
|
||||
{
|
||||
<changelly inline-template
|
||||
v-if="!srvModel.coinSwitchEnabled || selectedThirdPartyProcessor === 'changelly'"
|
||||
:merchant-id="srvModel.changellyMerchantId"
|
||||
:store-id="srvModel.storeId"
|
||||
:to-currency="srvModel.paymentMethodId"
|
||||
:to-currency-due="srvModel.changellyAmountDue"
|
||||
:to-currency-address="srvModel.btcAddress">
|
||||
<div class="changelly-component">
|
||||
<div class="changelly-component-dropdown-holder" v-show="prettyDropdownInstance">
|
||||
<select
|
||||
v-model="selectedFromCurrency"
|
||||
:disabled="isLoading"
|
||||
v-on:change="onCurrencyChange($event)"
|
||||
ref="changellyCurrenciesDropdown">
|
||||
<option value="">{{$t("ConversionTab_CurrencyList_Select_Option")}}</option>
|
||||
<option v-for="currency of currencies"
|
||||
:data-prefix="'<img src=\''+currency.image+'\'/>'"
|
||||
:value="currency.name">{{currency.fullName}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<a v-on:click="openDialog($event)" :href="url" class="action-button" v-show="url">{{$t("Pay with Changelly")}}</a>
|
||||
@if (Model.CoinSwitchEnabled)
|
||||
{
|
||||
<button v-on:click="$parent.selectedThirdPartyProcessor = 'coinswitch'" class="btn-link mt-2">{{$t("Pay with CoinSwitch")}}</button>
|
||||
}
|
||||
<button class="retry-button" v-if="calculateError" v-on:click="retry('calculateAmount')">
|
||||
{{$t("ConversionTab_CalculateAmount_Error")}}
|
||||
</button>
|
||||
<button class="retry-button" v-if="currenciesError" v-on:click="retry('loadCurrencies')">
|
||||
{{$t("ConversionTab_LoadCurrencies_Error")}}
|
||||
</button>
|
||||
<div v-show="isLoading" class="general__spinner">
|
||||
<partial name="Checkout-Spinner"/>
|
||||
</div>
|
||||
</div>
|
||||
</changelly>
|
||||
}
|
||||
</center>
|
||||
</nav>
|
||||
</div>
|
||||
|
@ -195,17 +151,8 @@
|
|||
<div class="payment-tabs__tab" id="copy-tab" v-on:click="switchTab('copy')" v-bind:class="{ 'active': currentTab == 'copy'}" >
|
||||
<span>{{$t("Copy")}}</span>
|
||||
</div>
|
||||
@if (Model.ChangellyEnabled || Model.CoinSwitchEnabled)
|
||||
{
|
||||
<div class="payment-tabs__tab" id="altcoins-tab" v-on:click="switchTab('altcoins')" v-bind:class="{ 'active': currentTab == 'altcoins'}" >
|
||||
<span>{{$t("Conversion")}}</span>
|
||||
</div>
|
||||
<div id="tabsSlider" class="payment-tabs__slider three-tabs" v-bind:class="['slide-'+currentTab]"></div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="tabsSlider" class="payment-tabs__slider" v-bind:class="['slide-'+currentTab]"></div>
|
||||
}
|
||||
|
||||
<div id="tabsSlider" class="payment-tabs__slider" v-bind:class="['slide-'+currentTab]"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
@ -216,7 +163,6 @@
|
|||
template: "#bitcoin-lightning-method-checkout-template",
|
||||
components: {
|
||||
qrcode: VueQrcode,
|
||||
changelly: ChangellyComponent,
|
||||
coinswitch: CoinSwitchComponent
|
||||
},
|
||||
data: function() {
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
@using Microsoft.AspNetCore.Mvc.Rendering
|
||||
@model UpdateChangellySettingsViewModel
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.Index, "Update Store Changelly Settings");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
<form method="post">
|
||||
<div class="alert alert-warning" role="alert">
|
||||
If you are enabling Changelly support, we advise that you configure the invoice expiration to a minimum of 30 minutes as it may take longer than the default 15 minutes to convert the funds.
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiUrl"></label>
|
||||
<input asp-for="ApiUrl" class="form-control"/>
|
||||
<span asp-validation-for="ApiUrl" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey"></label>
|
||||
<input asp-for="ApiKey" class="form-control"/>
|
||||
<span asp-validation-for="ApiKey" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiSecret"></label>
|
||||
<input asp-for="ApiSecret" class="form-control"/>
|
||||
<span asp-validation-for="ApiSecret" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ChangellyMerchantId"></label>
|
||||
<input asp-for="ChangellyMerchantId" class="form-control"/>
|
||||
<span asp-validation-for="ChangellyMerchantId" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="AmountMarkupPercentage"></label>
|
||||
<input asp-for="AmountMarkupPercentage" class="form-control"/>
|
||||
<span asp-validation-for="AmountMarkupPercentage" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Enabled"></label>
|
||||
<input asp-for="Enabled" type="checkbox" class="form-check"/>
|
||||
</div>
|
||||
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
|
||||
<button name="command" type="submit" value="test" class="btn btn-primary">Test Settings</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
|
@ -11510,46 +11510,7 @@ low-fee-timeline {
|
|||
opacity: 1;
|
||||
transition: opacity 1s ease;
|
||||
}
|
||||
|
||||
.changelly-component {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.changelly-component-dropdown-holder {
|
||||
height: 32px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.changelly-component .general__spinner bp-spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.changelly-component .general__spinner bp-spinner svg {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.changelly-component .retry-button {
|
||||
border-radius: 5px;
|
||||
border: 1px solid #a9a9a9;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
min-width: 100px;
|
||||
padding-left: 0.8rem;
|
||||
padding-right: 0.8rem;
|
||||
min-height: 30px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.changelly-component .retry-button :hover {
|
||||
border-color: #7f7f7f;
|
||||
}
|
||||
|
||||
.changelly-component .prettydropdown li img {
|
||||
width: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#prettydropdown-DefaultLang {
|
||||
min-width: 200px;
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
var ChangellyComponent =
|
||||
{
|
||||
props: ["storeId", "toCurrency", "toCurrencyDue", "toCurrencyAddress", "merchantId"],
|
||||
data: function () {
|
||||
return {
|
||||
currencies: [],
|
||||
isLoading: true,
|
||||
calculatedAmount: 0,
|
||||
selectedFromCurrency: "",
|
||||
prettyDropdownInstance: null,
|
||||
calculateError: false,
|
||||
currenciesError: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
url: function () {
|
||||
if (this.calculatedAmount && this.selectedFromCurrency && !this.isLoading) {
|
||||
return "https://changelly.com/widget/v1?auth=email" +
|
||||
"&from=" +
|
||||
this.selectedFromCurrency +
|
||||
"&to=" +
|
||||
this.toCurrency +
|
||||
"&address=" +
|
||||
this.toCurrencyAddress +
|
||||
"&amount=" +
|
||||
this.calculatedAmount +
|
||||
(this.merchantId ? "&merchant_id=" + this.merchantId + "&ref_id=" + this.merchantId : "");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedFromCurrency: function (val) {
|
||||
if (val) {
|
||||
this.calculateAmount();
|
||||
} else {
|
||||
this.calculateAmount = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.prettyDropdownInstance = initDropdown(this.$refs.changellyCurrenciesDropdown);
|
||||
this.loadCurrencies();
|
||||
},
|
||||
methods: {
|
||||
getUrl: function () {
|
||||
return window.location.origin + "/changelly/" + this.storeId;
|
||||
},
|
||||
loadCurrencies: function () {
|
||||
this.isLoading = true;
|
||||
this.currenciesError = false;
|
||||
$.ajax(
|
||||
{
|
||||
context: this,
|
||||
url: this.getUrl() + "/currencies",
|
||||
dataType: "json",
|
||||
success: function (result) {
|
||||
|
||||
for (i = 0; i < result.length; i++) {
|
||||
if (result[i].enabled &&
|
||||
result[i].name.toLowerCase() !== this.toCurrency.toLowerCase()) {
|
||||
this.currencies.push(result[i]);
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
Vue.nextTick(function () {
|
||||
self.prettyDropdownInstance
|
||||
.refresh()
|
||||
.on("change",
|
||||
function (event) {
|
||||
self.onCurrencyChange(self.$refs.changellyCurrenciesDropdown.value);
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
error: function(){
|
||||
this.currenciesError = true;
|
||||
},
|
||||
complete: function () {
|
||||
this.isLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
calculateAmount: function () {
|
||||
this.isLoading = true;
|
||||
this.calculateError = false;
|
||||
$.ajax(
|
||||
{
|
||||
url: this.getUrl() + "/calculate",
|
||||
dataType: "json",
|
||||
data: {
|
||||
fromCurrency: this.selectedFromCurrency,
|
||||
toCurrency: this.toCurrency,
|
||||
toCurrencyAmount: this.toCurrencyDue
|
||||
},
|
||||
context: this,
|
||||
success: function (result) {
|
||||
this.calculatedAmount = result;
|
||||
},
|
||||
error: function(){
|
||||
this.calculateError = true;
|
||||
},
|
||||
complete: function () {
|
||||
this.isLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
retry: function(type){
|
||||
if(type=="loadCurrencies"){
|
||||
this.loadCurrencies();
|
||||
}else if(type=="calculateAmount"){
|
||||
this.calculateAmount();
|
||||
}
|
||||
},
|
||||
onCurrencyChange: function (value) {
|
||||
this.selectedFromCurrency = value;
|
||||
this.calculatedAmount = 0;
|
||||
},
|
||||
openDialog: function (e) {
|
||||
if (e && e.preventDefault) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
var changellyWindow = window.open(
|
||||
this.url,
|
||||
'Changelly',
|
||||
'width=600,height=470,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=0,left=0,top=0');
|
||||
changellyWindow.focus();
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Add table
Reference in a new issue