Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Faradadeh co committed Feb 24, 2022
1 parent 4fcfb73 commit e4b97f7
Show file tree
Hide file tree
Showing 79 changed files with 74,608 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[*.cs]

# CS8602: Dereference of a possibly null reference.
dotnet_diagnostic.CS8602.severity = none

# CS1998: Async method lacks 'await' operators and will run synchronously
dotnet_diagnostic.CS1998.severity = none
30 changes: 30 additions & 0 deletions Sadad.Psp.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32203.90
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sadad.Psp", "Sadad.Psp\Sadad.Psp.csproj", "{CA41BEB7-CCE7-4E01-8B6C-F809E96DEC44}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A223B988-F524-464C-80AA-A1D2F6EC2AC9}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CA41BEB7-CCE7-4E01-8B6C-F809E96DEC44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA41BEB7-CCE7-4E01-8B6C-F809E96DEC44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA41BEB7-CCE7-4E01-8B6C-F809E96DEC44}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA41BEB7-CCE7-4E01-8B6C-F809E96DEC44}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71AEA4CC-E170-4168-B649-366E319F7588}
EndGlobalSection
EndGlobal
223 changes: 223 additions & 0 deletions Sadad.Psp/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
using Microsoft.AspNetCore.Mvc;
using Sadad.Psp.Models;
using System.Diagnostics;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace Sadad.Psp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IConfiguration _config;

public HomeController(ILogger<HomeController> logger, IConfiguration config)
{
_logger = logger;
_config = config;
}

public IActionResult Index()
{
return View();
}

[HttpPost]
public async Task<IActionResult> Index(PaymentRequest request)
{
// فایل
// appsettings.json
// یا
// appsettings.Development.json
// ویرایش شود
var TerminalId = _config["terminalId"];
var TerminalKey = _config["terminalKey"];
var MerchantId = _config["merchantId"];
var ReturnUrl = _config["returnUrl"];
var PurchasePage = _config["purchasePage"];

if (!ModelState.IsValid)
return View(request);
try
{
var OrderId = new Random().Next(1000, int.MaxValue).ToString(); // شماره فاکتور - نباید تکراری باشد

// رمزنگاری TripleDes
string SignData = TripleDes($"{TerminalId};{OrderId};{request.Amount}", TerminalKey);

var data = new
{
TerminalId,
MerchantId,
request.Amount,
SignData,
ReturnUrl,
LocalDateTime = DateTime.Now,
OrderId,
};

var ipgUri = string.Format("{0}/api/v0/Request/PaymentRequest", PurchasePage);

// درخواست توکن به سرور
var res = await CallApi<PayResultData>(ipgUri, data);

if (res != null)
{
if (res.ResCode == "0")
{
// ذخیره
// res.Token
// در پایگاه داده

Response.Redirect(string.Format("{0}/Purchase/Index?token={1}", PurchasePage, res.Token));
}
ViewBag.Message = res.Description;
return View();
}
}
catch (Exception ex)
{
ViewBag.Message = ex.ToString();
}
return View();
}

/// <summary>
/// تایید تراکنش بعد از پرداخت، مستقیم توسط درگاه صدا زده می شود این متد.
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Verify(PurchaseResult result)
{
// مقایسه و اعتبار سنجی توکن و شماره فاکتور در پایگاه داده
// result.Token
// result.OrderId
// در صورت مجاز ادامه میدهیم

// چک کردن مقدار زیر در صورت 0 بودن ادامه خواهیم داد
// result.ResCode

try
{
// فایل
// appsettings.json
// یا
// appsettings.Development.json
// ویرایش شود
var TerminalId = _config["terminalId"];
var TerminalKey = _config["terminalKey"];
var MerchantId = _config["merchantId"];
var ReturnUrl = _config["returnUrl"];
var PurchasePage = _config["purchasePage"];

// رمزنگاری TripleDes
var signedData = TripleDes(result.Token ?? "", TerminalKey);

var data = new
{
token = result.Token,
SignData = signedData
};

var ipgUri = string.Format("{0}/api/v0/Advice/Verify", PurchasePage);

// بررسی صحت اطلاعات دریافتی با درگاه
var res = CallApi<VerifyResultData>(ipgUri, data);
if (res != null && res.Result != null)
{
if (res.Result.ResCode == "0")
{
// مقایسه اطلاعات دریافتی با پایگاه داده

// ذخیره اطلاعات در پایگاه داده
res.Result.Succeed = true;
return View(res.Result);
}
ViewBag.Message = res.Result.Description;
return View(res.Result);
}
}
catch (Exception ex)
{
ViewBag.Message = ex.ToString();
}

return View(new VerifyResultData());
}

