mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
Checkout fixes (#4375)
* Round buttons on results view * Checkout v2: Fix for BIP21 case with LN as default payment method Fixes #4352. * Update changelog * Add test for fix
This commit is contained in:
parent
e55a16d917
commit
9ee9653c7d
@ -151,6 +151,15 @@ namespace BTCPayServer.Tests
|
||||
Assert.StartsWith("bitcoin:", payUrl);
|
||||
Assert.Contains("&LIGHTNING=", payUrl);
|
||||
|
||||
// BIP21 with LN as default payment method
|
||||
s.GoToHome();
|
||||
invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
||||
s.GoToInvoiceCheckout(invoiceId);
|
||||
Assert.Empty(s.Driver.FindElements(By.CssSelector(".payment-method")));
|
||||
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
||||
Assert.StartsWith("bitcoin:", payUrl);
|
||||
Assert.Contains("&LIGHTNING=", payUrl);
|
||||
|
||||
// BIP21 with topup invoice (which is only available with Bitcoin onchain)
|
||||
s.GoToHome();
|
||||
invoiceId = s.CreateInvoice(amount: null);
|
||||
|
@ -643,9 +643,23 @@ namespace BTCPayServer.Controllers
|
||||
return null;
|
||||
|
||||
bool isDefaultPaymentId = false;
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var btcId = PaymentMethodId.Parse("BTC");
|
||||
var lnId = PaymentMethodId.Parse("BTC_LightningLike");
|
||||
if (paymentMethodId is null)
|
||||
{
|
||||
var enabledPaymentIds = store.GetEnabledPaymentIds(_NetworkProvider);
|
||||
var enabledPaymentIds = store.GetEnabledPaymentIds(_NetworkProvider)
|
||||
// Exclude LNURL for Checkout v2
|
||||
.Where(pmId => storeBlob.CheckoutType == CheckoutType.V1 || pmId.PaymentType is not LNURLPayPaymentType)
|
||||
.ToArray();
|
||||
|
||||
// Exclude Lightning if OnChainWithLnInvoiceFallback is active and we have both payment methods
|
||||
if (storeBlob.CheckoutType == CheckoutType.V2 && storeBlob.OnChainWithLnInvoiceFallback &&
|
||||
enabledPaymentIds.Contains(btcId) && enabledPaymentIds.Contains(lnId))
|
||||
{
|
||||
enabledPaymentIds = enabledPaymentIds.Where(pmId => pmId != lnId).ToArray();
|
||||
}
|
||||
|
||||
PaymentMethodId? invoicePaymentId = invoice.GetDefaultPaymentMethod();
|
||||
PaymentMethodId? storePaymentId = store.GetDefaultPaymentId();
|
||||
if (invoicePaymentId is not null)
|
||||
@ -676,6 +690,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
if (paymentMethodId is null)
|
||||
return null;
|
||||
|
||||
BTCPayNetworkBase network = _NetworkProvider.GetNetwork<BTCPayNetworkBase>(paymentMethodId.CryptoCode);
|
||||
if (network is null || !invoice.Support(paymentMethodId))
|
||||
{
|
||||
@ -702,12 +717,10 @@ namespace BTCPayServer.Controllers
|
||||
return await GetInvoiceModel(invoiceId, paymentMethodId, lang);
|
||||
}
|
||||
}
|
||||
|
||||
var dto = invoice.EntityToDTO();
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var accounting = paymentMethod.Calculate();
|
||||
|
||||
var paymentMethodHandler = _paymentMethodHandlerDictionary[paymentMethodId];
|
||||
|
||||
var divisibility = _CurrencyNameTable.GetNumberFormatInfo(paymentMethod.GetId().CryptoCode, false)?.CurrencyDecimalDigits;
|
||||
|
||||
switch (lang?.ToLowerInvariant())
|
||||
@ -810,16 +823,18 @@ namespace BTCPayServer.Controllers
|
||||
.OrderByDescending(a => a.CryptoCode == _NetworkProvider.DefaultNetwork.CryptoCode).ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0)
|
||||
.ToList()
|
||||
};
|
||||
|
||||
// Exclude Lightning if OnChainWithLnInvoiceFallback is active and we have both payment methods
|
||||
if (storeBlob.CheckoutType == CheckoutType.V2 && storeBlob.OnChainWithLnInvoiceFallback)
|
||||
{
|
||||
var onchainPM = model.AvailableCryptos.Find(c => c.PaymentMethodId == "BTC");
|
||||
var lightningPM = model.AvailableCryptos.Find(c => c.PaymentMethodId == "BTC_LightningLike");
|
||||
var onchainPM = model.AvailableCryptos.Find(c => c.PaymentMethodId == btcId.ToString());
|
||||
var lightningPM = model.AvailableCryptos.Find(c => c.PaymentMethodId == lnId.ToString());
|
||||
if (onchainPM != null && lightningPM != null)
|
||||
{
|
||||
model.AvailableCryptos.Remove(lightningPM);
|
||||
}
|
||||
}
|
||||
|
||||
paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob, paymentMethod);
|
||||
model.UISettings = paymentMethodHandler.GetCheckoutUISettings();
|
||||
model.PaymentMethodId = paymentMethodId.ToString();
|
||||
|
@ -134,9 +134,9 @@
|
||||
<payment-details :srv-model="srvModel" :is-active="isActive" class="mb-5"></payment-details>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<a v-if="srvModel.receiptLink" class="btn btn-primary" :href="srvModel.receiptLink" :target="isModal ? '_top' : null" v-t="'view_receipt'" id="ReceiptLink"></a>
|
||||
<a v-if="storeLink" class="btn btn-secondary" :href="storeLink" :target="isModal ? '_top' : null" v-t="{ path: 'return_to_store', args: { storeName: srvModel.storeName }}" id="StoreLink"></a>
|
||||
<button v-else-if="isModal" class="btn btn-secondary" v-on:click="close" v-t="'Close'"></button>
|
||||
<a v-if="srvModel.receiptLink" class="btn btn-primary rounded-pill w-100" :href="srvModel.receiptLink" :target="isModal ? '_top' : null" v-t="'view_receipt'" id="ReceiptLink"></a>
|
||||
<a v-if="storeLink" class="btn btn-secondary rounded-pill w-100" :href="storeLink" :target="isModal ? '_top' : null" v-t="{ path: 'return_to_store', args: { storeName: srvModel.storeName }}" id="StoreLink"></a>
|
||||
<button v-else-if="isModal" class="btn btn-secondary rounded-pill w-100" v-on:click="close" v-t="'Close'"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="expired" v-if="isUnpayable">
|
||||
@ -165,8 +165,8 @@
|
||||
<p class="text-center mt-3" v-html="replaceNewlines($t('invoice_expired_body', { storeName: srvModel.storeName, minutes: @Model.MaxTimeMinutes }))"></p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<a v-if="storeLink" class="btn btn-primary" :href="storeLink" :target="isModal ? '_top' : null" v-t="{ path: 'return_to_store', args: { storeName: srvModel.storeName }}" id="StoreLink"></a>
|
||||
<button v-else-if="isModal" class="btn btn-primary" v-on:click="close" v-t="'Close'"></button>
|
||||
<a v-if="storeLink" class="btn btn-primary rounded-pill w-100" :href="storeLink" :target="isModal ? '_top' : null" v-t="{ path: 'return_to_store', args: { storeName: srvModel.storeName }}" id="StoreLink"></a>
|
||||
<button v-else-if="isModal" class="btn btn-primary rounded-pill w-100" v-on:click="close" v-t="'Close'"></button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -13,6 +13,7 @@
|
||||
* Some logos or images wouldn't show up properly if rootPath is used (#4367) @NicolasDorier
|
||||
* Fix malformed manifest on PoS app (#4373, #4363) @dennisreimann
|
||||
* Call to LND would start failing on some conditions @NicolasDorier
|
||||
* Checkout v2: Fix for BIP21 case with default payment method other than onchain BTC (#4375) @dennisreimann
|
||||
|
||||
### Improvement
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user