Skip to content

Commit

Permalink
Make Checkout V2 the default (#4850)
Browse files Browse the repository at this point in the history
* Make Checkout V2 the default

* Fix align
  • Loading branch information
NicolasDorier committed Apr 4, 2023
1 parent 1b672a1 commit 9b8d08a
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 56 deletions.
8 changes: 7 additions & 1 deletion BTCPayServer.Tests/CheckoutUITests.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using BTCPayServer.Payments;
using BTCPayServer.Tests.Logging;
using BTCPayServer.Views.Stores;
Expand Down Expand Up @@ -27,6 +28,7 @@ public async Task CanHandleRefundEmailForm()
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();
s.GoToStore(StoreNavPages.CheckoutAppearance);
s.Driver.FindElement(By.Id("RequiresRefundEmail")).Click();
Expand Down Expand Up @@ -72,6 +74,7 @@ public async Task CanHandleRefundEmailForm2()
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();

// Now create an invoice that requires a refund email
Expand Down Expand Up @@ -124,6 +127,7 @@ public async Task CanUseLanguageDropdown()
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();

var invoiceId = s.CreateInvoice();
Expand Down Expand Up @@ -154,12 +158,12 @@ public async Task CanSetDefaultPaymentMethod()
s.GoToRegister();
s.RegisterNewUser(true);
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddLightningNode();
s.AddDerivationScheme();

var invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
s.GoToInvoiceCheckout(invoiceId);

Assert.Equal("Bitcoin (Lightning) (BTC)", s.Driver.FindElement(By.ClassName("payment__currencies")).Text);
s.Driver.Quit();
}
Expand All @@ -174,6 +178,7 @@ public async Task CanUseLightningSatsFeature()
s.GoToRegister();
s.RegisterNewUser(true);
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddLightningNode();
s.GoToLightningSettings();
s.Driver.SetCheckbox(By.Id("LightningAmountInSatoshi"), true);
Expand All @@ -193,6 +198,7 @@ public async Task CanUseJSModal()
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.GoToStore();
s.AddDerivationScheme();
var invoiceId = s.CreateInvoice(0.001m, "BTC", "a@x.com");
Expand Down
22 changes: 7 additions & 15 deletions BTCPayServer.Tests/Checkoutv2Tests.cs
@@ -1,11 +1,13 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using BTCPayServer.Payments;
using BTCPayServer.Tests.Logging;
using BTCPayServer.Views.Stores;
using NBitcoin;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.Extensions;
using OpenQA.Selenium.Support.UI;
using Xunit;
using Xunit.Abstractions;
Expand All @@ -32,7 +34,6 @@ public async Task CanConfigureCheckout()
s.GoToRegister();
s.RegisterNewUser(true);
s.CreateNewStore();
s.EnableCheckoutV2();
s.AddLightningNode();
// Use non-legacy derivation scheme
s.AddDerivationScheme("BTC", "tpubDD79XF4pzhmPSJ9AyUay9YbXAeD1c6nkUqC32pnKARJH6Ja5hGUfGc76V82ahXpsKqN6UcSGXMkzR34aZq4W23C6DAdZFaVrzWqzj24F8BC");
Expand Down Expand Up @@ -148,7 +149,7 @@ public async Task CanConfigureCheckout()
Assert.True(expiredSection.Displayed);
Assert.Contains("Invoice Expired", expiredSection.Text);
});
Assert.True(s.Driver.ElementDoesNotExist(By.Id("ReceiptLink")));
Assert.True(s.Driver.ElementDoesNotExist(By.Id("receipt-btn")));
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));

// Test payment
Expand Down Expand Up @@ -179,23 +180,16 @@ public async Task CanConfigureCheckout()
await s.Server.ExplorerNode.GenerateAsync(1);

// Fake Pay
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountFraction);
s.Driver.FindElement(By.Id("FakePay")).Click();
TestUtils.Eventually(() =>
{
Assert.Contains("Created transaction",
s.Driver.WaitForElement(By.Id("CheatSuccessMessage")).Text);
s.Server.ExplorerNode.Generate(2);
paymentInfo = s.Driver.WaitForElement(By.Id("PaymentInfo"));
Assert.Contains("The invoice hasn't been paid in full", paymentInfo.Text);
Assert.Contains("Please send", paymentInfo.Text);
});

s.Driver.Navigate().Refresh();
// Pay full amount
var amountDue = s.Driver.FindElement(By.Id("AmountDue")).GetAttribute("data-amount-due");
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountDue);
s.Driver.FindElement(By.Id("FakePay")).Click();

s.PayInvoice();
// Processing
TestUtils.Eventually(() =>
{
Expand All @@ -205,9 +199,8 @@ public async Task CanConfigureCheckout()
Assert.Contains("Your payment has been received and is now processing", processingSection.Text);
Assert.True(s.Driver.ElementDoesNotExist(By.Id("confetti")));
});

