Skip to content

feat: Update the UI and add order cancellation #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/TokenPay/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ public async Task<IActionResult> Pay(Guid Id)
{
return View(order);
}

// Redirect to `Cancel` page when the status of the order is closed.
if (order.Status == OrderStatus.Closed)
{
return RedirectToAction("Cancel", new { order.Id });
}

ViewData["QrCode"] = Convert.ToBase64String(CreateQrCode(order.ToAddress));
var ExpireTime = _configuration.GetValue("ExpireTime", 10 * 60);
if (DateTime.Now > order.CreateTime.AddSeconds(ExpireTime) || order.Status == OrderStatus.Expired)
Expand Down Expand Up @@ -535,5 +542,32 @@ private static byte[] CreateQrCode(string qrcode, int size = 300)
qrCode.GenerateImage(stream);
return stream.ToArray();
}

/// <summary>
/// Cancel the payment of an order.
/// </summary>
/// <param name="id">The id of the order.</param>
/// <returns>The result of the cancellation.</returns>
[HttpGet("/Cancel/{id:guid}")]
public async Task<IActionResult> CancelAsync(Guid id)
{
var order = await _repository.Where(order => order.Id == id).FirstAsync();

if (order == null)
{
return NotFound();
}

if (order.Status is not OrderStatus.Closed)
{
order.Status = OrderStatus.Closed;
await _repository.UpdateAsync(order);
}

return View(new OrderCancellationModel(
orderId: order.Id,
orderCode: order.OutOrderId,
returnUrl: order.RedirectUrl ?? string.Empty));
}
}
}
3 changes: 2 additions & 1 deletion src/TokenPay/Domains/TokenOrders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public enum OrderStatus
{
Pending,
Paid,
Expired
Expired,
Closed,
}
}
25 changes: 25 additions & 0 deletions src/TokenPay/Models/OrderCancellationModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace TokenPay.Models;

/// <summary>
/// The model of the order cancellation.
/// </summary>
public class OrderCancellationModel
{
public OrderCancellationModel(Guid orderId, string orderCode, string returnUrl)
=> (OrderId, OrderCode, ReturnUrl) = (orderId, orderCode, returnUrl);

/// <summary>
/// The id of the order.
/// </summary>
public Guid OrderId { get; set; }

/// <summary>
/// The code of the order. Here is an alias for `外部订单号`.
/// </summary>
public string OrderCode { get; set; }

/// <summary>
/// The URL set by the API caller.
/// </summary>
public string ReturnUrl { get; set; }
}
27 changes: 27 additions & 0 deletions src/TokenPay/Views/Home/Cancel.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@model OrderCancellationModel
@{
ViewData["Title"] = "Order canceled";
}
<section class="container-fluid">
<div class="container d-grid gap-3 mx-auto my-4" style="max-width: 55rem;">
<div class="row card p-5 rounded-0 border-0 shadow-sm">
<div class="card-body border-0 p-4 d-flex flex-column align-items-center">
<img src="~/images/finish-error.png" alt="Order canceled" height="100" />
<h4 class="mt-5 mb-4 fw-bold">Order Canceled</h4>
<p class="text-secondary text-center lead fs-6">
The order has been canceled, please contact online service if you have any questions.
</p>
<footer class="mt-5 justify-content-center">
<a href="@Model.ReturnUrl" class="col btn btn-outline-secondary rounded-pill px-5 w-auto">
Continue
</a>
</footer>
</div>

<div class="card-footer d-flex flex-column align-items-center bg-white border-0 p-4">
<p class="text-secondary">Order Code:</p>
<h4 class="fs-5 order-code">@Model.OrderCode</h4>
</div>
</div>
</div>
</section>
45 changes: 25 additions & 20 deletions src/TokenPay/Views/Home/OrderExpired.cshtml
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
@{
ViewData["Title"] = "订单过期";
ViewData["Title"] = "订单已过期";
}
@using TokenPay.Domains;
@model TokenPay.Domains.TokenOrders
<div class="row align-items-center h-100">
@if (Model == null)
{
<div class="text-center">
<h4 class="display-4">订单不存在!</h4>
</div>
}
else
{
<div class="text-center">
<h1 class="display-4">订单已过期!</h1>
@if (!string.IsNullOrEmpty(Model.RedirectUrl))
{
<a class="btn btn-primary btn-sm" href="@Model.RedirectUrl">返回</a>
}
</div>

}
</div>
<section class="container-fluid">
<div class="container d-grid gap-3 mx-auto my-4" style="max-width: 55rem;">
<div class="row card p-5 rounded-0 border-0 shadow-sm">
<div class="card-body border-0 p-4 d-flex flex-column align-items-center">
<img src="~/images/finish-error.png" alt="Order canceled" height="100" />
<h4 class="mt-5 mb-4 fw-bold">订单已过期</h4>
<p class="text-secondary text-center lead fs-6">
The order has been expired, please contact online service if you have any questions.
此订单已经过期,如果有任何疑问可以联系在线客服。
</p>
<footer class="mt-5 justify-content-center">
<a href="@Model.RedirectUrl" class="col btn btn-outline-secondary rounded-pill px-5 w-auto">
继续
</a>
</footer>
</div>

<div class="card-footer d-flex flex-column align-items-center bg-white border-0 p-4">
<p class="text-secondary">订单号:</p>
<h4 class="fs-5 order-code">@Model.OutOrderId</h4>
</div>
</div>
</div>
</section>
44 changes: 24 additions & 20 deletions src/TokenPay/Views/Home/OrderExpired.en.cshtml
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
@{
ViewData["Title"] = "订单过期";
ViewData["Title"] = "Order expired";
}
@using TokenPay.Domains;
@model TokenPay.Domains.TokenOrders
<div class="row align-items-center h-100">
@if (Model == null)
{
<div class="text-center">
<h4 class="display-4">Order does not exist!</h4>
</div>
}
else
{
<div class="text-center">
<h1 class="display-4">Order has expired!</h1>
@if (!string.IsNullOrEmpty(Model.RedirectUrl))
{
<a class="btn btn-primary btn-sm" href="@Model.RedirectUrl">Back</a>
}
</div>

}
</div>
<section class="container-fluid">
<div class="container d-grid gap-3 mx-auto my-4" style="max-width: 55rem;">
<div class="row card p-5 rounded-0 border-0 shadow-sm">
<div class="card-body border-0 p-4 d-flex flex-column align-items-center">
<img src="~/images/finish-error.png" alt="Order canceled" height="100" />
<h4 class="mt-5 mb-4 fw-bold">Order Expired</h4>
<p class="text-secondary text-center lead fs-6">
The order has been expired, please contact online service if you have any questions.
</p>
<footer class="mt-5 justify-content-center">
<a href="@Model.RedirectUrl" class="col btn btn-outline-secondary rounded-pill px-5 w-auto">
Continue
</a>
</footer>
</div>

<div class="card-footer d-flex flex-column align-items-center bg-white border-0 p-4">
<p class="text-secondary">Order Code:</p>
<h4 class="fs-5 order-code">@Model.OutOrderId</h4>
</div>
</div>
</div>
</section>
Loading