378 lines
14 KiB
C#
378 lines
14 KiB
C#
using _0_Framework.Application;
|
||
using _0_Framework.Application.PaymentGateway;
|
||
using Company.Domain.BankAgg;
|
||
using Company.Domain.PaymentTransactionAgg;
|
||
using CompanyManagment.App.Contracts.FinancialStatment;
|
||
using CompanyManagment.App.Contracts.FinancilTransaction;
|
||
using CompanyManagment.App.Contracts.PaymentTransaction;
|
||
using CompanyManagment.App.Contracts.Workshop;
|
||
using CompanyManagment.EFCore.Migrations;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Options;
|
||
using Newtonsoft.Json;
|
||
using NuGet.Protocol;
|
||
using Parbad;
|
||
using ServiceHost.BaseControllers;
|
||
using System.ComponentModel.DataAnnotations;
|
||
using System.Globalization;
|
||
using System.Net.Http;
|
||
using System.Security.Cryptography;
|
||
using System.Threading;
|
||
using CompanyManagment.App.Contracts.FinancialInvoice;
|
||
using CompanyManagment.App.Contracts.InstitutionContract;
|
||
using GozareshgirProgramManager.Application._Common.Constants;
|
||
using GozareshgirProgramManager.Infrastructure.Persistence.Context;
|
||
|
||
namespace ServiceHost.Controllers;
|
||
|
||
public class GeneralController : GeneralBaseController
|
||
{
|
||
private readonly IPaymentTransactionApplication _paymentTransactionApplication;
|
||
private readonly IPaymentGateway _paymentGateway;
|
||
private readonly IFinancialStatmentApplication _financialStatmentApplication;
|
||
private readonly IFinancialInvoiceApplication _financialInvoiceApplication;
|
||
private readonly IInstitutionContractApplication _institutionContractApplication;
|
||
|
||
public GeneralController(IPaymentTransactionApplication paymentTransactionApplication,
|
||
IHttpClientFactory clientFactory, IFinancialStatmentApplication financialStatmentApplication,
|
||
IFinancialInvoiceApplication financialInvoiceApplication,
|
||
IInstitutionContractApplication institutionContractApplication)
|
||
{
|
||
_paymentTransactionApplication = paymentTransactionApplication;
|
||
_paymentGateway = new SepehrPaymentGateway(clientFactory);
|
||
_financialStatmentApplication = financialStatmentApplication;
|
||
_financialInvoiceApplication = financialInvoiceApplication;
|
||
_institutionContractApplication = institutionContractApplication;
|
||
}
|
||
|
||
/// <summary>
|
||
/// نمایش اطلاعات عمومی مانند تاریخ ها و سال ها
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet("Dates")]
|
||
public IActionResult GetDates()
|
||
{
|
||
var pc = new PersianCalendar();
|
||
var now = DateTime.Now;
|
||
var currentYear = pc.GetYear(now);
|
||
var years = Enumerable.Range(1370, currentYear - 1370 + 1).ToList();
|
||
var months = Enumerable.Range(1, 12).ToList();
|
||
var currentDate = new { Year = currentYear, Month = pc.GetMonth(now), Day = pc.GetDayOfMonth(now) };
|
||
return new JsonResult(new
|
||
{
|
||
years,
|
||
months,
|
||
currentDate
|
||
});
|
||
}
|
||
|
||
[HttpGet("pm-permissions")]
|
||
public IActionResult GetPMPermissions()
|
||
{
|
||
var permissions = ProgramManagerPermissionCode.GetAllCodes();
|
||
return new JsonResult(permissions);
|
||
}
|
||
|
||
[HttpGet("/api/callback"), HttpPost("/api/callback")]
|
||
public async Task<IActionResult> Verify(SepehrGatewayPayResponse payResponse)
|
||
{
|
||
if (!long.TryParse(payResponse.invoiceid, out var paymentTransactionId))
|
||
{
|
||
return BadRequest("Invalid invoice_id");
|
||
}
|
||
|
||
var transaction = await _paymentTransactionApplication.GetDetails(paymentTransactionId);
|
||
|
||
if (transaction == null)
|
||
{
|
||
return NotFound("Transaction not found");
|
||
}
|
||
|
||
if (transaction.Status != PaymentTransactionStatus.Pending)
|
||
{
|
||
return BadRequest("این تراکنش قبلا پرداخت شده است");
|
||
}
|
||
|
||
|
||
if (payResponse.respcode != 0)
|
||
{
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
var extraData = JsonConvert.DeserializeObject<IDictionary<string, object>>(payResponse.payload);
|
||
extraData.TryGetValue("financialInvoiceId", out var financialInvoiceIdObj);
|
||
if (financialInvoiceIdObj == null ||
|
||
!long.TryParse(financialInvoiceIdObj.ToString(), out var financialInvoiceId))
|
||
{
|
||
return BadRequest("فاکتور مالی نامعتبر است");
|
||
}
|
||
|
||
|
||
var financialInvoice = _financialInvoiceApplication.GetDetails(financialInvoiceId);
|
||
|
||
if (financialInvoice == null)
|
||
{
|
||
return BadRequest("فاکتور مالی نامعتبر است");
|
||
}
|
||
|
||
if (financialInvoice.Status != FinancialInvoiceStatus.Unpaid)
|
||
{
|
||
return BadRequest("فاکتور مالی نامعتبر است");
|
||
}
|
||
|
||
if (financialInvoice.Amount != transaction.Amount)
|
||
{
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
var verifyCommand = new VerifyPaymentGateWayRequest()
|
||
{
|
||
Amount = transaction.Amount,
|
||
TransactionId = payResponse.invoiceid,
|
||
DigitalReceipt = payResponse.digitalreceipt
|
||
};
|
||
|
||
var verifyRes = await _paymentGateway.Verify(verifyCommand, CancellationToken.None);
|
||
_financialInvoiceApplication.SetPaid(financialInvoiceId, DateTime.Now);
|
||
|
||
if (verifyRes.IsSuccess)
|
||
{
|
||
var command = new CreateFinancialStatment()
|
||
{
|
||
ContractingPartyId = transaction.ContractingPartyId,
|
||
Deptor = 0,
|
||
Creditor = transaction.Amount,
|
||
DeptorString = "0",
|
||
TypeOfTransaction = "credit",
|
||
DescriptionOption = financialInvoice.Description + "شماره فاکتور" + financialInvoice.InvoiceNumber,
|
||
Description = "درگاه بانکی",
|
||
};
|
||
var statementResult = _financialStatmentApplication.CreateFromBankGateway(command);
|
||
if (!statementResult.IsSuccedded)
|
||
{
|
||
return new JsonResult(statementResult);
|
||
}
|
||
|
||
var setSuccessResult = _paymentTransactionApplication.SetSuccess(paymentTransactionId,
|
||
payResponse.cardnumber, payResponse.issuerbank, payResponse.rrn.ToString(),
|
||
payResponse.digitalreceipt);
|
||
|
||
if (financialInvoice.Items?.Any(x => x.Type is FinancialInvoiceItemType.BuyInstitutionContract or FinancialInvoiceItemType.BuyInstitutionContractInstallment) ?? false)
|
||
{
|
||
var financialItems = financialInvoice.Items
|
||
.Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContract);
|
||
foreach (var editFinancialInvoiceItem in financialItems)
|
||
{
|
||
await _institutionContractApplication.SetPendingWorkflow(editFinancialInvoiceItem.EntityId);
|
||
}
|
||
var financialInstallmentItems = financialInvoice.Items
|
||
.Where(x => x.Type == FinancialInvoiceItemType.BuyInstitutionContractInstallment);
|
||
|
||
foreach (var editFinancialInvoiceItem in financialInstallmentItems)
|
||
{
|
||
var institutionContractId =
|
||
await _institutionContractApplication.GetIdByInstallmentId(
|
||
editFinancialInvoiceItem.EntityId);
|
||
await _institutionContractApplication.SetPendingWorkflow(institutionContractId);
|
||
}
|
||
}
|
||
|
||
if (!setSuccessResult.IsSuccedded)
|
||
{
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
return Redirect(BuildCallbackUrl(transaction.CallBackUrl, true, transaction.Id));
|
||
}
|
||
|
||
// در غیر این صورت تراکنش ناموفق است
|
||
return await HandleFailedTransaction(transaction);
|
||
|
||
|
||
//var data = JsonConvert.SerializeObject(invoice.AdditionalData);
|
||
//var statics =
|
||
//JsonConvert.SerializeObject(res);
|
||
|
||
//await _onlinePayment.CancelAsync(invoice);
|
||
//return new JsonResult(new
|
||
//{
|
||
// data,
|
||
// statics
|
||
//});
|
||
|
||
//// Check if the invoice is new, or it's already processed before.
|
||
//if (invoice.Status != PaymentFetchResultStatus.ReadyForVerifying)
|
||
//{
|
||
// // You can also see if the invoice is already verified before.
|
||
// var isAlreadyVerified = invoice.IsAlreadyVerified;
|
||
|
||
// return Content("The payment was not successful.");
|
||
//}
|
||
|
||
//// Note: Save the verifyResult.TransactionCode in your database.
|
||
}
|
||
|
||
[HttpPost("/api/callback3232")]
|
||
public async Task<IActionResult> OnGetCallBack(string? transid, string? cardnumber, string? tracking_number,
|
||
string bank, string invoice_id, string? status, CancellationToken cancellationToken)
|
||
{
|
||
if (!long.TryParse(invoice_id, out var paymentTransactionId))
|
||
{
|
||
return BadRequest("Invalid invoice_id");
|
||
}
|
||
|
||
var transaction = await _paymentTransactionApplication.GetDetails(paymentTransactionId);
|
||
if (transaction == null)
|
||
{
|
||
return NotFound("Transaction not found");
|
||
}
|
||
|
||
if (transaction.Status != PaymentTransactionStatus.Pending)
|
||
{
|
||
return BadRequest("این تراکنش قبلا پرداخت شده است");
|
||
}
|
||
|
||
// اگر شماره کارت یا شماره پیگیری خالی باشد، تراکنش ناموفق است
|
||
if (string.IsNullOrWhiteSpace(cardnumber) || string.IsNullOrWhiteSpace(tracking_number))
|
||
{
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
var verifyCommand = new VerifyPaymentGateWayRequest()
|
||
{
|
||
Amount = transaction.Amount / 10,
|
||
TransactionId = transid
|
||
};
|
||
var verifyRes = await _paymentGateway.Verify(verifyCommand, cancellationToken);
|
||
|
||
// اگر استاتوس 1 باشد، تراکنش موفق است
|
||
if (verifyRes.IsSuccess)
|
||
{
|
||
var command = new CreateFinancialStatment()
|
||
{
|
||
ContractingPartyId = transaction.ContractingPartyId,
|
||
Deptor = 0,
|
||
Creditor = transaction.Amount,
|
||
DeptorString = "0",
|
||
TypeOfTransaction = "credit",
|
||
DescriptionOption = "بابت قرارداد مابین (روابط کار)",
|
||
Description = "درگاه بانکی",
|
||
};
|
||
var statementResult = _financialStatmentApplication.CreateFromBankGateway(command);
|
||
if (!statementResult.IsSuccedded)
|
||
{
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
var setSuccessResult =
|
||
_paymentTransactionApplication.SetSuccess(paymentTransactionId, cardnumber, bank, null, null);
|
||
|
||
if (!setSuccessResult.IsSuccedded)
|
||
{
|
||
return new JsonResult(setSuccessResult);
|
||
}
|
||
|
||
return Redirect(BuildCallbackUrl(transaction.CallBackUrl, true, transaction.Id));
|
||
}
|
||
|
||
// در غیر این صورت تراکنش ناموفق است
|
||
return await HandleFailedTransaction(transaction);
|
||
}
|
||
|
||
private async Task<IActionResult> HandleFailedTransaction(PaymentTransactionDetailsViewModel transaction)
|
||
{
|
||
var result = _paymentTransactionApplication.SetFailed(transaction.Id);
|
||
if (!result.IsSuccedded)
|
||
{
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
return Redirect(BuildCallbackUrl(transaction.CallBackUrl, false, transaction.Id));
|
||
}
|
||
|
||
private string BuildCallbackUrl(string baseUrl, bool isSuccess, long transactionId)
|
||
{
|
||
var statusCode = isSuccess ? "1" : "0";
|
||
return $"{baseUrl}/callback?Status={statusCode}&transactionId={transactionId}";
|
||
}
|
||
}
|
||
|
||
public class TokenReq
|
||
{
|
||
public long Amount { get; set; }
|
||
|
||
public string CallbackUrl { get; set; }
|
||
|
||
[Display(Name = "شماره فاکتور")]
|
||
[MaxLength(100)]
|
||
[Required]
|
||
[Key]
|
||
// be ezaye har pazirande bayad yekta bashad
|
||
public string invoiceID { get; set; }
|
||
|
||
[Required] public long terminalID { get; set; }
|
||
|
||
/*
|
||
* JSON Bashad
|
||
* etelaate takmili site harchi
|
||
* nabayad char khas dashte bashe (*'"xp_%!+- ...)
|
||
*/
|
||
public string Payload { get; set; } = "";
|
||
public string email { get; set; }
|
||
}
|
||
|
||
public class TokenResp
|
||
{
|
||
// if 0 = success
|
||
public int Status { get; set; }
|
||
public string AccessToken { get; set; }
|
||
}
|
||
|
||
public class PayRequest
|
||
{
|
||
[Required] [MaxLength(3000)] public string token { get; set; }
|
||
[Required] public long terminalID { get; set; }
|
||
public string nationalCode { get; set; }
|
||
}
|
||
|
||
public class SepehrGatewayPayResponse
|
||
{
|
||
/* 0 yni movafaq
|
||
* -1 yni enseraf
|
||
* -2 yni etmam zaman
|
||
*/
|
||
public int respcode { get; set; }
|
||
[Display(Name = "متن نتیجه تراکنش")] public string respmsg { get; set; }
|
||
|
||
[Display(Name = "مبلغ کسر شده از مشتری")]
|
||
public long amount { get; set; }
|
||
|
||
[Display(Name = " شماره فاکتور ")] public string invoiceid { get; set; }
|
||
|
||
[Display(Name = " اطلاعاتی که پذیرنده ارسال کرد ")]
|
||
public string payload { get; set; }
|
||
|
||
[Display(Name = " شماره ترمینال ")] public long terminalid { get; set; }
|
||
|
||
[Display(Name = " شماره پیگیری ")] public long tracenumber { get; set; }
|
||
|
||
// bayad negah dari she hatman to db
|
||
[Display(Name = " شماره سند بانکی ")] public long rrn { get; set; }
|
||
|
||
[Display(Name = " زمان و تاریخ پرداخت ")]
|
||
public string datepaid { get; set; }
|
||
|
||
[Display(Name = " رسید دیجیتال ")] public string digitalreceipt { get; set; }
|
||
|
||
[Display(Name = " نام بانک صادر کننده کارت ")]
|
||
public string issuerbank { get; set; }
|
||
|
||
[Display(Name = " شماره کارت ")] public string cardnumber { get; set; }
|
||
}
|
||
|
||
public class AdviceReq
|
||
{
|
||
[Display(Name = " رسید دیجیتال ")] public string digitalreceipt { get; set; }
|
||
public long Tid { get; set; }
|
||
} |