// Mine
s.Driver.FindElement(By.Id("Mine")).Click();
s.MineBlockOnInvoiceCheckout();
TestUtils.Eventually(() =>
{
Assert.Contains("Mined 1 block",
Expand All @@ -222,7 +215,7 @@ public async Task CanConfigureCheckout()
Assert.Contains("Invoice Paid", settledSection.Text);
});
s.Driver.FindElement(By.Id("confetti"));
s.Driver.FindElement(By.Id("ReceiptLink"));
s.Driver.FindElement(By.Id("receipt-btn"));
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));

// BIP21
Expand Down Expand Up @@ -412,7 +405,6 @@ public async Task CanUseCheckoutAsModal()
s.GoToRegister();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckoutV2();
s.GoToStore();
s.AddDerivationScheme();
var invoiceId = s.CreateInvoice(0.001m, "BTC", "a@x.com");
Expand Down
2 changes: 2 additions & 0 deletions BTCPayServer.Tests/PayJoinTests.cs
Expand Up @@ -249,6 +249,7 @@ public async Task CanUsePayjoinForTopUp()
await s.StartAsync();
s.RegisterNewUser(true);
var receiver = s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
var receiverSeed = s.GenerateWallet("BTC", "", true, true, ScriptPubKeyType.Segwit);
var receiverWalletId = new WalletId(receiver.storeId, "BTC");

Expand Down Expand Up @@ -303,6 +304,7 @@ public async Task CanUsePayjoinViaUI()
{
var cryptoCode = "BTC";
var receiver = s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
var receiverSeed = s.GenerateWallet(cryptoCode, "", true, true, format);
var receiverWalletId = new WalletId(receiver.storeId, cryptoCode);

Expand Down
20 changes: 14 additions & 6 deletions BTCPayServer.Tests/SeleniumTester.cs
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Client.Models;
using BTCPayServer.Lightning;
using BTCPayServer.Lightning.CLightning;
using BTCPayServer.Views.Manage;
Expand Down Expand Up @@ -94,6 +95,7 @@ public void PayInvoice(bool mine = false, decimal? amount= null)
Driver.FindElement(By.Id("test-payment-amount")).Clear();
Driver.FindElement(By.Id("test-payment-amount")).SendKeys(amount.ToString());
}
Driver.WaitUntilAvailable(By.Id("FakePayment"));
Driver.FindElement(By.Id("FakePayment")).Click();
if (mine)
{
Expand Down Expand Up @@ -193,16 +195,22 @@ public TestAccount AsTestAccount()
StoreId = storeId;
return (name, storeId);
}

public void EnableCheckoutV2(bool bip21 = false)
public void EnableCheckout(CheckoutType checkoutType, bool bip21 = false)
{
GoToStore(StoreNavPages.CheckoutAppearance);
Driver.SetCheckbox(By.Id("UseNewCheckout"), true);
Driver.WaitForElement(By.Id("OnChainWithLnInvoiceFallback"));
Driver.SetCheckbox(By.Id("OnChainWithLnInvoiceFallback"), bip21);
if (checkoutType == CheckoutType.V2)
{
Driver.SetCheckbox(By.Id("UseClassicCheckout"), false);
Driver.WaitForElement(By.Id("OnChainWithLnInvoiceFallback"));
Driver.SetCheckbox(By.Id("OnChainWithLnInvoiceFallback"), bip21);
}
else
{
Driver.SetCheckbox(By.Id("UseClassicCheckout"), true);
}
Driver.FindElement(By.Id("Save")).SendKeys(Keys.Enter);
Assert.Contains("Store successfully updated", FindAlertMessage().Text);
Assert.True(Driver.FindElement(By.Id("UseNewCheckout")).Selected);
Assert.True(Driver.FindElement(By.Id("UseClassicCheckout")).Selected);
}