public IActionResult Privacy()
{
return View();
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

private static async Task<T?> CallApi<T>(string apiUrl, object value)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
using var client = new HttpClient();
client.BaseAddress = new Uri(apiUrl);
client.DefaultRequestHeaders.Accept.Clear();
var w = client.PostAsJsonAsync(apiUrl, value);
w.Wait();
HttpResponseMessage response = w.Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadFromJsonAsync<T>();
result.Wait();
return result.Result;
}
return default;
}

private static string TripleDes(string data, string TerminalKey)
{
var dataBytes = Encoding.UTF8.GetBytes(data);

var symmetric = SymmetricAlgorithm.Create("TripleDes");
symmetric.Mode = CipherMode.ECB;
symmetric.Padding = PaddingMode.PKCS7;

var encryptor = symmetric.CreateEncryptor(Convert.FromBase64String(TerminalKey), new byte[32]);

var SignData = Convert.ToBase64String(encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length));
return SignData;
}

public class PaymentRequest
{
public long Amount { get; set; } = 1000;
}

public class PayResultData
{
public string? ResCode { get; set; }
public string? Token { get; set; }
public string? Description { get; set; }
}

public class PurchaseResult
{
public string? OrderId { get; set; }
public string? Token { get; set; }
public string? ResCode { get; set; }
}

public class VerifyResultData
{
public bool Succeed { get; set; }
public string? ResCode { get; set; }
public string? Description { get; set; }
public string? Amount { get; set; }
public string? RetrivalRefNo { get; set; }
public string? SystemTraceNo { get; set; }
public string? OrderId { get; set; }
}
}
}
9 changes: 9 additions & 0 deletions Sadad.Psp/Models/ErrorViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Sadad.Psp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
23 changes: 23 additions & 0 deletions Sadad.Psp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
28 changes: 28 additions & 0 deletions Sadad.Psp/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20582",
"sslPort": 0
}
},
"profiles": {
"Sadad.Psp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5090",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
13 changes: 13 additions & 0 deletions Sadad.Psp/Sadad.Psp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions Sadad.Psp/Sadad.Psp.csproj.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<View_SelectedScaffolderID>RazorViewEmptyScaffolder</View_SelectedScaffolderID>
<View_SelectedScaffolderCategoryPath>root/Common/MVC/View</View_SelectedScaffolderCategoryPath>
</PropertyGroup>
</Project>
23 changes: 23 additions & 0 deletions Sadad.Psp/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@{
ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<br /><br /><br />
<form action="/Home/Index" method="post" class="row g-3">
<div class="col-md-6">
<label for="inputEmail4" class="form-label">مبلغ: </label>
<input name="Amount" class="form-control" value="10000" type="number" />
<br />
<button class="btn btn-primary" type="submit">ارسال</button>
<br />
<br />
<div class="alert alert-primary" role="alert">
@ViewBag.Message
</div>
</div>
</form>
<br /><br /><br />
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
6 changes: 6 additions & 0 deletions Sadad.Psp/Views/Home/Privacy.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
Loading

0 comments on commit e4b97f7

Please sign in to comment.