✨ Custom apps create payment orders
This commit is contained in:
@@ -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,36 +9,87 @@ 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)
|
||||||
{
|
{
|
||||||
var order = await db.PaymentOrders.FindAsync(id);
|
var order = await db.PaymentOrders.FindAsync(id);
|
||||||
|
|
||||||
if (order == null)
|
if (order == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
|
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
|
||||||
|
|
||||||
// Validate PIN code
|
// Validate PIN code
|
||||||
if (!await auth.ValidatePinCode(currentUser.Id, request.PinCode))
|
if (!await auth.ValidatePinCode(currentUser.Id, request.PinCode))
|
||||||
return StatusCode(403, "Invalid PIN Code");
|
return StatusCode(403, "Invalid PIN Code");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get the wallet for the current user
|
// Get the wallet for the current user
|
||||||
var wallet = await db.Wallets.FirstOrDefaultAsync(w => w.AccountId == currentUser.Id);
|
var wallet = await db.Wallets.FirstOrDefaultAsync(w => w.AccountId == currentUser.Id);
|
||||||
if (wallet == null)
|
if (wallet == null)
|
||||||
return BadRequest("Wallet was not found.");
|
return BadRequest("Wallet was not found.");
|
||||||
|
|
||||||
// Pay the order
|
// Pay the order
|
||||||
var paidOrder = await payment.PayOrderAsync(id, wallet);
|
var paidOrder = await payment.PayOrderAsync(id, wallet);
|
||||||
return Ok(paidOrder);
|
return Ok(paidOrder);
|
||||||
@@ -49,7 +101,3 @@ public class OrderController(PaymentService payment, AuthService auth, AppDataba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PayOrderRequest
|
|
||||||
{
|
|
||||||
public string PinCode { get; set; } = string.Empty;
|
|
||||||
}
|
|
@@ -34,7 +34,7 @@ public class SnCustomApp : ModelBase, IIdentifiedResource
|
|||||||
|
|
||||||
public Guid ProjectId { get; set; }
|
public Guid ProjectId { get; set; }
|
||||||
public SnDevProject Project { get; set; } = null!;
|
public SnDevProject Project { get; set; } = null!;
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public SnDeveloper Developer => Project.Developer;
|
public SnDeveloper Developer => Project.Developer;
|
||||||
|
|
||||||
@@ -81,36 +81,41 @@ 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;
|
|
||||||
Description = string.IsNullOrEmpty(p.Description) ? null : p.Description;
|
|
||||||
Status = p.Status switch
|
|
||||||
{
|
{
|
||||||
Shared.Proto.CustomAppStatus.Developing => CustomAppStatus.Developing,
|
Id = Guid.Parse(p.Id),
|
||||||
Shared.Proto.CustomAppStatus.Staging => CustomAppStatus.Staging,
|
Slug = p.Slug,
|
||||||
Shared.Proto.CustomAppStatus.Production => CustomAppStatus.Production,
|
Name = p.Name,
|
||||||
Shared.Proto.CustomAppStatus.Suspended => CustomAppStatus.Suspended,
|
Description = string.IsNullOrEmpty(p.Description) ? null : p.Description,
|
||||||
_ => CustomAppStatus.Developing
|
Status = p.Status switch
|
||||||
|
{
|
||||||
|
Shared.Proto.CustomAppStatus.Developing => CustomAppStatus.Developing,
|
||||||
|
Shared.Proto.CustomAppStatus.Staging => CustomAppStatus.Staging,
|
||||||
|
Shared.Proto.CustomAppStatus.Production => CustomAppStatus.Production,
|
||||||
|
Shared.Proto.CustomAppStatus.Suspended => CustomAppStatus.Suspended,
|
||||||
|
_ => 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user