Remove Coinswitch entirely

This commit is contained in:
Kukks 2021-09-28 10:33:11 +02:00
parent edfde494fa
commit ed1ec2300d
17 changed files with 0 additions and 539 deletions

View file

@ -122,7 +122,6 @@ namespace BTCPayServer.Controllers.GreenField
DefaultPaymentMethod = data.GetDefaultPaymentId(_btcPayNetworkProvider)?.ToStringNormalized(), DefaultPaymentMethod = data.GetDefaultPaymentId(_btcPayNetworkProvider)?.ToStringNormalized(),
//blob //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 DefaultCurrencyPairs,Spread, PreferredExchange, RateScripting, RateScript in this model and instead opt to set it in stores/storeid/rates 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 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 //we do not include EmailSettings in this model and instead opt to set it in stores/storeid/email endpoints
//we do not include PaymentMethodCriteria because moving the CurrencyValueJsonConverter to the Client csproj is hard and requires a refactor (#1571 & #1572) //we do not include PaymentMethodCriteria because moving the CurrencyValueJsonConverter to the Client csproj is hard and requires a refactor (#1571 & #1572)
@ -160,7 +159,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 //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 //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 DefaultCurrencyPairs;Spread; PreferredExchange; RateScripting; RateScript in this model and instead opt to set it in stores/storeid/rates 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 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 //we do not include EmailSettings in this model and instead opt to set it in stores/storeid/email endpoints
//we do not include OnChainMinValue and LightningMaxValue because moving the CurrencyValueJsonConverter to the Client csproj is hard and requires a refactor (#1571 & #1572) //we do not include OnChainMinValue and LightningMaxValue because moving the CurrencyValueJsonConverter to the Client csproj is hard and requires a refactor (#1571 & #1572)

View file

@ -21,7 +21,6 @@ using BTCPayServer.Models;
using BTCPayServer.Models.InvoicingModels; using BTCPayServer.Models.InvoicingModels;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.Lightning;
using BTCPayServer.Plugins.CoinSwitch;
using BTCPayServer.Rating; using BTCPayServer.Rating;
using BTCPayServer.Security; using BTCPayServer.Security;
using BTCPayServer.Services.Invoices; using BTCPayServer.Services.Invoices;

View file

@ -7,7 +7,6 @@ using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.JsonConverters; using BTCPayServer.JsonConverters;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Plugins.CoinSwitch;
using BTCPayServer.Rating; using BTCPayServer.Rating;
using BTCPayServer.Services.Mails; using BTCPayServer.Services.Mails;
using BTCPayServer.Services.Rates; using BTCPayServer.Services.Rates;

View file

@ -1,84 +0,0 @@
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Client;
using BTCPayServer.Data;
using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace BTCPayServer.Plugins.CoinSwitch
{
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[Route("plugins/{storeId}/coinswitch")]
public class CoinSwitchController : Controller
{
private readonly StoreRepository _storeRepository;
public CoinSwitchController(StoreRepository storeRepository)
{
_storeRepository = storeRepository;
}
[HttpGet("")]
public IActionResult UpdateCoinSwitchSettings(string storeId)
{
var store = HttpContext.GetStoreData();
if (store == null)
return NotFound();
UpdateCoinSwitchSettingsViewModel vm = new UpdateCoinSwitchSettingsViewModel();
SetExistingValues(store, vm);
return View(vm);
}
private void SetExistingValues(StoreData store, UpdateCoinSwitchSettingsViewModel vm)
{
var existing = store.GetStoreBlob().GetCoinSwitchSettings();
if (existing == null)
return;
vm.MerchantId = existing.MerchantId;
vm.Enabled = existing.Enabled;
vm.Mode = existing.Mode;
vm.AmountMarkupPercentage = existing.AmountMarkupPercentage;
}
[HttpPost("")]
public async Task<IActionResult> UpdateCoinSwitchSettings(string storeId, UpdateCoinSwitchSettingsViewModel vm,
string command)
{
var store = HttpContext.GetStoreData();
if (store == null)
return NotFound();
if (vm.Enabled)
{
if (!ModelState.IsValid)
{
return View(vm);
}
}
var coinSwitchSettings = new CoinSwitchSettings()
{
MerchantId = vm.MerchantId,
Enabled = vm.Enabled,
Mode = vm.Mode,
AmountMarkupPercentage = vm.AmountMarkupPercentage
};
switch (command)
{
case "save":
var storeBlob = store.GetStoreBlob();
storeBlob.SetCoinSwitchSettings(coinSwitchSettings);
store.SetStoreBlob(storeBlob);
await _storeRepository.UpdateStore(store);
TempData[WellKnownTempData.SuccessMessage] = "CoinSwitch settings modified";
return RedirectToAction(nameof(UpdateCoinSwitchSettings), new {storeId});
default:
return View(vm);
}
}
}
}

