Custom apps create payment orders

This commit is contained in:
2025-10-05 21:59:07 +08:00
parent 42dad7095a
commit 243159e4cc
2 changed files with 84 additions and 31 deletions

View File

@@ -1,5 +1,6 @@
using DysonNetwork.Pass.Auth; using DysonNetwork.Pass.Auth;
using DysonNetwork.Shared.Models; using DysonNetwork.Shared.Models;
using DysonNetwork.Shared.Proto;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -8,8 +9,54 @@ namespace DysonNetwork.Pass.Wallet;
[ApiController] [ApiController]
[Route("/api/orders")] [Route("/api/orders")]
public class OrderController(PaymentService payment, AuthService auth, AppDatabase db) : ControllerBase public class OrderController(
PaymentService payment,
Pass.Auth.AuthService auth,
AppDatabase db,
CustomAppService.CustomAppServiceClient customApps
) : ControllerBase
{ {
public class CreateOrderRequest
{
public string Currency { get; set; } = null!;
public decimal Amount { get; set; }
public string? Remarks { get; set; }
public string? ProductIdentifier { get; set; }
public Dictionary<string, object>? Meta { get; set; }
public int DurationHours { get; set; } = 24;
public string ClientId { get; set; } = null!;
public string ClientSecret { get; set; } = null!;
}
[HttpPost]
public async Task<ActionResult<SnWalletOrder>> CreateOrder([FromBody] CreateOrderRequest request)
{
var clientResp = await customApps.GetCustomAppAsync(new GetCustomAppRequest { Slug = request.ClientId });
if (clientResp.App is null) return BadRequest("Client not found");
var client = SnCustomApp.FromProtoValue(clientResp.App);
var secret = await customApps.CheckCustomAppSecretAsync(new CheckCustomAppSecretRequest
{
AppId = client.Id.ToString(),
Secret = request.ClientSecret,
});
if (!secret.Valid) return BadRequest("Invalid client secret");
var order = await payment.CreateOrderAsync(
default,
request.Currency,
request.Amount,
NodaTime.Duration.FromHours(request.DurationHours),
request.ClientId,
request.ProductIdentifier,
request.Remarks,
request.Meta
);
return Ok(order);
}
[HttpGet("{id:guid}")] [HttpGet("{id:guid}")]
public async Task<ActionResult<SnWalletOrder>> GetOrderById(Guid id) public async Task<ActionResult<SnWalletOrder>> GetOrderById(Guid id)
{ {
@@ -21,6 +68,11 @@ public class OrderController(PaymentService payment, AuthService auth, AppDataba
return Ok(order); return Ok(order);
} }
public class PayOrderRequest
{
public string PinCode { get; set; } = string.Empty;
}
[HttpPost("{id:guid}/pay")] [HttpPost("{id:guid}/pay")]
[Authorize] [Authorize]
public async Task<ActionResult<SnWalletOrder>> PayOrder(Guid id, [FromBody] PayOrderRequest request) public async Task<ActionResult<SnWalletOrder>> PayOrder(Guid id, [FromBody] PayOrderRequest request)
@@ -49,7 +101,3 @@ public class OrderController(PaymentService payment, AuthService auth, AppDataba
} }
} }
public class PayOrderRequest
{
public string PinCode { get; set; } = string.Empty;
}

View File

@@ -81,12 +81,14 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
}; };
} }
public SnCustomApp FromProtoValue(Proto.CustomApp p) public static SnCustomApp FromProtoValue(Proto.CustomApp p)
{ {
Id = Guid.Parse(p.Id); var obj = new SnCustomApp
Slug = p.Slug; {
Name = p.Name; Id = Guid.Parse(p.Id),
Description = string.IsNullOrEmpty(p.Description) ? null : p.Description; Slug = p.Slug,
Name = p.Name,
Description = string.IsNullOrEmpty(p.Description) ? null : p.Description,
Status = p.Status switch Status = p.Status switch
{ {
Shared.Proto.CustomAppStatus.Developing => CustomAppStatus.Developing, Shared.Proto.CustomAppStatus.Developing => CustomAppStatus.Developing,
@@ -94,23 +96,26 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
Shared.Proto.CustomAppStatus.Production => CustomAppStatus.Production, Shared.Proto.CustomAppStatus.Production => CustomAppStatus.Production,
Shared.Proto.CustomAppStatus.Suspended => CustomAppStatus.Suspended, Shared.Proto.CustomAppStatus.Suspended => CustomAppStatus.Suspended,
_ => CustomAppStatus.Developing _ => CustomAppStatus.Developing
},
ProjectId = string.IsNullOrEmpty(p.ProjectId) ? Guid.Empty : Guid.Parse(p.ProjectId),
CreatedAt = p.CreatedAt.ToInstant(),
UpdatedAt = p.UpdatedAt.ToInstant(),
}; };
ProjectId = string.IsNullOrEmpty(p.ProjectId) ? Guid.Empty : Guid.Parse(p.ProjectId);
CreatedAt = p.CreatedAt.ToInstant(); if (p.Picture is not null) obj.Picture = SnCloudFileReferenceObject.FromProtoValue(p.Picture);
UpdatedAt = p.UpdatedAt.ToInstant(); if (p.Background is not null) obj.Background = SnCloudFileReferenceObject.FromProtoValue(p.Background);
if (p.Picture is not null) Picture = SnCloudFileReferenceObject.FromProtoValue(p.Picture); if (p.Verification is not null) obj.Verification = SnVerificationMark.FromProtoValue(p.Verification);
if (p.Background is not null) Background = SnCloudFileReferenceObject.FromProtoValue(p.Background);
if (p.Verification is not null) Verification = SnVerificationMark.FromProtoValue(p.Verification);
if (p.Links is not null) if (p.Links is not null)
{ {
Links = new SnCustomAppLinks obj.Links = new SnCustomAppLinks
{ {
HomePage = string.IsNullOrEmpty(p.Links.HomePage) ? null : p.Links.HomePage, HomePage = string.IsNullOrEmpty(p.Links.HomePage) ? null : p.Links.HomePage,
PrivacyPolicy = string.IsNullOrEmpty(p.Links.PrivacyPolicy) ? null : p.Links.PrivacyPolicy, PrivacyPolicy = string.IsNullOrEmpty(p.Links.PrivacyPolicy) ? null : p.Links.PrivacyPolicy,
TermsOfService = string.IsNullOrEmpty(p.Links.TermsOfService) ? null : p.Links.TermsOfService TermsOfService = string.IsNullOrEmpty(p.Links.TermsOfService) ? null : p.Links.TermsOfService
}; };
} }
return this;
return obj;
} }
} }