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:
d11n 2022-11-29 03:19:23 +01:00 committed by GitHub
parent e55a16d917
commit 9ee9653c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 11 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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>

View File

@ -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