View file

@ -1,32 +0,0 @@
using BTCPayServer.Data;
using NBitcoin;
using NBXplorer;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Plugins.CoinSwitch
{
public static class CoinSwitchExtensions
{
public const string StoreBlobKey = "coinSwitchSettings";
public static CoinSwitchSettings GetCoinSwitchSettings(this StoreBlob storeBlob)
{
if (storeBlob.AdditionalData.TryGetValue(StoreBlobKey, out var rawS) && rawS is JObject rawObj)
{
return new Serializer(null).ToObject<CoinSwitchSettings>(rawObj);
}
return null;
}
public static void SetCoinSwitchSettings(this StoreBlob storeBlob, CoinSwitchSettings settings)
{
if (settings is null)
{
storeBlob.AdditionalData.Remove(StoreBlobKey);
}
else
{
storeBlob.AdditionalData.AddOrReplace(StoreBlobKey, JObject.FromObject(settings));
}
}
}
}

View file

@ -1,34 +0,0 @@
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Abstractions.Services;
using Microsoft.Extensions.DependencyInjection;
namespace BTCPayServer.Plugins.CoinSwitch
{
public class CoinSwitchPlugin : BaseBTCPayServerPlugin
{
public override string Identifier => "BTCPayServer.Plugins.CoinSwitch";
public override string Name => "CoinSwitch";
public override string Description =>
"Allows you to embed a coinswitch conversion screen to allow customers to pay with altcoins.";
public override void Execute(IServiceCollection applicationBuilder)
{
applicationBuilder.AddSingleton<CoinSwitchService>();
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/StoreIntegrationCoinSwitchOption",
"store-integrations-list"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/CheckoutContentExtension",
"checkout-bitcoin-post-content"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/CheckoutContentExtension",
"checkout-ethereum-post-content"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/CheckoutTabExtension",
"checkout-bitcoin-post-tabs"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/CheckoutTabExtension",
"checkout-ethereum-post-tabs"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("CoinSwitch/CheckoutEnd",
"checkout-end"));
base.Execute(applicationBuilder);
}
}
}

View file

@ -1,36 +0,0 @@
using System;
using System.Threading.Tasks;
using BTCPayServer.Data;
using BTCPayServer.Services.Stores;
using Microsoft.Extensions.Caching.Memory;
namespace BTCPayServer.Plugins.CoinSwitch
{
public class CoinSwitchService: IDisposable
{
private readonly StoreRepository _storeRepository;
private readonly IMemoryCache _memoryCache;
public CoinSwitchService(StoreRepository storeRepository, IMemoryCache memoryCache)
{
_storeRepository = storeRepository;
_memoryCache = memoryCache;
}
public async Task<CoinSwitchSettings> GetCoinSwitchForInvoice(string id)
{
return await _memoryCache.GetOrCreateAsync($"{nameof(CoinSwitchService)}-{id}", async entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1);
var d = await _storeRepository.GetStoreByInvoiceId(id);
return d?.GetStoreBlob()?.GetCoinSwitchSettings();
});
}
public void Dispose()
{
_memoryCache?.Dispose();
}
}
}

View file

@ -1,16 +0,0 @@
namespace BTCPayServer.Plugins.CoinSwitch
{
public class CoinSwitchSettings
{
public string MerchantId { get; set; }
public string Mode { get; set; }
public bool Enabled { get; set; }
public decimal AmountMarkupPercentage { get; set; }
public bool IsConfigured()
{
return
!string.IsNullOrEmpty(MerchantId);
}
}
}

View file

@ -1,27 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BTCPayServer.Models.StoreViewModels
{
public class UpdateCoinSwitchSettingsViewModel
{
public string MerchantId { get; set; }
public bool Enabled { get; set; }
[Display(Name = "Integration Mode")]
public string Mode { get; set; } = "inline";
[Required]
[Range(0, 100)]
[Display(Name =
"Percentage to multiply amount requested at Coinswitch to avoid underpaid situations due to Coinswitch not guaranteeing rates. ")]
public decimal AmountMarkupPercentage { get; set; } = new decimal(2);
public List<SelectListItem> Modes { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "popup", Text = "Open in a popup" },
new SelectListItem { Value = "inline", Text = "Embed inside Checkout UI " },
};
}
}

View file

