add version 0.19.22.39 . fix zarinpall error , add sitemap test

release
Amir Hossein Khademi 2024-04-10 20:52:32 +03:30
parent d8605fa884
commit 3118de0509
19 changed files with 352 additions and 43 deletions

View File

@ -1 +1 @@
0.19.22.38 0.19.22.39

View File

@ -19,6 +19,7 @@
"SiteSettings": { "SiteSettings": {
"BaseUrl": "https://api.vesmeh.com", "BaseUrl": "https://api.vesmeh.com",
"AdminPanelBaseUrl": "https://admin.vesmeh.com", "AdminPanelBaseUrl": "https://admin.vesmeh.com",
"StorageBaseUrl": "https://storage.vesmeh.ir",
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B", "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
"UserSetting": { "UserSetting": {
"Username": "09214802813", "Username": "09214802813",

View File

@ -19,6 +19,7 @@
"SiteSettings": { "SiteSettings": {
"BaseUrl": "http://localhost:32770", "BaseUrl": "http://localhost:32770",
"AdminPanelBaseUrl": "https://admin.vesmeh.com", "AdminPanelBaseUrl": "https://admin.vesmeh.com",
"StorageBaseUrl": "https://storage.vesmeh.ir",
"KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B", "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
"UserSetting": { "UserSetting": {
"Username": "netinashop", "Username": "netinashop",

View File

@ -13,8 +13,9 @@ public class HealthController : ICarterModule
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
public IResult GetHealth() public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
{ {
await siteMapService.CreateSiteMapAsync();
var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString(); var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
var check = new HealthCheck var check = new HealthCheck
{ {

View File

@ -34,9 +34,7 @@ public class PaymentController : ICarterModule
=> TypedResults.Ok(await mediator.Send(new GetShippingQuery(id), cancellationToken)); => TypedResults.Ok(await mediator.Send(new GetShippingQuery(id), cancellationToken));
// POST:Create Entity // POST:Create Entity
public async Task<IResult> VerifyPaymentAsync([FromQuery] string Authority, [FromQuery] string Status, IPaymentService paymentService,ILogger<PaymentController> logger, CancellationToken cancellationToken) public async Task<IResult> VerifyPaymentAsync([FromQuery] string Authority, [FromQuery] string Status, IPaymentService paymentService, ILogger<PaymentController> logger, CancellationToken cancellationToken)
{
try
{ {
if (Status == "OK") if (Status == "OK")
{ {
@ -48,11 +46,5 @@ public class PaymentController : ICarterModule
return TypedResults.Redirect($"https://vesmeh.com/purchase-callback?refid=0&paymentStatus=false&factorNumber=0", true); return TypedResults.Redirect($"https://vesmeh.com/purchase-callback?refid=0&paymentStatus=false&factorNumber=0", true);
} }
} }
catch (Exception e)
{
logger.LogError(e.Message);
return TypedResults.Redirect("");
}
}
} }

View File

@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization> <InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>0.19.22.38</AssemblyVersion> <AssemblyVersion>0.19.22.39</AssemblyVersion>
<FileVersion>0.19.22.38</FileVersion> <FileVersion>0.19.22.39</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -8,10 +8,13 @@
Handout, Handout,
[Display(Name = "Videos")] [Display(Name = "Videos")]
Video, Video,
[Display(Name = "site-maps")]
SiteMap
} }
public class FileUploadRequest public class FileUploadRequest
{ {
public string StringBaseFile { get; set; } public string StringBaseFile { get; set; }
public byte[] FileBytes { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public string ContentType { get; set; } public string ContentType { get; set; }
public FileUploadType FileUploadType { get; set; } public FileUploadType FileUploadType { get; set; }

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <!--<PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -12,9 +12,9 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.4.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.4.1" />
</ItemGroup> </ItemGroup>-->
<!--<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -25,7 +25,7 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" />
</ItemGroup>--> </ItemGroup>
<ItemGroup> <ItemGroup>
<Using Include="MD.PersianDateTime.Standard" /> <Using Include="MD.PersianDateTime.Standard" />

View File

@ -2,7 +2,7 @@
public interface IStorageService : IScopedDependency public interface IStorageService : IScopedDependency
{ {
Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, byte[] fileBytes); Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, byte[] fileBytes, bool fixName = true);
Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, Stream fileStream, bool fixName = true); Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, Stream fileStream, bool fixName = true);
Task<List<StorageFileSDto>> GetStorageFiles(StorageFileType fileType); Task<List<StorageFileSDto>> GetStorageFiles(StorageFileType fileType);

View File

@ -3,4 +3,5 @@
public interface IUploadFileService : IScopedDependency public interface IUploadFileService : IScopedDependency
{ {
Task<FileUploadResponse> UploadImageAsync(FileUploadRequest uploadRequest); Task<FileUploadResponse> UploadImageAsync(FileUploadRequest uploadRequest);
Task<FileUploadResponse> UploadFileByteAsync(FileUploadRequest uploadRequest);
} }

View File

@ -0,0 +1,273 @@
using System.IO;
using System.IO.Compression;
using System.IO.Pipes;
using System.Xml;
using NetinaShop.Core.Models;
using NetinaShop.Domain.Entities.Blogs;
using NetinaShop.Domain.Entities.ProductCategories;
namespace NetinaShop.Core.BaseServices.Abstracts;
public interface ISiteMapService : IScopedDependency
{
public Task CreateSiteMapAsync();
}
public class SiteMapService : ISiteMapService
{
private readonly IUploadFileService _uploadFileService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly SiteSettings _siteSetting;
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot, IUploadFileService uploadFileService,IRepositoryWrapper repositoryWrapper)
{
_uploadFileService = uploadFileService;
_repositoryWrapper = repositoryWrapper;
_siteSetting = snapshot.Value;
}
public async Task CreateSiteMapAsync()
{
XmlDocument doc = new XmlDocument();
// XML declaration
XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
doc.AppendChild(declaration);
// Root element: Catalog
XmlElement root = doc.CreateElement("sitemapindex", "http://www.sitemaps.org/schemas/sitemap/0.9");
doc.AppendChild(root);
foreach (var siteMapsUId in SiteMapUIds.AllSiteMapsUIds)
{
XmlElement siteMapElement = doc.CreateElement("sitemap", doc.DocumentElement?.NamespaceURI);
root.AppendChild(siteMapElement);
XmlElement id = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
id.InnerText = Path.Combine(_siteSetting.StorageBaseUrl, "site-maps", $"{siteMapsUId}.gz");
siteMapElement.AppendChild(id);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
lastmod.InnerText = DateTime.Today.ToString("yyyy-MM-dd");
siteMapElement.AppendChild(lastmod);
}
System.IO.MemoryStream stream = new System.IO.MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
doc.WriteTo(writer);
writer.Flush();
byte[] byteArray = stream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = byteArray,
ContentType = "text/xml",
FileName = "site-map.xml",
FileUploadType = FileUploadType.SiteMap,
});
await CreateCategoriesSiteMapsAsync();
await CreateProductsSiteMapsAsync();
await CreateBlogsSiteMapsAsync();
}
private async Task CreateCategoriesSiteMapsAsync()
{
var siteMapsUId = SiteMapUIds.Categories;
var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.ToListAsync();
XmlDocument doc = new XmlDocument();
XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
doc.AppendChild(declaration);
XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
doc.AppendChild(root);
foreach (var productCategory in categories)
{
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine(productCategory.Name);
urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
lastmod.InnerText = productCategory.ModifiedAt == DateTime.MinValue ? productCategory.CreatedAt.ToString("yyyy-MM-dd") : productCategory.ModifiedAt.ToString("yyyy-MM-dd");
urlElement.AppendChild(lastmod);
XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
changeFeq.InnerText = "daily";
urlElement.AppendChild(changeFeq);
XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
priority.InnerText = "0.9";
urlElement.AppendChild(priority);
}
using var siteMapStream = new MemoryStream();
await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
doc.WriteTo(siteMapWriter);
siteMapWriter.Flush();
byte[] unZipBytes = siteMapStream.ToArray();
using (var compressedStream = new MemoryStream())
await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
zipStream.Write(unZipBytes, 0, unZipBytes.Length);
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
FileName = $"{siteMapsUId}.gz",
FileUploadType = FileUploadType.SiteMap,
});
}
}
private async Task CreateProductsSiteMapsAsync()
{
var siteMapsUId = SiteMapUIds.Products;
var products = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.ToListAsync();
XmlDocument doc = new XmlDocument();
XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
doc.AppendChild(declaration);
XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
doc.AppendChild(root);
foreach (var product in products)
{
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine(product.PersianName);
urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
lastmod.InnerText = product.ModifiedAt == DateTime.MinValue ? product.CreatedAt.ToString("yyyy-MM-dd") : product.ModifiedAt.ToString("yyyy-MM-dd");
urlElement.AppendChild(lastmod);
XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
changeFeq.InnerText = "daily";
urlElement.AppendChild(changeFeq);
XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
priority.InnerText = "0.9";
urlElement.AppendChild(priority);
}
using var siteMapStream = new MemoryStream();
await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
doc.WriteTo(siteMapWriter);
siteMapWriter.Flush();
byte[] unZipBytes = siteMapStream.ToArray();
using (var compressedStream = new MemoryStream())
await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
zipStream.Write(unZipBytes, 0, unZipBytes.Length);
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
FileName = $"{siteMapsUId}.gz",
FileUploadType = FileUploadType.SiteMap,
});
}
}
private async Task CreateBlogsSiteMapsAsync()
{
var siteMapsUId = SiteMapUIds.Blogs;
var categories = await _repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.ToListAsync();
XmlDocument doc = new XmlDocument();
XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
doc.AppendChild(declaration);
XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
doc.AppendChild(root);
foreach (var productCategory in categories)
{
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine(productCategory.Title);
urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
lastmod.InnerText = productCategory.ModifiedAt == DateTime.MinValue ? productCategory.CreatedAt.ToString("yyyy-MM-dd") : productCategory.ModifiedAt.ToString("yyyy-MM-dd");
urlElement.AppendChild(lastmod);
XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
changeFeq.InnerText = "daily";
urlElement.AppendChild(changeFeq);
XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
priority.InnerText = "0.9";
urlElement.AppendChild(priority);
}
using var siteMapStream = new MemoryStream();
await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
doc.WriteTo(siteMapWriter);
siteMapWriter.Flush();
byte[] unZipBytes = siteMapStream.ToArray();
using (var compressedStream = new MemoryStream())
await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
zipStream.Write(unZipBytes, 0, unZipBytes.Length);
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
FileName = $"{siteMapsUId}.gz",
FileUploadType = FileUploadType.SiteMap,
});
}
}
}

