mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-13 03:16:46 +01:00
Also detects if the checkout page is shown within an iframe and hides the back to store link in that case.
196 lines
10 KiB
Text
196 lines
10 KiB
Text
@model BTCPayServer.Models.InvoicingModels.InvoiceReceiptViewModel
|
|
@using BTCPayServer.Client
|
|
@using BTCPayServer.Client.Models
|
|
@using BTCPayServer.Components.QRCode
|
|
@using BTCPayServer.Services
|
|
@inject BTCPayServerEnvironment Env
|
|
@inject DisplayFormatter DisplayFormatter
|
|
@{
|
|
Layout = null;
|
|
ViewData["Title"] = $"Receipt from {Model.StoreName}";
|
|
ViewData["StoreBranding"] = Model.StoreBranding;
|
|
var isProcessing = Model.Status == InvoiceStatus.Processing;
|
|
var isFreeInvoice = (Model.Status == InvoiceStatus.New && Model.Amount == 0);
|
|
var isSettled = Model.Status == InvoiceStatus.Settled;
|
|
}
|
|
<!DOCTYPE html>
|
|
<html lang="en" @(Env.IsDeveloping ? " data-devenv" : "")>
|
|
<head>
|
|
<partial name="LayoutHead"/>
|
|
<meta name="robots" content="noindex,nofollow">
|
|
@if (isProcessing)
|
|
{
|
|
<script type="text/javascript">
|
|
setTimeout(() => { window.location.reload(); }, 10000);
|
|
</script>
|
|
}
|
|
else if (isFreeInvoice)
|
|
{
|
|
<script type="text/javascript">
|
|
setTimeout(() => { window.location.reload(); }, 2000);
|
|
</script>
|
|
}
|
|
<style>
|
|
#InvoiceReceipt { --wrap-max-width: 768px; }
|
|
#InvoiceSummary { gap: var(--btcpay-space-l); }
|
|
#PaymentDetails table tbody tr:first-child td { padding-top: 1rem; }
|
|
#PaymentDetails table tbody:not(:last-child) tr:last-child > th,td { padding-bottom: 1rem; }
|
|
#AdditionalData td > table:last-child, #CartData td > table:last-child { margin-bottom: 0 !important; }
|
|
#AdditionalData table > tbody > tr:first-child > td > h4, #CartData table > tbody > tr:first-child > td > h4 { margin-top: 0 !important; }
|
|
</style>
|
|
</head>
|
|
<body class="min-vh-100">
|
|
<div id="InvoiceReceipt" class="public-page-wrap">
|
|
<main class="flex-grow-1">
|
|
<div class="d-flex flex-column justify-content-center gap-4">
|
|
<partial name="_StoreHeader" model="(Model.StoreName, Model.StoreBranding)" />
|
|
<partial name="_StatusMessage" model="@(new ViewDataDictionary(ViewData) { { "Margin", "mb-4" } })"/>
|
|
<div id="InvoiceSummary" class="tile d-flex flex-wrap align-items-center justify-content-center">
|
|
@if (isProcessing)
|
|
{
|
|
<div class="lead text-center p-4 fw-semibold" id="invoice-processing">
|
|
The invoice has detected a payment but is still waiting to be settled.
|
|
</div>
|
|
}
|
|
else if (!isSettled)
|
|
{
|
|
<div class="lead text-center p-4 fw-semibold" id="invoice-unsettled">
|
|
The invoice is not settled.
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
if (Model.ReceiptOptions.ShowQR is true)
|
|
{
|
|
<vc:qr-code data="@Context.Request.GetCurrentUrl()" />
|
|
}
|
|
<div class="d-flex gap-4 mb-0 flex-fill">
|
|
<dl class="d-flex flex-column gap-4 mb-0 flex-fill">
|
|
<div class="d-flex flex-column">
|
|
<dd class="text-muted mb-0 fw-semibold">Amount Paid</dd>
|
|
<dt class="fs-2 mb-0 text-nowrap fw-semibold">@DisplayFormatter.Currency(Model.Amount, Model.Currency, DisplayFormatter.CurrencyFormat.Symbol)</dt>
|
|
</div>
|
|
<div class="d-flex flex-column">
|
|
<dd class="text-muted mb-0 fw-semibold">Date</dd>
|
|
<dt class="fs-5 mb-0 text-nowrap fw-semibold">@Model.Timestamp.ToBrowserDate()</dt>
|
|
</div>
|
|
@if (!string.IsNullOrEmpty(Model.OrderId))
|
|
{
|
|
<div class="d-flex flex-column">
|
|
<dd class="text-muted mb-0 fw-semibold">Order ID</dd>
|
|
<dt class="fs-5 mb-0 text-break fw-semibold">@Model.OrderId</dt>
|
|
</div>
|
|
}
|
|
</dl>
|
|
<a href="?print=true" class="flex-grow-0 align-self-start btn btn-secondary d-print-none fs-4" target="_blank" id="ReceiptLinkPrint">Print</a>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@if (isProcessing)
|
|
{
|
|
<small class="d-block text-muted text-center px-4">This page will refresh periodically until the invoice is settled.</small>
|
|
}
|
|
else if (isSettled)
|
|
{
|
|
if (Model.AdditionalData?.Any() is true)
|
|
{
|
|
<div id="AdditionalData" class="tile">
|
|
<h2 class="h4 mb-3">Additional Data</h2>
|
|
<div class="table-responsive my-0">
|
|
<partial name="PosData" model="(Model.AdditionalData, 1)"/>
|
|
</div>
|
|
</div>
|
|
}
|
|
if (Model.CartData?.Any() is true)
|
|
{
|
|
<div id="CartData" class="tile">
|
|
<h2 class="h4 mb-3">Cart</h2>
|
|
<div class="table-responsive my-0">
|
|
<partial name="PosData" model="(Model.CartData, 1)" />
|
|
</div>
|
|
</div>
|
|
}
|
|
if (Model.Payments?.Any() is true)
|
|
{
|
|
<div id="PaymentDetails" class="tile">
|
|
<h2 class="h4 mb-3">Payment Details</h2>
|
|
<div class="table-responsive my-0 d-print-none">
|
|
<table class="invoice table table-borderless">
|
|
<thead>
|
|
<tr>
|
|
<th class="fw-normal text-secondary date-col w-125px">Date</th>
|
|
<th class="fw-normal text-secondary amount-col">Paid</th>
|
|
<th class="fw-normal text-secondary amount-col w-225px">Payment</th>
|
|
</tr>
|
|
</thead>
|
|
@foreach (var payment in Model.Payments)
|
|
{
|
|
<tbody>
|
|
<tr>
|
|
<td class="date-col">@payment.ReceivedDate.ToBrowserDate()</td>
|
|
<td class="amount-col">@payment.PaidFormatted</td>
|
|
<td class="amount-col">@payment.AmountFormatted</td>
|
|
</tr>
|
|
@if (!string.IsNullOrEmpty(payment.Destination))
|
|
{
|
|
<tr>
|
|
<th class="fw-normal text-nowrap text-secondary">
|
|
Destination
|
|
</th>
|
|
<td class="fw-normal" colspan="2">
|
|
<vc:truncate-center text="@payment.Destination" classes="truncate-center-id" />
|
|
</td>
|
|
</tr>
|
|
}
|
|
@if (!string.IsNullOrEmpty(payment.PaymentProof))
|
|
{
|
|
<tr>
|
|
<th class="fw-normal text-nowrap text-secondary">
|
|
Payment Proof
|
|
</th>
|
|
<td class="fw-normal" colspan="2">
|
|
<vc:truncate-center text="@payment.PaymentProof" link="@payment.Link" classes="truncate-center-id" />
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
}
|
|
</table>
|
|
</div>
|
|
<div class="d-none d-print-block">
|
|
@foreach (var payment in Model.Payments)
|
|
{
|
|
<div class="mb-4">
|
|
<strong>@payment.PaidFormatted</strong> = @payment.Amount @payment.PaymentMethod, Rate: @payment.RateFormatted
|
|
@if (!string.IsNullOrEmpty(payment.PaymentProof))
|
|
{
|
|
<div>Proof: @payment.PaymentProof</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
@if (!string.IsNullOrEmpty(Model.RedirectUrl))
|
|
{
|
|
<a href="@Model.RedirectUrl" class="btn btn-secondary rounded-pill mx-auto mt-3" rel="noreferrer noopener" target="_blank" id="StoreLink">Return to @(string.IsNullOrEmpty(Model.StoreName) ? "store" : Model.StoreName)</a>
|
|
}
|
|
</div>
|
|
</main>
|
|
<footer class="store-footer">
|
|
<p permission="@Policies.CanViewInvoices" class="d-print-none">
|
|
<a asp-action="Invoice" asp-route-invoiceId="@Model.InvoiceId">
|
|
Admin details
|
|
</a>
|
|
</p>
|
|
<a class="store-powered-by" href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">
|
|
<span text-translate="true">Powered by</span> <partial name="_StoreFooterLogo" />
|
|
</a>
|
|
</footer>
|
|
</div>
|
|
<partial name="LayoutFoot"/>
|
|
</body>
|
|
</html>
|
|
|