@ -1,49 +0,0 @@
@using BTCPayServer.Views.Stores
@using BTCPayServer.Abstractions.Extensions
@model UpdateCoinSwitchSettingsViewModel
@{
Layout = "../Shared/_NavLayout.cshtml";
ViewData["NavPartialName"] = "../Stores/_Nav";
ViewData.SetActivePageAndTitle(StoreNavPages.Integrations, "Update Store CoinSwitch Settings", Context.GetStoreData().StoreName);
}
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
<div class="row">
<div class="col-md-10">
<form method="post">
<div class="alert alert-warning" role="alert">
If you are enabling CoinSwitch 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>
<p>
You can obtain a merchant id at
<a href="https://coinswitch.co/switch/setup/btcpay" target="_blank" rel="noreferrer noopener">
https://coinswitch.co/switch/setup/btcpay
</a>
</p>
<div class="form-group">
<label asp-for="MerchantId" class="form-label"></label>
<input asp-for="MerchantId" class="form-control"/>
<span asp-validation-for="MerchantId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Mode" class="form-label"></label>
<select asp-for="Mode" asp-items="Model.Modes" class="form-select"></select>
</div>
<div class="form-group">
<label asp-for="AmountMarkupPercentage" class="form-label"></label>
<input asp-for="AmountMarkupPercentage" class="form-control"/>
<span asp-validation-for="AmountMarkupPercentage" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label asp-for="Enabled" class="form-check-label"></label>
<input asp-for="Enabled" type="checkbox" class="form-check-input"/>
</div>
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
@section PageFootContent {
<partial name="_ValidationScriptsPartial" />
}

View file

@ -1,41 +0,0 @@
@using BTCPayServer.Plugins.CoinSwitch
@inject CoinSwitchService CoinSwitchService
@{
var invoiceId = this.Context.GetRouteValue("invoiceId")?.ToString();
var settings = await CoinSwitchService.GetCoinSwitchForInvoice(invoiceId);
if (settings?.IsConfigured() is true && settings.Enabled)
{
<div id="altcoins" class="bp-view payment manual-flow" v-bind:class="{ 'active': currentTab == 'altcoins'}">
<nav>
<div class="manual__step-two__instructions">
<span>
{{$t("ConversionTab_BodyTop", srvModel)}}
<br/><br/>
{{$t("ConversionTab_BodyDesc", srvModel)}}
</span>
</div>
<center>
<coinswitch inline-template
:merchant-id="srvModel.coinSwitchMerchantId"
:to-currency="srvModel.paymentMethodId"
:to-currency-due="srvModel.btcDue * (1 + (@settings.AmountMarkupPercentage / 100)) "
mode = '@settings.Mode'
merchant-id="@settings.MerchantId"
:autoload="true"
: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>
<iframe
v-if="showInlineIFrame"
v-on:load="onLoadIframe"
style="height: 100%; position: fixed; top: 0; width: 100%; left: 0;"
sandbox="allow-scripts allow-forms allow-popups allow-same-origin"
:src="url">
</iframe>
</div>
</coinswitch>
</center>
</nav>
</div>
}
}

View file

@ -1 +0,0 @@
<script src="~/checkout/js/coinswitchComponent.js"></script>

View file

@ -1,12 +0,0 @@
@using BTCPayServer.Plugins.CoinSwitch
@inject CoinSwitchService CoinSwitchService
@{
var invoiceId = this.Context.GetRouteValue("invoiceId")?.ToString();
var settings = await CoinSwitchService.GetCoinSwitchForInvoice(invoiceId);
}
@if (settings?.IsConfigured() is true)
{
<div class="payment-tabs__tab" id="altcoins-tab" v-on:click="switchTab('altcoins')" v-bind:class="{ 'active': currentTab == 'altcoins'}">
<span>{{$t("Conversion")}}</span>
</div>
}

View file

@ -1,39 +0,0 @@
@using BTCPayServer.Plugins.CoinSwitch
@{
var settings = Context.GetStoreData().GetStoreBlob().GetCoinSwitchSettings();
}
<li class="list-group-item bg-tile ">
<div class="d-flex align-items-center">
<span class="d-flex flex-wrap flex-fill flex-column flex-sm-row">
<strong class="me-3">
CoinSwitch
</strong>
<span title="" class="d-flex me-3">
<span class="text-secondary">Accept payments in altcoins that are not supported by BTCPay Server.</span>
</span>
</span>
<span class="d-flex align-items-center fw-semibold">
@if (settings?.IsConfigured() is true && settings?.Enabled is true)
{
<span class="d-flex align-items-center text-success">
<span class="me-2 btcpay-status btcpay-status--enabled"></span>
Enabled
</span>
<span class="text-light ms-3 me-2">|</span>
<a lass="btn btn-link px-1 py-1 fw-semibold" asp-controller="CoinSwitch" asp-action="UpdateCoinSwitchSettings" asp-route-storeId="@Context.GetRouteValue("storeId")">
Modify
</a>
}
else
{
<span class="d-flex align-items-center text-danger">
<span class="me-2 btcpay-status btcpay-status--disabled"></span>
Disabled
</span>
<a class="btn btn-primary btn-sm ms-4 px-3 py-1 fw-semibold" asp-controller="CoinSwitch" asp-action="UpdateCoinSwitchSettings" asp-route-storeId="@Context.GetRouteValue("storeId")">
Setup
</a>
}
</span>
</div>
</li>

