mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-04 14:44:30 +01:00
Merge branch 'lepipele-dev-shapeshift'
This commit is contained in:
@@ -229,6 +229,7 @@ namespace BTCPayServer.Controllers
|
||||
Status = invoice.Status,
|
||||
CryptoImage = "/" + GetImage(paymentMethodId, network),
|
||||
NetworkFeeDescription = $"{accounting.TxRequired} transaction{(accounting.TxRequired > 1 ? "s" : "")} x {paymentMethodDetails.GetTxFee()} {network.CryptoCode}",
|
||||
AllowCoinConversion = store.GetStoreBlob().AllowCoinConversion,
|
||||
AvailableCryptos = invoice.GetPaymentMethods(_NetworkProvider)
|
||||
.Where(i => i.Network != null)
|
||||
.Select(kv=> new PaymentModel.AvailableCrypto()
|
||||
|
||||
@@ -222,6 +222,7 @@ namespace BTCPayServer.Controllers
|
||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||
vm.RateMultiplier = (double)storeBlob.GetRateMultiplier();
|
||||
vm.PreferredExchange = storeBlob.PreferredExchange.IsCoinAverage() ? "coinaverage" : storeBlob.PreferredExchange;
|
||||
vm.AllowCoinConversion = storeBlob.AllowCoinConversion;
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
@@ -298,6 +299,7 @@ namespace BTCPayServer.Controllers
|
||||
blob.PreferredExchange = model.PreferredExchange;
|
||||
|
||||
blob.SetRateMultiplier(model.RateMultiplier);
|
||||
blob.AllowCoinConversion = model.AllowCoinConversion;
|
||||
|
||||
if (store.SetStoreBlob(blob))
|
||||
{
|
||||
|
||||
@@ -213,6 +213,10 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public bool AllowCoinConversion
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[DefaultValue(60)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public int MonitoringExpiration
|
||||
|
||||
@@ -43,5 +43,7 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
public int MaxTimeMinutes { get; internal set; }
|
||||
public string PaymentType { get; internal set; }
|
||||
public string PaymentMethodId { get; internal set; }
|
||||
|
||||
public bool AllowCoinConversion { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,12 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name = "Allow conversion through third party (Shapeshift, Changelly...)")]
|
||||
public bool AllowCoinConversion
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get; set;
|
||||
|
||||
@@ -170,23 +170,20 @@
|
||||
<div class="payment-tabs__tab" id="copy-tab">
|
||||
<span i18n="">Copy</span>
|
||||
</div>
|
||||
<div class="payment-tabs__slider"></div>
|
||||
@if (Model.AllowCoinConversion)
|
||||
{
|
||||
<div class="payment-tabs__tab" id="altcoins-tab">
|
||||
<span i18n="">Conversion</span>
|
||||
</div>
|
||||
<div id="tabsSlider" class="payment-tabs__slider three-tabs"></div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="tabsSlider" class="payment-tabs__slider"></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div adjust-height="" class="payment-box">
|
||||
<div class="bp-view payment scan" id="scan">
|
||||
<div class="payment__scan">
|
||||
<img v-bind:src="srvModel.cryptoImage" style="position: absolute; height:64px; width:64px; left:118px; top:96px;" />
|
||||
<qrcode v-bind:val="srvModel.invoiceBitcoinUrlQR" v-bind:size="256" bg-color="#f5f5f7" fg-color="#000">
|
||||
</qrcode>
|
||||
</div>
|
||||
<div class="payment__details__instruction__open-wallet">
|
||||
<a class="payment__details__instruction__open-wallet__btn action-button" v-bind:href="srvModel.invoiceBitcoinUrl">
|
||||
<span i18n="">Open in wallet</span>
|
||||
<span class="glyphicon glyphicon-new-window"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bp-view payment manual-flow enter-contact-email active" id="emailAddressView">
|
||||
<form class="manual__step-one refund-address-form contact-email-form" id="emailAddressForm" name="emailAddressForm" novalidate="">
|
||||
<div class="manual__step-one__header">
|
||||
@@ -211,7 +208,7 @@
|
||||
<bp-spinner>
|
||||
<svg xml:space="preserve" style="enable-background:new 0 0 50 50;" version="1.1" viewBox="0 0 50 50" x="0px" xmlns="http://www.w3.org/2000/svg" y="0px">
|
||||
<path d="M11.1,29.6c-0.5-1.5-0.8-3-0.8-4.6c0-8.1,6.6-14.7,14.7-14.7S39.7,16.9,39.7,25c0,1.6-0.3,3.2-0.8,4.6l6.1,2c0.7-2.1,1.1-4.3,1.1-6.6c0-11.7-9.5-21.2-21.2-21.2S3.8,13.3,3.8,25c0,2.3,0.4,4.5,1.1,6.6L11.1,29.6z"></path>
|
||||
</svg>
|
||||
</svg>
|
||||
</bp-spinner>
|
||||
</div>
|
||||
</button>
|
||||
@@ -219,6 +216,94 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bp-view payment scan" id="scan">
|
||||
<div class="payment__scan">
|
||||
<img v-bind:src="srvModel.cryptoImage" style="position: absolute; height:64px; width:64px; left:118px; top:96px;" />
|
||||
<qrcode v-bind:val="srvModel.invoiceBitcoinUrlQR" v-bind:size="256" bg-color="#f5f5f7" fg-color="#000">
|
||||
</qrcode>
|
||||
</div>
|
||||
<div class="payment__details__instruction__open-wallet">
|
||||
<a class="payment__details__instruction__open-wallet__btn action-button" v-bind:href="srvModel.invoiceBitcoinUrl">
|
||||
<span i18n="">Open in wallet</span>
|
||||
<span class="glyphicon glyphicon-new-window"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bp-view payment manual-flow" id="copy">
|
||||
<div class="manual__step-two__instructions">
|
||||
<span i18n="">To complete your payment, please send {{ srvModel.btcDue }} {{ srvModel.cryptoCode }} to the address below.</span>
|
||||
</div>
|
||||
<div class="manual-box flipped" style="margin-bottom: 30px;">
|
||||
<div class="manual-box__amount">
|
||||
<div class="manual-box__amount__label label" i18n="">Amount</div>
|
||||
<!---->
|
||||
<div class="manual-box__amount__value copy-cursor" ngxclipboard="">
|
||||
<span>{{srvModel.btcDue}}</span> {{ srvModel.cryptoCode }}
|
||||
<div class="copied-label">
|
||||
<span i18n="">Copied</span>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="manual-box__address">
|
||||
<div class="flipper flipped-initially">
|
||||
<div class="back"></div>
|
||||
<div class="front">
|
||||
<div class="manual-box__address__arrow"></div>
|
||||
<div class="manual-box__address__label label" i18n="">Address</div>
|
||||
<!---->
|
||||
<div class="manual-box__address__value copy-cursor" ngxclipboard="">
|
||||
<div class="manual-box__address__wrapper">
|
||||
<div class="manual-box__address__wrapper__logo">
|
||||
<img :src="srvModel.cryptoImage" height="16" />
|
||||
</div>
|
||||
<div class="manual-box__address__wrapper__value" style="overflow:hidden;max-width:240px;">{{srvModel.btcAddress}}</div>
|
||||
</div>
|
||||
<div class="copied-label" style="top: 5px;">
|
||||
<span i18n="">Copied</span>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (Model.AllowCoinConversion)
|
||||
{
|
||||
<div id="altcoins" class="bp-view payment manual-flow">
|
||||
<div v-if="srvModel.paymentMethodId != 'BTC_LightningLike'">
|
||||
<div class="manual__step-two__instructions">
|
||||
<span>
|
||||
You can pay {{ srvModel.btcDue }} {{ srvModel.cryptoCode }} using altcoins other than the ones merchant directly supports.
|
||||
<br /><br />
|
||||
This service is provided by 3rd party. Please keep in mind that
|
||||
<span style="font-weight: 900;">we have no control</span> over how providers will forward your funds.
|
||||
Invoice will only be marked paid once funds are received on {{srvModel.cryptoCode}} Blockchain.
|
||||
</span>
|
||||
</div>
|
||||
<center>
|
||||
<script>function shapeshift_click(a, e) { e.preventDefault(); var link = a.href; var shapeshiftWindow = window.open(link, '1418115287605', 'width=700,height=500,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=0,left=0,top=0'); shapeshiftWindow.focus(); return false; }</script>
|
||||
<a onclick="shapeshift_click(this, event);" v-bind:href="srvModel.shapeshiftUrl">
|
||||
<img src="https://shapeshift.io/images/shifty/xs_light_altcoins.png" class="ss-button">
|
||||
</a>
|
||||
|
||||
@*Changelly doesn't have TO_AMOUNT support so we can't include it
|
||||
<script type="text/javascript">function open_widget(a, e) { e.preventDefault(); var link = a.href; var changellyWindow = window.open(link, 'Changelly', 'width=600,height=470,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=0,left=0,top=0'); changellyWindow.focus(); return false; }</script>
|
||||
<a onclick="open_widget(this, event);" href="https://changelly.com/widget/v1?auth=email&from=DASH&to=BTC&address=&amount=1&merchant_id=&ref_id=">
|
||||
<img src="https://changelly.com/pay_button_pay_with.png" alt="Changelly" />
|
||||
</a>*@
|
||||
</center>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="manual__step-two__instructions">
|
||||
<span>
|
||||
No conversion providers available for BTC Lightning Network payments.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="bp-view" id="link-expired" style="padding-top: 3.6rem;">
|
||||
<div class="manual__step-one refund-address-form" novalidate="">
|
||||
<div class="manual__step-one__header" i18n="">Link Expired</div>
|
||||
@@ -354,46 +439,7 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bp-view payment manual-flow" id="copy">
|
||||
<div class="manual__step-two__instructions">
|
||||
<span i18n="">To complete your payment, please send {{ srvModel.btcDue }} {{ srvModel.cryptoCode }} to the address below.</span>
|
||||
</div>
|
||||
<div class="manual-box flipped" style="margin-bottom: 30px;">
|
||||
<div class="manual-box__amount">
|
||||
<div class="manual-box__amount__label label" i18n="">Amount</div>
|
||||
<!---->
|
||||
<div class="manual-box__amount__value copy-cursor" ngxclipboard="">
|
||||
<span>{{srvModel.btcDue}}</span> {{ srvModel.cryptoCode }}
|
||||
<div class="copied-label">
|
||||
<span i18n="">Copied</span>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="manual-box__address">
|
||||
<div class="flipper flipped-initially">
|
||||
<div class="back"></div>
|
||||
<div class="front">
|
||||
<div class="manual-box__address__arrow"></div>
|
||||
<div class="manual-box__address__label label" i18n="">Address</div>
|
||||
<!---->
|
||||
<div class="manual-box__address__value copy-cursor" ngxclipboard="">
|
||||
<div class="manual-box__address__wrapper">
|
||||
<div class="manual-box__address__wrapper__logo">
|
||||
<img :src="srvModel.cryptoImage" height="16" />
|
||||
</div>
|
||||
<div class="manual-box__address__wrapper__value" style="overflow:hidden;max-width:240px;">{{srvModel.btcAddress}}</div>
|
||||
</div>
|
||||
<div class="copied-label" style="top: 5px;">
|
||||
<span i18n="">Copied</span>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bp-view pad" id="paid">
|
||||
<div class="status-block">
|
||||
<div class="success-block">
|
||||
@@ -551,7 +597,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
<div class="bp-view" id="refund-complete">
|
||||
<div class="status-block">
|
||||
<div class="success-block" style="opacity: 1;">
|
||||
@@ -611,8 +656,6 @@
|
||||
</bp-done-text>
|
||||
</button>
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="footer-button enter-different-address-button">
|
||||
<bp-done-text>
|
||||
<!---->
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
</select>
|
||||
<span asp-validation-for="SpeedPolicy" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="AllowCoinConversion"></label>
|
||||
<input asp-for="AllowCoinConversion" type="checkbox" class="form-check" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h5>Derivation Scheme</h5>
|
||||
<span>The DerivationScheme represents the destination of the funds received by your invoice on chain.</span>
|
||||
@@ -85,7 +89,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach(var scheme in Model.DerivationSchemes)
|
||||
@foreach (var scheme in Model.DerivationSchemes)
|
||||
{
|
||||
<tr>
|
||||
<td>@scheme.Crypto</td>
|
||||
@@ -114,7 +118,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach(var scheme in Model.LightningNodes)
|
||||
@foreach (var scheme in Model.LightningNodes)
|
||||
{
|
||||
<tr>
|
||||
<td>@scheme.CryptoCode</td>
|
||||
|
||||
@@ -8562,10 +8562,23 @@ strong {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.payment-tabs__slider.slide-right {
|
||||
.payment-tabs__slider.slide-copy {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.payment-tabs__slider.three-tabs {
|
||||
width: 33%;
|
||||
right: 67%;
|
||||
}
|
||||
|
||||
.payment-tabs__slider.three-tabs.slide-copy {
|
||||
right: 33%;
|
||||
}
|
||||
|
||||
.payment-tabs__slider.three-tabs.slide-altcoins {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.manual__step-one__header {
|
||||
padding-top: 20px;
|
||||
text-align: center;
|
||||
|
||||
@@ -20,11 +20,7 @@ function onDataCallback(jsonData) {
|
||||
|
||||
$(".modal-dialog").addClass("paid");
|
||||
|
||||
if ($("#scan").hasClass("active")) {
|
||||
$("#scan").removeClass("active");
|
||||
} else if ($("#copy").hasClass("active")) {
|
||||
$("#copy").removeClass("active");
|
||||
}
|
||||
resetTabsSlider();
|
||||
$("#paid").addClass("active");
|
||||
}
|
||||
|
||||
@@ -36,11 +32,7 @@ function onDataCallback(jsonData) {
|
||||
$(".modal-dialog").addClass("expired");
|
||||
$("#expired").addClass("active");
|
||||
|
||||
if ($("#scan").hasClass("active")) {
|
||||
$("#scan").removeClass("active");
|
||||
} else if ($("#copy").hasClass("active")) {
|
||||
$("#copy").removeClass("active");
|
||||
}
|
||||
resetTabsSlider();
|
||||
}
|
||||
|
||||
if (checkoutCtrl.srvModel.status !== newStatus) {
|
||||
@@ -53,6 +45,7 @@ function onDataCallback(jsonData) {
|
||||
$(".payment__spinner").hide();
|
||||
}
|
||||
|
||||
jsonData.shapeshiftUrl = "https://shapeshift.io/shifty.html?destination=" + jsonData.btcAddress + "&output=" + jsonData.paymentMethodId + "&amount=" + jsonData.btcDue;
|
||||
// updating ui
|
||||
checkoutCtrl.srvModel = jsonData;
|
||||
}
|
||||
@@ -143,21 +136,24 @@ $(document).ready(function () {
|
||||
contentType: "application/json; charset=utf-8"
|
||||
}).done(function () {
|
||||
hideEmailForm();
|
||||
})
|
||||
.fail(function (jqXHR, textStatus, errorThrown) {
|
||||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||||
|
||||
})
|
||||
})
|
||||
.always(function () {
|
||||
$("#emailAddressForm .input-wrapper bp-loading-button .action-button").removeClass("loading");
|
||||
});
|
||||
} else {
|
||||
|
||||
$("#emailAddressForm").addClass("ng-touched ng-dirty ng-submitted ng-invalid");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Validate Email address
|
||||
function validateEmail(email) {
|
||||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return re.test(email);
|
||||
}
|
||||
|
||||
/* =============== Even listeners =============== */
|
||||
|
||||
// Email
|
||||
@@ -171,47 +167,51 @@ $(document).ready(function () {
|
||||
// Scan/Copy Transitions
|
||||
// Scan Tab
|
||||
$("#scan-tab").click(function () {
|
||||
if (!$(this).is(".active")) {
|
||||
$(this).addClass("active");
|
||||
}
|
||||
|
||||
if ($("#copy-tab").is(".active")) {
|
||||
$("#copy-tab").removeClass("active");
|
||||
}
|
||||
|
||||
$(".payment-tabs__slider").removeClass("slide-right");
|
||||
|
||||
if (!$("#scan").is(".active")) {
|
||||
$("#copy").hide();
|
||||
$("#copy").removeClass("active");
|
||||
|
||||
$("#scan").show();
|
||||
$("#scan").addClass("active");
|
||||
}
|
||||
resetTabsSlider();
|
||||
activateTab("#scan");
|
||||
});
|
||||
|
||||
// Main Copy tab
|
||||
// Copy tab
|
||||
$("#copy-tab").click(function () {
|
||||
if (!$(this).is(".active")) {
|
||||
$(this).addClass("active");
|
||||
}
|
||||
resetTabsSlider();
|
||||
activateTab("#copy");
|
||||
|
||||
if ($("#scan-tab").is(".active")) {
|
||||
$("#scan-tab").removeClass("active");
|
||||
}
|
||||
if (!$(".payment-tabs__slider").is("slide-right")) {
|
||||
$(".payment-tabs__slider").addClass("slide-right");
|
||||
}
|
||||
|
||||
if (!$("#copy").is(".active")) {
|
||||
$("#copy").show();
|
||||
$("#copy").addClass("active");
|
||||
|
||||
$("#scan").hide();
|
||||
$("#scan").removeClass("active");
|
||||
}
|
||||
$("#tabsSlider").addClass("slide-copy");
|
||||
});
|
||||
|
||||
// Altcoins tab
|
||||
$("#altcoins-tab").click(function () {
|
||||
resetTabsSlider();
|
||||
activateTab("#altcoins");
|
||||
|
||||
$("#tabsSlider").addClass("slide-altcoins");
|
||||
});
|
||||
|
||||
function resetTabsSlider() {
|
||||
$("#tabsSlider").removeClass("slide-copy");
|
||||
$("#tabsSlider").removeClass("slide-altcoins");
|
||||
|
||||
$("#scan-tab").removeClass("active");
|
||||
$("#copy-tab").removeClass("active");
|
||||
$("#altcoins-tab").removeClass("active");
|
||||
|
||||
$("#copy").hide();
|
||||
$("#copy").removeClass("active");
|
||||
|
||||
$("#scan").hide();
|
||||
$("#scan").removeClass("active");
|
||||
|
||||
$("#altcoins").hide();
|
||||
$("#altcoins").removeClass("active");
|
||||
}
|
||||
|
||||
function activateTab(senderName) {
|
||||
$(senderName + "-tab").addClass("active");
|
||||
|
||||
$(senderName).show();
|
||||
$(senderName).addClass("active");
|
||||
}
|
||||
|
||||
// Payment received
|
||||
// Should connect using webhook ?
|
||||
// If notification received
|
||||
@@ -244,12 +244,6 @@ $(document).ready(function () {
|
||||
// function to load contents in different language should go there
|
||||
});
|
||||
|
||||
// Validate Email address
|
||||
function validateEmail(email) {
|
||||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return re.test(email);
|
||||
}
|
||||
|
||||
// Expand Line-Items
|
||||
$(".buyerTotalLine").click(function () {
|
||||
$("line-items").toggleClass("expanded");
|
||||
|
||||
Reference in New Issue
Block a user