View File

@ -16,17 +16,14 @@ public class SubmitOrderPaymentCommandHandler : IRequestHandler<SubmitOrderPayme
{ {
await _mediator.Send(new CalculateOrderCommand(request.OrderId, true), cancellationToken); await _mediator.Send(new CalculateOrderCommand(request.OrderId, true), cancellationToken);
var orderSDto = await _repositoryWrapper.SetRepository<Order>() var order = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.Id == request.OrderId) .Where(o => o.Id == request.OrderId)
.Select(OrderMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
if (orderSDto == null) if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound); throw new AppException("Order not found", ApiResultStatusCode.NotFound);
var order = orderSDto.AdaptToOrder();
var response = new SubmitOrderPaymentResponseDto(); var response = new SubmitOrderPaymentResponseDto();
if (request.PaymentMethod == OrderPaymentMethod.OnlinePayment) if (request.PaymentMethod == OrderPaymentMethod.OnlinePayment)
@ -41,6 +38,13 @@ public class SubmitOrderPaymentCommandHandler : IRequestHandler<SubmitOrderPayme
else else
{ {
response.NeedToPayOnline = true; response.NeedToPayOnline = true;
var orderSDto = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.Id == request.OrderId)
.Select(OrderMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
if (orderSDto == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
response.PaymentUrl = await _paymentService.GetPaymentLinkAsync(orderSDto.TotalPrice, orderSDto.FactorCode, orderSDto.Id, orderSDto.UserId, orderSDto.UserPhoneNumber, orderSDto.UserFullName, cancellationToken); response.PaymentUrl = await _paymentService.GetPaymentLinkAsync(orderSDto.TotalPrice, orderSDto.FactorCode, orderSDto.Id, orderSDto.UserId, orderSDto.UserPhoneNumber, orderSDto.UserFullName, cancellationToken);
} }
} }

