From 60b53f6e39c0476def55598c762f540f6bc1bf13 Mon Sep 17 00:00:00 2001 From: MahanCh Date: Tue, 8 Jul 2025 12:54:23 +0330 Subject: [PATCH] add payment PaymentGateway --- .../AqayePardakhtPaymentGateway.cs | 76 ++++++ .../PaymentGateway/IPaymentGateway.cs | 49 ++++ DadmehrGostar.sln.DotSettings | 4 +- .../Pages/Company/AndroidApk/Index.cshtml | 6 + .../Pages/Company/AndroidApk/Index.cshtml.cs | 222 ++++++++++++++++-- ServiceHost/Properties/launchSettings.json | 2 +- 6 files changed, 343 insertions(+), 16 deletions(-) create mode 100644 0_Framework/Application/PaymentGateway/AqayePardakhtPaymentGateway.cs create mode 100644 0_Framework/Application/PaymentGateway/IPaymentGateway.cs diff --git a/0_Framework/Application/PaymentGateway/AqayePardakhtPaymentGateway.cs b/0_Framework/Application/PaymentGateway/AqayePardakhtPaymentGateway.cs new file mode 100644 index 00000000..3ef27aac --- /dev/null +++ b/0_Framework/Application/PaymentGateway/AqayePardakhtPaymentGateway.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Json; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace _0_Framework.Application.PaymentGateway; + +public class AqayePardakhtPaymentGateway:IPaymentGateway +{ + private const string Pin = "86EAF2C4D052F7D8759F"; + private readonly HttpClient _httpClient; + + public AqayePardakhtPaymentGateway(IHttpClientFactory httpClientFactory) + { + _httpClient = httpClientFactory.CreateClient(); + } + + public async Task Create(CreatePaymentGatewayRequest command) + { + var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new + { + pin = Pin, + amount = command.Amount, + callback = command.CallBackUrl, + card_number = command.CardNumber, + invoice_id = command.InvoiceId, + mobile = command.Mobile, + email = command.Email, + description = command.Email, + }); + + var result = await response.Content.ReadFromJsonAsync(); + return result; + } + + public string GetStartPayUrl(string transactionId) => + $"https://panel.aqayepardakht.ir/startpay/{transactionId}"; + + public async Task Verify(VerifyPaymentGateWayRequest command) + { + var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/verify", new + { + pin = Pin, + amount = command.Amount, + transid = command.TransactionId, + }); + + var result = await response.Content.ReadFromJsonAsync(); + return result; + } + + public async Task CreateSandBox(CreatePaymentGatewayRequest command) + { + var response = await _httpClient.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new + { + pin = "sandbox", + amount = command.Amount, + callback = command.CallBackUrl, + card_number = command.Amount, + invoice_id = command.InvoiceId, + mobile = command.Mobile, + email = command.Email, + description = command.Email, + }); + + var result = await response.Content.ReadFromJsonAsync(); + return result; + } + + public string GetStartPaySandBoxUrl(string transactionId) => + $"https://panel.aqayepardakht.ir/startpay/sandbox/{transactionId}"; +} \ No newline at end of file diff --git a/0_Framework/Application/PaymentGateway/IPaymentGateway.cs b/0_Framework/Application/PaymentGateway/IPaymentGateway.cs new file mode 100644 index 00000000..cc3d14a4 --- /dev/null +++ b/0_Framework/Application/PaymentGateway/IPaymentGateway.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.HttpSys; + +namespace _0_Framework.Application.PaymentGateway; + +public interface IPaymentGateway +{ + Task Create(CreatePaymentGatewayRequest command); + + string GetStartPayUrl(string transactionId); + Task Verify(VerifyPaymentGateWayRequest command); + Task CreateSandBox(CreatePaymentGatewayRequest command); + + string GetStartPaySandBoxUrl(string transactionId); + +} +public class PaymentGatewayResponse +{ + [JsonPropertyName("status")] + public string Status { get; set; } + + [JsonPropertyName("code")] + public int? ErrorCode { get; set; } + + [JsonPropertyName("transid")] + public string TransactionId { get; set; } +} + +public class CreatePaymentGatewayRequest +{ + public double Amount { get; set; } + public string CallBackUrl { get; set; } + public string InvoiceId { get; set; } + public string CardNumber { get; set; } + public string Mobile { get; set; } + public string Email { get; set; } + public string Description { get; set; } +} + +public class VerifyPaymentGateWayRequest +{ + public string TransactionId { get; set; } + public double Amount { get; set; } +} \ No newline at end of file diff --git a/DadmehrGostar.sln.DotSettings b/DadmehrGostar.sln.DotSettings index 2d803009..cd0dd14f 100644 --- a/DadmehrGostar.sln.DotSettings +++ b/DadmehrGostar.sln.DotSettings @@ -1,4 +1,6 @@  False + True True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml index b0b19817..4f02bec3 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml @@ -28,6 +28,12 @@ +
+ + +
+ + @if (ViewData["message"] != null) {

@ViewData["message"]

diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs index d4956894..9235eda6 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs @@ -12,6 +12,10 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; +using System.Net.Http; +using System.Text.Json.Serialization; +using _0_Framework.Application.PaymentGateway; +using static ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk.IndexModel2; namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk { @@ -22,16 +26,19 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk private readonly IRollCallDomainService _rollCallDomainService; private readonly CompanyContext _context; private readonly AccountContext _accountContext; + private readonly IPaymentGateway _paymentGateway; + [BindProperty] public IFormFile File { get; set; } - public IndexModel(IAndroidApkVersionApplication application, IRollCallDomainService rollCallDomainService, CompanyContext context, AccountContext accountContext) + public IndexModel(IAndroidApkVersionApplication application, IRollCallDomainService rollCallDomainService, CompanyContext context, AccountContext accountContext, IHttpClientFactory httpClientFactory) { _application = application; _rollCallDomainService = rollCallDomainService; _context = context; _accountContext = accountContext; + _paymentGateway = new AqayePardakhtPaymentGateway(httpClientFactory); } public void OnGet() @@ -82,22 +89,71 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk } public async Task OnPostShiftDateNew2() { - //var startRollCall = new DateTime(2025, 3, 21); - //var rollCalls = _context.RollCalls.Where(x => x.StartDate >= startRollCall && x.EndDate != null ).ToList(); - //var r1 = rollCalls.Skip(10000).Take(10000).ToList(); + //var startRollCall = new DateTime(2025, 3, 21); + //var rollCalls = _context.RollCalls.Where(x => x.StartDate >= startRollCall && x.EndDate != null ).ToList(); + //var r1 = rollCalls.Skip(10000).Take(10000).ToList(); - //Console.ForegroundColor = ConsoleColor.DarkRed; - //Console.WriteLine("endStep 1 ============"); - //SetRollCall(r1); + //Console.ForegroundColor = ConsoleColor.DarkRed; + //Console.WriteLine("endStep 1 ============"); + //SetRollCall(r1); await ChangeFridayWorkToWeeklyDayOfWeek(); - ViewData["message"] = "تومام دو"; - return Page(); + ViewData["message"] = "تومام دو"; + return Page(); + } + public async Task OnPostPaymentGateWay() + { + var command = new CreatePaymentGatewayRequest() + { + Amount = 1000, + Email = "mahanch83@gmail.com", + CallBackUrl = Url.Page(".", "Callback", null, Request.Scheme, Request.Host.Value), + InvoiceId = "{C771E841-B810-413D-9D4C-9F659575B8CC}", + + + }; + var createResponse = await _paymentGateway.CreateSandBox(command); + + + if (createResponse.Status == "success") + { + return Redirect(_paymentGateway.GetStartPaySandBoxUrl(createResponse.TransactionId)); + } + + //TranslateCode(result?.ErrorCode); + return Page(); + + } + + public async System.Threading.Tasks.Task OnGetCallback(string? transid, string? cardnumber, string? tracking_number, string status) + { + + + if (string.IsNullOrEmpty(cardnumber) || string.IsNullOrEmpty(tracking_number)) + { + ViewData["message"] = "پرداخت ناموفق بوده است"; + return; + } + else if (status == "1") + { + ViewData["message"] = "پرداخت موفق بوده است"; + return; + + } + //var client = _httpClientFactory.CreateClient(); + //var response = await client.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/verify", new + //{ + // pin = "aqayepardakht", + // amount = 100, + // transid = transid, + //}); + + //var result = await response.Content.ReadFromJsonAsync(); } private async System.Threading.Tasks.Task SetWorkshopRoleSubAccount() { - var subAccountRoles = _accountContext.SubAccountRoles.Include(x=>x.SubAccounts).ToList(); + var subAccountRoles = _accountContext.SubAccountRoles.Include(x => x.SubAccounts).ToList(); subAccountRoles.ForEach(role => { @@ -110,7 +166,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk role.Edit(role.Title, role.RolePermissions.Select(x => x.PermissionCode).ToList(), workshopIds); } - + }); await _accountContext.SaveChangesAsync(); } @@ -260,7 +316,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk var calculationMonth = Convert.ToInt32(calculationDate.ToFarsiMonth()); var calculationYear = Convert.ToInt32(calculationDate.ToFarsiYear()); - salaryAid.Edit(salaryAid.Amount,salaryAid.SalaryAidDateTime,0,UserType.Anonymous,calculationMonth, calculationYear); + salaryAid.Edit(salaryAid.Amount, salaryAid.SalaryAidDateTime, 0, UserType.Anonymous, calculationMonth, calculationYear); } @@ -273,7 +329,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk .Include(x => x.EmployeeDocumentItemCollection) .Where(x => x.IsConfirmed); - var employeeClientTemps = await _context.EmployeeClientTemps.Where(x=>employeeDocuments.Any(a=>a.WorkshopId == x.WorkshopId && a.EmployeeId == x.EmployeeId)).ToListAsync(); + var employeeClientTemps = await _context.EmployeeClientTemps.Where(x => employeeDocuments.Any(a => a.WorkshopId == x.WorkshopId && a.EmployeeId == x.EmployeeId)).ToListAsync(); foreach (var employeeClientTemp in employeeClientTemps) { @@ -285,7 +341,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk private async System.Threading.Tasks.Task ChangeIsConfirmed() { - var employeeDocuments = await _context.EmployeeDocuments.Include(x=>x.EmployeeDocumentItemCollection).ToListAsync(); + var employeeDocuments = await _context.EmployeeDocuments.Include(x => x.EmployeeDocumentItemCollection).ToListAsync(); foreach (var employeeDocument in employeeDocuments) { employeeDocument.UpdateRequiredItemsSubmittedByClient(); @@ -562,4 +618,142 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk } } + public class IndexModel2 : PageModel + { + private readonly ILogger logger; + private readonly IHttpClientFactory httpClientFactory; + + public IndexModel2(ILogger logger, IHttpClientFactory httpClientFactory) + { + this.logger = logger; + this.httpClientFactory = httpClientFactory; + } + + [BindProperty] + public string? Message { get; set; } + + public void OnGet() + { + + } + + public async Task OnPostAsync() + { + Message = null; + + var client = httpClientFactory.CreateClient(); + var response = await client.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/create", new + { + pin = "aqayepardakht", + amount = 100, + callback = System.Web.HttpUtility.UrlEncode(Url.Page("./Index", "Callback", null, Request.Scheme, Request.Host.Value)), + card_number = "1111111111111111", + invoice_id = "{C771E841-B810-413D-9D4C-9F659575B8CC}", + mobile = "09121111111", + email = "test@test.com", + description = "توضیحات تست", + }); + + var result = await response.Content.ReadFromJsonAsync(); + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + return Redirect($"https://panel.aqayepardakht.ir/startpay/{result?.TransactionId}"); + } + + TranslateCode(result?.ErrorCode); + return Page(); + } + + public async System.Threading.Tasks.Task OnGetCallbackAsync(string? transid, string? cardnumber, string? tracking_number) + { + Message = null; + + if (string.IsNullOrEmpty(cardnumber) || string.IsNullOrEmpty(tracking_number)) + { + Message = "پرداخت ناموفق بوده است"; + return; + } + + var client = httpClientFactory.CreateClient(); + var response = await client.PostAsJsonAsync("https://panel.aqayepardakht.ir/api/v2/verify", new + { + pin = "aqayepardakht", + amount = 100, + transid = transid, + }); + + var result = await response.Content.ReadFromJsonAsync(); + TranslateCode(result?.ErrorCode); + } + + private void TranslateCode(int? code) + { + switch (code) + { + case 0: + Message = "پرداخت انجام نشد"; + break; + case 1: + Message = "پرداخت با موفقیت انجام شد"; + break; + case 2: + Message = "تراکنش قبلا وریفای شده است"; + break; + case -1: + Message = "amount نمی تواند خالی باشد"; + break; + case -2: + Message = "کد پین درگاه نمی تواند خالی باشد"; + break; + case -3: + Message = "callback نمی تواند خالی باشد"; + break; + case -4: + Message = "amount باید عددی باشد"; + break; + case -5: + Message = "amount باید بین 100 تا 50,000,000 تومان باشد"; + break; + case -6: + Message = "کد پین درگاه اشتباه هست"; + break; + case -7: + Message = "transid نمی تواند خالی باشد"; + break; + case -8: + Message = "تراکنش مورد نظر وجود ندارد"; + break; + case -9: + Message = "کد پین درگاه با درگاه تراکنش مطابقت ندارد"; + break; + case -10: + Message = "مبلغ با مبلغ تراکنش مطابقت ندارد"; + break; + case -11: + Message = "درگاه درانتظار تایید و یا غیر فعال است"; + break; + case -12: + Message = "امکان ارسال درخواست برای این پذیرنده وجود ندارد"; + break; + case -13: + Message = "شماره کارت باید 16 رقم چسبیده بهم باشد"; + break; + default: + Message = "خطای نامشخص"; + break; + } + } + + public class TokenResponse + { + [JsonPropertyName("status")] + public string? Status { get; set; } + + [JsonPropertyName("code")] + public int? ErrorCode { get; set; } + + [JsonPropertyName("transid")] + public string? TransactionId { get; set; } + } + } } diff --git a/ServiceHost/Properties/launchSettings.json b/ServiceHost/Properties/launchSettings.json index 788962e4..1a8464a4 100644 --- a/ServiceHost/Properties/launchSettings.json +++ b/ServiceHost/Properties/launchSettings.json @@ -19,7 +19,7 @@ "sqlDebugging": true, "dotnetRunMessages": "true", "nativeDebugging": true, - "applicationUrl": "https://localhost:5004;http://localhost:5003;", + "applicationUrl": "https://localhost:5004;http://localhost:5003;http://192.168.0.102:82;https://192.168.0.102:83", "jsWebView2Debugging": false, "hotReloadEnabled": true },