| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- using Infrastructure.Kyc.Nice;
- using MediatR;
- using Microsoft.Extensions.Options;
- using Web.Api.Common;
- namespace Web.Api.Endpoints.Developers.Profile;
- internal sealed class KycCallback : IEndpoint
- {
- // NICE 표준창 → return_url 콜백. NICE 가 query string 으로 web_transaction_id 전달.
- // 이 endpoint 는 cookie 없는 외부 호출이라 anonymous. 검증은 NICE result API 가 web_transaction_id 의 유효성을 보장.
- // 처리 후 Frontend 의 결과 페이지로 302 redirect.
- public void MapEndpoint(IEndpointRouteBuilder app)
- {
- app.MapGet("api/developers/profile/kyc/callback/{sessionToken}", async (
- string sessionToken,
- HttpContext httpContext,
- ISender sender,
- IOptions<NiceAuthOptions> options,
- CancellationToken ct
- ) => {
- var frontUrl = options.Value.FrontendCallbackUrl;
- if (string.IsNullOrWhiteSpace(frontUrl))
- {
- // Frontend URL 미설정 — 운영자 안내
- return Results.Problem(
- detail: "FrontendCallbackUrl 이 설정되지 않았습니다.",
- statusCode: 500);
- }
- var webTransactionId = httpContext.Request.Query["web_transaction_id"].ToString();
- if (string.IsNullOrEmpty(webTransactionId))
- {
- return Results.Redirect(BuildRedirect(frontUrl, ok: false, "인증이 취소되었습니다."));
- }
- var command = new Application.Features.Api.Developers.Profile.CompleteKyc.Command(sessionToken, webTransactionId);
- var result = await sender.Send(command, ct);
- return Results.Redirect(result.IsSuccess
- ? BuildRedirect(frontUrl, ok: true, null)
- : BuildRedirect(frontUrl, ok: false, result.Error.Description));
- })
- .WithTags("Developers")
- .AllowAnonymous();
- }
- private static string BuildRedirect(string frontUrl, bool ok, string? message)
- {
- var separator = frontUrl.Contains('?') ? '&' : '?';
- var ms = string.IsNullOrEmpty(message) ? string.Empty : "&message=" + Uri.EscapeDataString(message);
- return $"{frontUrl}{separator}ok={(ok ? 1 : 0)}{ms}";
- }
- }
|