diff --git a/src/TokenPay/Controllers/HomeController.cs b/src/TokenPay/Controllers/HomeController.cs index 3f4cac4..d21141c 100644 --- a/src/TokenPay/Controllers/HomeController.cs +++ b/src/TokenPay/Controllers/HomeController.cs @@ -113,6 +113,13 @@ public async Task 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) @@ -535,5 +542,32 @@ private static byte[] CreateQrCode(string qrcode, int size = 300) qrCode.GenerateImage(stream); return stream.ToArray(); } + + /// + /// Cancel the payment of an order. + /// + /// The id of the order. + /// The result of the cancellation. + [HttpGet("/Cancel/{id:guid}")] + public async Task 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)); + } } } diff --git a/src/TokenPay/Domains/TokenOrders.cs b/src/TokenPay/Domains/TokenOrders.cs index f752524..43850a6 100644 --- a/src/TokenPay/Domains/TokenOrders.cs +++ b/src/TokenPay/Domains/TokenOrders.cs @@ -85,6 +85,7 @@ public enum OrderStatus { Pending, Paid, - Expired + Expired, + Closed, } } diff --git a/src/TokenPay/Models/OrderCancellationModel.cs b/src/TokenPay/Models/OrderCancellationModel.cs new file mode 100644 index 0000000..49275cd --- /dev/null +++ b/src/TokenPay/Models/OrderCancellationModel.cs @@ -0,0 +1,25 @@ +namespace TokenPay.Models; + +/// +/// The model of the order cancellation. +/// +public class OrderCancellationModel +{ + public OrderCancellationModel(Guid orderId, string orderCode, string returnUrl) + => (OrderId, OrderCode, ReturnUrl) = (orderId, orderCode, returnUrl); + + /// + /// The id of the order. + /// + public Guid OrderId { get; set; } + + /// + /// The code of the order. Here is an alias for `外部订单号`. + /// + public string OrderCode { get; set; } + + /// + /// The URL set by the API caller. + /// + public string ReturnUrl { get; set; } +} \ No newline at end of file diff --git a/src/TokenPay/Views/Home/Cancel.cshtml b/src/TokenPay/Views/Home/Cancel.cshtml new file mode 100644 index 0000000..07fba13 --- /dev/null +++ b/src/TokenPay/Views/Home/Cancel.cshtml @@ -0,0 +1,27 @@ +@model OrderCancellationModel +@{ + ViewData["Title"] = "Order canceled"; +} +
+
+
+
+ Order canceled +

Order Canceled

+

+ The order has been canceled, please contact online service if you have any questions. +

+ +
+ + +
+
+
\ No newline at end of file diff --git a/src/TokenPay/Views/Home/OrderExpired.cshtml b/src/TokenPay/Views/Home/OrderExpired.cshtml index c27d714..614ad31 100644 --- a/src/TokenPay/Views/Home/OrderExpired.cshtml +++ b/src/TokenPay/Views/Home/OrderExpired.cshtml @@ -1,24 +1,29 @@ @{ - ViewData["Title"] = "订单过期"; + ViewData["Title"] = "订单已过期"; } -@using TokenPay.Domains; @model TokenPay.Domains.TokenOrders -
- @if (Model == null) - { -
-

订单不存在!

-
- } - else - { -
-

订单已过期!

- @if (!string.IsNullOrEmpty(Model.RedirectUrl)) - { - 返回 - } -
- } -
+
+
+
+
+ Order canceled +

订单已过期

+

+ The order has been expired, please contact online service if you have any questions. + 此订单已经过期,如果有任何疑问可以联系在线客服。 +

+ +
+ + +
+
+
\ No newline at end of file diff --git a/src/TokenPay/Views/Home/OrderExpired.en.cshtml b/src/TokenPay/Views/Home/OrderExpired.en.cshtml index f7149c1..735a936 100644 --- a/src/TokenPay/Views/Home/OrderExpired.en.cshtml +++ b/src/TokenPay/Views/Home/OrderExpired.en.cshtml @@ -1,24 +1,28 @@ @{ - ViewData["Title"] = "订单过期"; + ViewData["Title"] = "Order expired"; } -@using TokenPay.Domains; @model TokenPay.Domains.TokenOrders -
- @if (Model == null) - { -
-

Order does not exist!

-
- } - else - { -
-

Order has expired!

- @if (!string.IsNullOrEmpty(Model.RedirectUrl)) - { - Back - } -
- } -
+
+
+
+
+ Order canceled +

Order Expired

+

+ The order has been expired, please contact online service if you have any questions. +

+ +
+ + +
+
+
\ No newline at end of file diff --git a/src/TokenPay/Views/Home/Pay.cshtml b/src/TokenPay/Views/Home/Pay.cshtml index 78e2bdd..b2ed418 100644 --- a/src/TokenPay/Views/Home/Pay.cshtml +++ b/src/TokenPay/Views/Home/Pay.cshtml @@ -1,134 +1,133 @@ @{ - ViewData["Title"] = "支付页"; - var Now = DateTime.Now.ToUniversalTime(); - var ExpireTime = ViewData.ContainsKey("ExpireTime") ? Convert.ToDateTime(ViewData["ExpireTime"]).ToUniversalTime() : Now; + ViewData["Title"] = "订单支付"; } -@using TokenPay.Domains; @using TokenPay.Extensions @using TokenPay.Models.EthModel; @model TokenPay.Domains.TokenOrders -@inject List chain -@if (Model == null) -{ -
-
-

订单不存在!

-
-
+@inject List Chain +@inject IConfiguration Configuration -} -else -{ - -
-

您正在支付 @Model.Currency.ToBlockchainName(chain)@Model.Currency.ToCurrency(chain,true)

+
+
+
+
-
-
- - +
+ +
+
+ Wallet address +
+
-
- -
请仔细核对区块链和币种,避免丢失资产或支付失败!!!
-
-
区块链:@Model.Currency.ToBlockchainName(chain) 币种:@Model.Currency.ToCurrency(chain)
- 收款地址 -
@Model.ToAddress
-
-
-
- 支付金额:@Model.Amount @Model.Currency.ToCurrency(chain) + + -
- 订单编号:@Model.OutOrderId +
+ +
+ + +