crypto payment message
All checks were successful
Deploy / build-deploy (push) Successful in 3m18s

This commit is contained in:
Jorijn van der Graaf 2026-08-20 03:08:30 +02:00
commit 7098ac75cb
2 changed files with 27 additions and 19 deletions

View file

@ -1399,8 +1399,15 @@ export RenderedPage RenderOrderStatus(const OrderView& o, std::string_view indic
// No badge when paid: the confirmation notice below carries the state,
// and two green "paid" pills stacked read as a rendering bug.
//
// An awaiting order whose payment has been SEEN in flight says so in the
// badge itself, not only in the note below: the badge is where a buyer
// who just paid looks first, and "awaiting payment" there reads as "your
// money did not arrive" no matter what a paragraph underneath explains.
const bool inFlight = awaiting && o.cryptoPay && o.cryptoPay->seen;
SafeHtml statusLine =
awaiting ? Raw(R"(<span class="badge badge--experiment">awaiting payment</span>)")
inFlight ? Raw(R"(<span class="badge badge--experiment">payment detected, awaiting network confirmation</span>)")
: awaiting ? Raw(R"(<span class="badge badge--experiment">awaiting payment</span>)")
: o.status == "paid" ? SafeHtml{}
: o.status == "shipped" ? Raw(R"(<span class="badge badge--active">shipped</span>)")
: Raw(R"(<span class="badge">cancelled</span>)");
@ -1458,16 +1465,9 @@ export RenderedPage RenderOrderStatus(const OrderView& o, std::string_view indic
R"(<a href="mailto:info@catcrafts.net">info@catcrafts.net</a> )"
R"(and it will be settled by hand.</p>)");
// The in-flight acknowledgement: the rail has SEEN the full amount on
// the network, finality is the only thing missing. Rendered first,
// because a buyer who just paid scans for exactly this sentence.
const SafeHtml seenLine = pay.seen && pay.minutesLeft > 0
? Raw(R"(<p class="order__note"><strong>Your payment is on its way.</strong> )"
R"(It is visible on the network and is being finalized: this )"
R"(usually takes 10 to 25 minutes, and this page will confirm )"
R"(it automatically.</p>)")
: SafeHtml{};
// The in-flight state renders as the status badge up top
// ("confirming payment"), where a buyer who just paid looks first;
// this block keeps only the standing instructions.
SafeHtml indicativeLine = indicative.empty() ? SafeHtml{} : Format(
R"(<p class="order__indicative">{}, indicative only. The charge is )"
R"(the euro amount above.</p>)",
@ -1476,7 +1476,6 @@ export RenderedPage RenderOrderStatus(const OrderView& o, std::string_view indic
payBlock = Format(
R"(<section class="section">)"
R"(<h2 class="section__title">Pay with EURC</h2>)"
R"({})"
R"(<p>Send <strong>{} EURC</strong> to this address. One )"
R"(network, one payment:</p>)"
R"(<p><code class="order__address">{}</code></p>)"
@ -1490,7 +1489,6 @@ export RenderedPage RenderOrderStatus(const OrderView& o, std::string_view indic
R"(order reference is <strong>{}</strong>.</p>)"
R"({})"
R"(</section>)",
seenLine,
Escape(pay.amount),
Escape(pay.address),
Join(items),

View file

@ -567,12 +567,22 @@ void DonationLifecycle(TestServer& srv) {
"the awaiting page states the confirmation timing");
WriteFile(std::filesystem::path(
srv.Orders().string() + ".fake-paid.seen"), "");
const std::string page =
srv.WaitForBody(seenPath, "Your payment is on its way");
Check(page.find("Your payment is on its way") != std::string::npos,
"an in-flight payment is acknowledged on the order page");
Check(page.find("awaiting payment") != std::string::npos,
"an in-flight payment is still awaiting, not paid");
// The badge is where the buyer looks first, so it carries the
// state itself: "awaiting payment" under a wallet that said
// success reads as "your money did not arrive". "Detected" and
// not "received": the shop has seen the transfer, it does not
// yet trust it, and the badge should not outrun the rail. The
// waiting half uses the words every exchange deposit screen has
// taught buyers: "awaiting network confirmation".
const std::string page = srv.WaitForBody(
seenPath, ">payment detected, awaiting network confirmation<");
Check(page.find(">payment detected, awaiting network confirmation<")
!= std::string::npos,
"the badge flips to detected-awaiting-confirmation in flight");
Check(page.find(">awaiting payment<") == std::string::npos,
"the awaiting badge is replaced, not doubled");
Check(page.find("Thank you") == std::string::npos,
"an in-flight payment is not yet confirmed as paid");
std::error_code ec;
std::filesystem::remove(std::filesystem::path(
srv.Orders().string() + ".fake-paid.seen"), ec);