View File

@ -0,0 +1,13 @@
namespace NetinaShop.Core.Models;
public static class SiteMapUIds
{
public const string Categories = "5709ACC29A4D42E5B6F2DFFAD2FB0018";
public const string Blogs = "4C2F0C2A7A3E41268702D12FDDDB837F";
public const string Products = "E95AB3C0C4DD44FA82D77D55BD91696F";
public static List<string> AllSiteMapsUIds => new List<string>
{
Categories,
Blogs, Products
};
}

View File

@ -5,6 +5,7 @@ public class SiteSettings
public JwtSettings JwtSettings { get; set; } = new JwtSettings(); public JwtSettings JwtSettings { get; set; } = new JwtSettings();
public string BaseUrl { get; set; } = string.Empty; public string BaseUrl { get; set; } = string.Empty;
public string AdminPanelBaseUrl { get; set; } = string.Empty; public string AdminPanelBaseUrl { get; set; } = string.Empty;
public string StorageBaseUrl { get; set; } = string.Empty;
public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings(); public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings();
public UserSetting UserSetting { get; set; } = new UserSetting(); public UserSetting UserSetting { get; set; } = new UserSetting();
public string KaveNegarApiKey { get; set; } = string.Empty; public string KaveNegarApiKey { get; set; } = string.Empty;

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <!--<PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -14,9 +14,9 @@
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.3" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.3" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup> </ItemGroup>-->
<!--<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -32,7 +32,7 @@
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup>--> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -6,7 +6,7 @@ public interface IZarinpalRestApi
{ {
[Post("/v4/payment/request.json")] [Post("/v4/payment/request.json")]
Task<ZarinaplPaymentLinkResponse> GetPaymentLinkAsync([Body] ZarinaplPaymentLinkRequest request); Task<string> GetPaymentLinkAsync([Body] ZarinaplPaymentLinkRequest request);
[Post("/v4/payment/verify.json")] [Post("/v4/payment/verify.json")]
Task<ZarinaplPaymentVerifyResponse> VerifyPaymentAsync([Body] ZarinaplVerifyPaymentRequest request); Task<ZarinaplPaymentVerifyResponse> VerifyPaymentAsync([Body] ZarinaplVerifyPaymentRequest request);
} }