public Mnemonic GenerateWallet(string cryptoCode = "BTC", string seed = "", bool? importkeys = null, bool isHotWallet = false, ScriptPubKeyType format = ScriptPubKeyType.Segwit)
Expand Down
7 changes: 5 additions & 2 deletions BTCPayServer.Tests/SeleniumTests.cs
Expand Up @@ -592,7 +592,7 @@ public async Task CanUseInvoiceReceipts()
s.GoToInvoices(s.StoreId);
s.GoToInvoiceCheckout(i);
var checkouturi = s.Driver.Url;
s.PayInvoice();
s.PayInvoice(mine: true);
TestUtils.Eventually(() =>
{
s.Driver.Navigate().Refresh();
Expand All @@ -602,7 +602,7 @@ public async Task CanUseInvoiceReceipts()
{
s.Driver.Navigate().Refresh();
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
Assert.Contains("invoice-processing", s.Driver.PageSource);
Assert.Contains("\"PaymentDetails\"", s.Driver.PageSource);
});
s.GoToUrl(checkouturi);

Expand Down Expand Up @@ -1067,6 +1067,7 @@ public async Task CanCreatePayRequest()
await s.StartAsync();
s.RegisterNewUser();
s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
s.AddDerivationScheme();

s.Driver.FindElement(By.Id("StoreNav-PaymentRequests")).Click();
Expand Down Expand Up @@ -2038,6 +2039,7 @@ public async Task CanUseLNURL()
new[] { s.Server.MerchantLnd.Client });
s.RegisterNewUser(true);
(_, string storeId) = s.CreateNewStore();
s.EnableCheckout(CheckoutType.V1);
var network = s.Server.NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode).NBitcoinNetwork;
s.AddLightningNode(LightningConnectionType.CLightning, false);
s.GoToLightningSettings();
Expand Down Expand Up @@ -2168,6 +2170,7 @@ public async Task CanUseLNURL()

s.GoToHome();
s.CreateNewStore(false);
s.EnableCheckout(CheckoutType.V1);
s.AddLightningNode(LightningConnectionType.LndREST, false);
s.GoToLightningSettings();
s.Driver.SetCheckbox(By.Id("LNURLEnabled"), true);
Expand Down
2 changes: 1 addition & 1 deletion BTCPayServer.Tests/TestUtils.cs
Expand Up @@ -17,7 +17,7 @@ public static class TestUtils
#if DEBUG && !SHORT_TIMEOUT
public const int TestTimeout = 600_000;
#else
public const int TestTimeout = 60_000;
public const int TestTimeout = 90_000;
#endif
public static DirectoryInfo TryGetSolutionDirectoryInfo(string currentPath = null)
{
Expand Down
4 changes: 2 additions & 2 deletions BTCPayServer/Controllers/UIInvoiceController.UI.cs
Expand Up @@ -1157,7 +1157,7 @@ public async Task<IActionResult> CreateInvoice(InvoicesModel? model = null)
{
StoreId = model.StoreId,
Currency = storeBlob?.DefaultCurrency,
UseNewCheckout = storeBlob?.CheckoutType is CheckoutType.V2,
CheckoutType = storeBlob?.CheckoutType ?? CheckoutType.V2,
AvailablePaymentMethods = GetPaymentMethodsSelectList()
};

Expand All @@ -1172,7 +1172,7 @@ public async Task<IActionResult> CreateInvoice(CreateInvoiceModel model, Cancell
{
var store = HttpContext.GetStoreData();
var storeBlob = store.GetStoreBlob();
model.UseNewCheckout = storeBlob.CheckoutType == CheckoutType.V2;
model.CheckoutType = storeBlob.CheckoutType;
model.AvailablePaymentMethods = GetPaymentMethodsSelectList();

if (!ModelState.IsValid)
Expand Down
4 changes: 2 additions & 2 deletions BTCPayServer/Controllers/UIStoresController.cs
Expand Up @@ -385,7 +385,7 @@ public IActionResult CheckoutAppearance()
};
}).ToList();

vm.UseNewCheckout = storeBlob.CheckoutType == Client.Models.CheckoutType.V2;
vm.UseClassicCheckout = storeBlob.CheckoutType == Client.Models.CheckoutType.V1;
vm.CelebratePayment = storeBlob.CelebratePayment;
vm.OnChainWithLnInvoiceFallback = storeBlob.OnChainWithLnInvoiceFallback;
vm.ShowPayInWalletButton = storeBlob.ShowPayInWalletButton;
Expand Down Expand Up @@ -509,7 +509,7 @@ public async Task<IActionResult> CheckoutAppearance(CheckoutAppearanceViewModel

blob.ShowPayInWalletButton = model.ShowPayInWalletButton;
blob.ShowStoreHeader = model.ShowStoreHeader;
blob.CheckoutType = model.UseNewCheckout ? Client.Models.CheckoutType.V2 : Client.Models.CheckoutType.V1;
blob.CheckoutType = model.UseClassicCheckout ? Client.Models.CheckoutType.V1 : Client.Models.CheckoutType.V2;
blob.CelebratePayment = model.CelebratePayment;
blob.OnChainWithLnInvoiceFallback = model.OnChainWithLnInvoiceFallback;
blob.LightningAmountInSatoshi = model.LightningAmountInSatoshi;
Expand Down
3 changes: 3 additions & 0 deletions BTCPayServer/Data/StoreBlob.cs
Expand Up @@ -33,12 +33,15 @@ public StoreBlob()
RecommendedFeeBlockTarget = 1;
PaymentMethodCriteria = new List<PaymentMethodCriteria>();
ReceiptOptions = InvoiceDataBase.ReceiptOptions.CreateDefault();
CheckoutType = CheckoutType.V2;
}

