93 lines
3.4 KiB
C#
93 lines
3.4 KiB
C#
using System.Globalization;
|
|
using AMREZ.EOP.Abstractions.Applications.UseCases.Payments.SlipVerification;
|
|
using AMREZ.EOP.Abstractions.Applications.UseCases.Payments.SlipVerification.QrDecode;
|
|
using AMREZ.EOP.Abstractions.Infrastructures.Integrations.SCB.Clients;
|
|
using AMREZ.EOP.Application.UseCases.Payments.SlipVerification.BankDetect;
|
|
using AMREZ.EOP.Application.UseCases.Payments.SlipVerification.QrDecode;
|
|
using AMREZ.EOP.Contracts.DTOs.Payments.SlipVerification;
|
|
using AMREZ.EOP.Domain.Shared.Payments;
|
|
|
|
namespace AMREZ.EOP.Application.UseCases.Payments.SlipVerification;
|
|
|
|
public sealed class VerifyFromImageUseCase : IVerifyFromImageUseCase
|
|
{
|
|
private readonly IQrDecoder _qr;
|
|
private readonly IScbSlipClient _scb;
|
|
private readonly SCBOptions _opts;
|
|
|
|
public VerifyFromImageUseCase(IQrDecoder qr, IScbSlipClient scb, SCBOptions opts)
|
|
{
|
|
_qr = qr;
|
|
_scb = scb;
|
|
_opts = opts;
|
|
}
|
|
|
|
public async Task<VerifyFromImageResponse?> ExecuteAsync(VerifyFromImageRequest request, CancellationToken ct)
|
|
{
|
|
await using var ms = new MemoryStream();
|
|
await request.Image.CopyToAsync(ms, ct);
|
|
|
|
var qrText = _qr.TryDecodeText(ms.ToArray());
|
|
var transId = TransRefParser.TryExtract(qrText);
|
|
var bank = ParserBankDetect.FromQrText(qrText) ?? _opts.DefaultSendingBank;
|
|
|
|
if (string.IsNullOrWhiteSpace(transId)) return null; // ไม่มี id ก็หยุด
|
|
|
|
// ← SCB API ต้องการ “id” (transRef/txnId) + sendingBank เท่านั้น
|
|
var env = await _scb.VerifyAsync(transId, bank, ct);
|
|
if (env?.Status?.Code != 1000 || env.Data is null) return null;
|
|
|
|
// 3) map → controller response
|
|
var d = env.Data;
|
|
var amount = decimal.TryParse(d.PaidLocalAmount ?? d.Amount ?? "0", NumberStyles.Any,
|
|
CultureInfo.InvariantCulture, out var v)
|
|
? v
|
|
: 0m;
|
|
var when = CombineBangkok(d.TransDate, d.TransTime);
|
|
|
|
var msisdn = d.Sender?.Proxy?.Type == "MSISDN" ? d.Sender.Proxy.Value : null;
|
|
var biller = d.Receiver?.Proxy?.Type == "BILLERID" ? d.Receiver.Proxy.Value : null;
|
|
|
|
return new VerifyFromImageResponse
|
|
{
|
|
TransRef = d.TransRef ?? transId,
|
|
SendingBank = bank,
|
|
AmountTHB = amount,
|
|
CurrencyNumeric = d.PaidLocalCurrency ?? "764",
|
|
SenderMsisdn = msisdn,
|
|
BillerId = biller,
|
|
TransactedAt = when
|
|
};
|
|
}
|
|
|
|
private static DateTimeOffset CombineBangkok(string? date, string? time)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(date) || string.IsNullOrWhiteSpace(time))
|
|
return DateTimeOffset.UtcNow; // fallback
|
|
|
|
var dt = DateTime.ParseExact($"{date} {time}", "yyyyMMdd HH:mm:ss", CultureInfo.InvariantCulture);
|
|
var local = DateTime.SpecifyKind(dt, DateTimeKind.Unspecified);
|
|
|
|
TimeZoneInfo? tz = null;
|
|
try
|
|
{
|
|
tz = TimeZoneInfo.FindSystemTimeZoneById("Asia/Bangkok");
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
if (tz is null)
|
|
try
|
|
{
|
|
tz = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time");
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
return tz is null
|
|
? new DateTimeOffset(local, TimeSpan.FromHours(7))
|
|
: new DateTimeOffset(local, tz.GetUtcOffset(local));
|
|
}
|
|
} |