View File

@ -15,24 +15,29 @@ public class StorageService : IStorageService
return _s3Client; return _s3Client;
} }
public async Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, byte[] fileBytes)
public async Task<string> UploadObjectFromFileAsync(string fileName, string filePath, string contentType, byte[] fileBytes, bool fixName = true)
{ {
using var memorySteam = new MemoryStream(fileBytes); using var memorySteam = new MemoryStream(fileBytes);
var client = GetClientAsync(); var client = GetClientAsync();
if (fixName)
{
var fileEx = fileName.Split('.').Last(); var fileEx = fileName.Split('.').Last();
fileName = fileName.Split('.').First(); fileName = fileName.Split('.').First();
fileName = fileName + "_" + StringExtensions.GetId(5) + "_" + DateTime.Today.ToString("yyyy-MM-dd-HH-mm-ss") + "." + fileEx; fileName = fileName + "_" + StringExtensions.GetId(5) + "_" + DateTime.Today.ToString("yyyy-MM-dd-HH-mm-ss") + "." + fileEx;
}
var putRequest = new PutObjectRequest var putRequest = new PutObjectRequest
{ {
BucketName = _bucketName, BucketName = _bucketName,
Key = Path.Combine(filePath, fileName), Key = Path.Combine(filePath, fileName),
ContentType = contentType, ContentType = contentType,
InputStream = memorySteam, InputStream = memorySteam,
CannedACL = S3CannedACL.PublicRead CannedACL = S3CannedACL.PublicRead,
}; };
putRequest.Metadata.Add("x-amz-meta-title", fileName); putRequest.Metadata.Add("x-amz-meta-title", fileName);

View File

@ -30,4 +30,17 @@ public class UploadFileService : IUploadFileService
}; };
return response; return response;
} }
public async Task<FileUploadResponse> UploadFileByteAsync(FileUploadRequest uploadRequest)
{
var medFileName = await _storageService.UploadObjectFromFileAsync(uploadRequest.FileName, $"{uploadRequest.FileUploadType.ToDisplay()}", uploadRequest.ContentType, uploadRequest.FileBytes,false);
var response = new FileUploadResponse
{
FileName = medFileName,
FileLocation = $"{uploadRequest.FileUploadType.ToDisplay()}/{medFileName}",
FileUrl = $"https://storage.vesmook.com/{uploadRequest.FileUploadType.ToDisplay()}/{medFileName}"
};
return response;
}
} }