[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public NetworkFeeMode NetworkFeeMode { get; set; }

[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
[DefaultValue(CheckoutType.V1)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public CheckoutType CheckoutType { get; set; }
public bool RequiresRefundEmail { get; set; }
public bool LightningAmountInSatoshi { get; set; }
Expand Down
3 changes: 2 additions & 1 deletion BTCPayServer/Models/InvoicingModels/CreateInvoiceModel.cs
Expand Up @@ -2,6 +2,7 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using BTCPayServer.Client.Models;
using BTCPayServer.Services.Apps;
using BTCPayServer.Validation;
using Microsoft.AspNetCore.Mvc.Rendering;
Expand Down Expand Up @@ -89,6 +90,6 @@ public RequiresRefundEmail RequiresRefundEmail
get; set;
}

public bool UseNewCheckout { get; set; }
public CheckoutType CheckoutType { get; set; }
}
}
Expand Up @@ -38,8 +38,8 @@ public void SetLanguages(LanguageService langService, string defaultLang)
[Display(Name = "Default payment method on checkout")]
public string DefaultPaymentMethod { get; set; }

[Display(Name = "Use the new checkout")]
public bool UseNewCheckout { get; set; }
[Display(Name = "Use the classic checkout")]
public bool UseClassicCheckout { get; set; }

[Display(Name = "Celebrate payment with confetti")]
public bool CelebratePayment { get; set; }
Expand Down
8 changes: 4 additions & 4 deletions BTCPayServer/Views/UIInvoice/Checkout-Cheating.cshtml
Expand Up @@ -10,13 +10,13 @@
<form id="test-payment" :action="`/i/${invoiceId}/test-payment`" method="post" v-on:submit.prevent="handleFormSubmit($event, 'paying')" v-if="displayPayment">
<input name="CryptoCode" type="hidden" :value="cryptoCode">
<input name="PaymentMethodId" type="hidden" :value="paymentMethodId">
<label for="FakePayAmount" class="control-label form-label">Fake a {{cryptoCode}} payment for testing</label>
<label for="test-payment-amount" class="control-label form-label">Fake a {{cryptoCode}} payment for testing</label>
<div class="d-flex gap-2 mb-2">
<div class="input-group">
<input id="FakePayAmount" name="Amount" type="number" :step="isSats ? '1' : '0.00000001'" min="0" class="form-control" placeholder="Amount" v-model="amountRemaining" :disabled="paying || paymentMethodId === 'BTC_LightningLike'"/>
<input id="test-payment-amount" name="Amount" type="number" :step="isSats ? '1' : '0.00000001'" min="0" class="form-control" placeholder="Amount" v-model="amountRemaining" :disabled="paying || paymentMethodId === 'BTC_LightningLike'" />
<div id="test-payment-crypto-code" class="input-group-addon input-group-text" v-text="cryptoCode"></div>
</div>
<button class="btn btn-secondary flex-shrink-0 px-3 w-100px" type="submit" :disabled="paying" id="FakePay">Pay</button>
<button class="btn btn-secondary flex-shrink-0 px-3 w-100px" type="submit" :disabled="paying" id="FakePayment">Pay</button>
</div>
</form>
<form id="mine-block" :action="`/i/${invoiceId}/mine-blocks`" method="post" v-on:submit.prevent="handleFormSubmit($event, 'mining')" v-if="displayMine">
Expand All @@ -26,7 +26,7 @@
<input id="BlockCount" name="BlockCount" type="number" step="1" min="1" class="form-control" value="1"/>
<div class="input-group-addon input-group-text">blocks</div>
</div>
<button class="btn btn-secondary flex-shrink-0 px-3 w-100px" type="submit" :disabled="mining" id="Mine">Mine</button>
<button class="btn btn-secondary flex-shrink-0 px-3 w-100px" type="submit" :disabled="mining" id="mine-block">Mine</button>
</div>
</form>
<form id="expire-invoice" :action="`/i/${invoiceId}/expire`" method="post" v-on:submit.prevent="handleFormSubmit($event, 'expiring')" v-if="displayExpire">
Expand Down
2 changes: 1 addition & 1 deletion BTCPayServer/Views/UIInvoice/CheckoutV2.cshtml
Expand Up @@ -172,7 +172,7 @@
</div>
</div>
<div class="buttons">
<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="srvModel.receiptLink" class="btn btn-primary rounded-pill w-100" :href="srvModel.receiptLink" :target="isModal ? '_top' : null" v-t="'view_receipt'" id="receipt-btn"></a>
<a v-if="storeLink" class="btn btn-secondary rounded-pill w-100" :href="storeLink" :target="isModal ? '_top' : null" v-html="$t('return_to_store', { 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>
Expand Down

0 comments on commit 9b8d08a

Please sign in to comment.