View file

@ -90,11 +90,6 @@
} }
return r; return r;
}, },
coinswitchAmountDue: function() {
return this.srvModel.coinSwitchAmountMarkupPercentage
? this.srvModel.btcDue * (1 + (this.srvModel.coinSwitchAmountMarkupPercentage / 100))
: this.srvModel.btcDue;
},
scanDisplayQr: function() { scanDisplayQr: function() {
return this.srvModel.invoiceBitcoinUrlQR; return this.srvModel.invoiceBitcoinUrlQR;
} }

View file

@ -1,93 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CoinSwitch</title>
<script>
var script = document.createElement('script'),
head = document.head || document.getElementsByTagName('head')[0];
script.src = 'https://files.coinswitch.co/public/js/cs_switch.js';
head.insertBefore(script, head.firstChild);
script.addEventListener('load', function () {
var qs = (function (a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i) {
var p = a[i].split('=', 2);
if (p.length == 1)
b[p[0]] = "";
else
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
var merchantId = qs["merchant_id"];
var toCurrencyDue = qs["toCurrencyDue"];
var toCurrencyAddress = qs["toCurrencyAddress"];
var toCurrency = qs["toCurrency"];
var mode = qs["mode"];
document.body.classList.add(mode);
var orderId = null;
var payment = new Coinswitch(merchantId);
if(window.localStorage){
orderId= window.localStorage.getItem(toCurrencyAddress);
}
var config = {
to_currency: toCurrency.toLowerCase(),
to_currency_address: toCurrencyAddress,
to_amount: parseFloat(toCurrencyDue),
state: orderId
};
payment.on('Exchange:Ready', function(){
waitForCoinSwitch();
});
payment.on("Exchange:Complete", function () {
if(window.localStorage){
window.localStorage.removeItem(toCurrencyAddress);
}
window.close();
});
payment.on("Exchange:Initiated", function(orderId) {
if(window.localStorage){
window.localStorage.setItem(toCurrencyAddress,orderId);
}
});
payment.on("Exchange:Closed", function () {
window.close();
window.postMessage("popup-closed", "*");
});
function waitForCoinSwitch() {
if (typeof payment.open !== "function") {
setTimeout(waitForCoinSwitch, 1000);
return;
}
payment.open(config);
}
});
</script>
<style>
body.popup #CoinSwitchPayment .cs-pay {
height: 100%;
}
body.popup #CoinSwitchPayment .cs-pay__main {
width: 100%;
min-height: 90vh;
padding-bottom: 20px;
}
body.popup #CoinSwitchPayment .cs-pay__dismiss-row {
display: none;
}
</style>
</head>
<body>
</body>
</html>

View file

@ -1,66 +0,0 @@
Vue.component("coinswitch" ,
{
props: ["toCurrency", "toCurrencyDue", "toCurrencyAddress", "merchantId", "autoload", "mode"],
data: function () {
return {
opened: false
};
},
computed: {
showInlineIFrame: function () {
return this.url && this.opened;
},
url: function () {
return window.location.origin + "/checkout/coinswitch.html?" +
"&toCurrency=" +
this.toCurrency +
"&toCurrencyAddress=" +
this.toCurrencyAddress +
"&toCurrencyDue=" +
this.toCurrencyDue +
"&mode=" +
this.mode +
(this.merchantId ? "&merchant_id=" + this.merchantId : "");
}
},
methods: {
openDialog: function (e) {
if (e && e.preventDefault) {
e.preventDefault();
}
if (this.mode === 'inline') {
this.opened = true;
} else if (this.mode === "popup") {
var coinSwitchWindow = window.open(
this.url,
'CoinSwitch',
'width=360,height=650,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=0,left=0,top=0');
coinSwitchWindow.opener = null;
coinSwitchWindow.focus();
}
},
closeDialog: function () {
if (this.mode === 'inline') {
this.opened = false;
}
},
onLoadIframe: function (event) {
$("#prettydropdown-DefaultLang").hide();
var c = this.closeDialog.bind(this);
event.currentTarget.contentWindow.addEventListener("message", function (evt) {
if (evt && evt.data == "popup-closed") {
c();
$("#prettydropdown-DefaultLang").show();
}
});
}
},
mounted: function () {
if (this.autoload) {
this.openDialog();
}
}
});