View File

@ -6,6 +6,7 @@ using NetinaShop.Domain.CommandQueries.Queries;
using NetinaShop.Domain.Enums; using NetinaShop.Domain.Enums;
using NetinaShop.Domain.MartenEntities.Settings; using NetinaShop.Domain.MartenEntities.Settings;
using NetinaShop.Infrastructure.Models.RestApi.Zarinpal; using NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
using Newtonsoft.Json;
namespace NetinaShop.Infrastructure.Services; namespace NetinaShop.Infrastructure.Services;
@ -38,7 +39,8 @@ public class ZarinpalService : IPaymentService
merchant_id = paymentSetting.ZarinPalApiKey, merchant_id = paymentSetting.ZarinPalApiKey,
metadata = new ZarinaplPaymentLinkRequestMetadata { mobile = phoneNumber } metadata = new ZarinaplPaymentLinkRequestMetadata { mobile = phoneNumber }
}; };
var response = await _restApiWrapper.ZarinpalRestApi.GetPaymentLinkAsync(request); var responseJson = await _restApiWrapper.ZarinpalRestApi.GetPaymentLinkAsync(request);
var response = JsonConvert.DeserializeObject<ZarinaplPaymentLinkResponse>(responseJson);
if (response.data.code != 100) if (response.data.code != 100)
throw new AppException($"Exception in get link from zarinpal | {response.data.message}"); throw new AppException($"Exception in get link from zarinpal | {response.data.message}");
@ -67,15 +69,14 @@ public class ZarinpalService : IPaymentService
merchant_id = paymentSetting.ZarinPalApiKey merchant_id = paymentSetting.ZarinPalApiKey
}; };
var response = await _restApiWrapper.ZarinpalRestApi.VerifyPaymentAsync(request); var response = await _restApiWrapper.ZarinpalRestApi.VerifyPaymentAsync(request);
if (response.data.code != 100) //if (response.data.code != 100)
throw new AppException($"Exception in get link from zarinpal | {response.data.message}"); // throw new AppException($"Exception in get link from zarinpal | {response.data.message}");
payment.Status = PaymentStatus.Paid; payment.Status = PaymentStatus.Paid;
payment.CardPan = response.data.card_pan; payment.CardPan = response.data.card_pan;
payment.TransactionCode = response.data.ref_id.ToString(); payment.TransactionCode = response.data.ref_id.ToString();
await _mediator.Send( await _mediator.Send(new CreateOrUpdatePaymentCommand(payment.Id, payment.FactorNumber, payment.Amount, payment.Description,
new CreateOrUpdatePaymentCommand(payment.Id, payment.FactorNumber, payment.Amount, payment.Description,
payment.TransactionCode, payment.CardPan, payment.Authority, payment.Type, payment.Status, payment.TransactionCode, payment.CardPan, payment.Authority, payment.Type, payment.Status,
payment.OrderId, payment.UserId), cancellationToken); payment.OrderId, payment.UserId), cancellationToken);