Added create order and verify payment API for razor pay
This commit is contained in:
parent
c6744f0556
commit
1d54af7c00
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MongoDB.Driver" Version="3.0.0" />
|
<PackageReference Include="MongoDB.Driver" Version="3.0.0" />
|
||||||
|
<PackageReference Include="Razorpay" Version="3.3.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
7
Marco.Pms.Model/Dtos/PaymentGetway/CreateOrderDto.cs
Normal file
7
Marco.Pms.Model/Dtos/PaymentGetway/CreateOrderDto.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Marco.Pms.Model.Dtos.PaymentGetway
|
||||||
|
{
|
||||||
|
public class CreateOrderDto
|
||||||
|
{
|
||||||
|
public double Amount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
namespace Marco.Pms.Model.Dtos.PaymentGetway
|
||||||
|
{
|
||||||
|
public class PaymentVerificationRequest
|
||||||
|
{
|
||||||
|
public string? OrderId { get; set; }
|
||||||
|
public string? PaymentId { get; set; }
|
||||||
|
public string? Signature { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace Marco.Pms.Model.ViewModels.PaymentGetway
|
||||||
|
{
|
||||||
|
public class CreateOrderVM
|
||||||
|
{
|
||||||
|
public string? OrderId { get; set; }
|
||||||
|
public string? Key { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
71
Marco.Pms.Services/Controllers/PaymentController.cs
Normal file
71
Marco.Pms.Services/Controllers/PaymentController.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using Marco.Pms.Model.Dtos.PaymentGetway;
|
||||||
|
using Marco.Pms.Model.Utilities;
|
||||||
|
using Marco.Pms.Services.Helpers;
|
||||||
|
using MarcoBMS.Services.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Services.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class PaymentController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly UserHelper _userHelper;
|
||||||
|
private readonly PaymentHelper _paymentHelper;
|
||||||
|
private readonly Guid tenantId;
|
||||||
|
private readonly Guid organizaionId;
|
||||||
|
public PaymentController(UserHelper userHelper, PaymentHelper paymentHelper)
|
||||||
|
{
|
||||||
|
_userHelper = userHelper;
|
||||||
|
_paymentHelper = paymentHelper;
|
||||||
|
tenantId = userHelper.GetTenantId();
|
||||||
|
organizaionId = userHelper.GetCurrentOrganizationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("create-order")]
|
||||||
|
public async Task<IActionResult> CreateOrder([FromBody] CreateOrderDto model)
|
||||||
|
{
|
||||||
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = _paymentHelper.CreateOrder(model.Amount, loggedInEmployee, tenantId);
|
||||||
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Payment created successfully", 200));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("Error occured While creating the payment", new
|
||||||
|
{
|
||||||
|
Message = ex.Message,
|
||||||
|
StackTrace = ex.StackTrace,
|
||||||
|
Source = ex.Source,
|
||||||
|
InnerException = new
|
||||||
|
{
|
||||||
|
Message = ex.InnerException?.Message,
|
||||||
|
StackTrace = ex.InnerException?.StackTrace,
|
||||||
|
Source = ex.InnerException?.Source,
|
||||||
|
}
|
||||||
|
}, 500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("verify-payment")]
|
||||||
|
public IActionResult VerifyPayment([FromBody] PaymentVerificationRequest request)
|
||||||
|
{
|
||||||
|
string payload = request.OrderId + "|" + request.PaymentId;
|
||||||
|
string actualSignature = request.Signature ?? "";
|
||||||
|
string expectedSignature = _paymentHelper.GetExpectedSignature(payload);
|
||||||
|
|
||||||
|
if (actualSignature == expectedSignature)
|
||||||
|
{
|
||||||
|
// Payment is verified, process accordingly e.g. update tenant payment details
|
||||||
|
return Ok(new { status = "success" });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest(new { status = "failure", message = "Invalid signature" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
57
Marco.Pms.Services/Helpers/PaymentHelper.cs
Normal file
57
Marco.Pms.Services/Helpers/PaymentHelper.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using Marco.Pms.Model.Employees;
|
||||||
|
using Marco.Pms.Model.ViewModels.PaymentGetway;
|
||||||
|
using Razorpay.Api;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Services.Helpers
|
||||||
|
{
|
||||||
|
public class PaymentHelper
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly string key = "YOUR_RAZORPAY_KEY";
|
||||||
|
private readonly string secret = "YOUR_RAZORPAY_SECRET";
|
||||||
|
public PaymentHelper(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
key = configuration["Razorpay:Key"] ?? "";
|
||||||
|
secret = configuration["Razorpay:Secret"] ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateOrderVM CreateOrder(double amount, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
RazorpayClient client = new RazorpayClient(key, secret);
|
||||||
|
|
||||||
|
var receipt = $"rec_{Guid.NewGuid()}";
|
||||||
|
var length = receipt.Length;
|
||||||
|
|
||||||
|
Dictionary<string, object> options = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "amount", amount * 100 }, // amount in paise
|
||||||
|
{ "currency", "INR" },
|
||||||
|
{ "receipt", receipt},
|
||||||
|
{ "payment_capture", 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
Order order = client.Order.Create(options);
|
||||||
|
var response = new CreateOrderVM
|
||||||
|
{
|
||||||
|
OrderId = order["id"],
|
||||||
|
Key = key
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetExpectedSignature(string payload)
|
||||||
|
{
|
||||||
|
string expectedSignature;
|
||||||
|
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
|
||||||
|
{
|
||||||
|
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
|
||||||
|
expectedSignature = Convert.ToHexString(hash).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
return expectedSignature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,6 +34,7 @@
|
|||||||
<PackageReference Include="Mime-Detective" Version="24.12.2" />
|
<PackageReference Include="Mime-Detective" Version="24.12.2" />
|
||||||
<PackageReference Include="Mime-Detective.Definitions.Exhaustive" Version="24.12.2" />
|
<PackageReference Include="Mime-Detective.Definitions.Exhaustive" Version="24.12.2" />
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||||
|
<PackageReference Include="Razorpay" Version="3.3.2" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
|
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using Marco.Pms.CacheHelper;
|
|
||||||
using FirebaseAdmin;
|
using FirebaseAdmin;
|
||||||
using Google.Apis.Auth.OAuth2;
|
using Google.Apis.Auth.OAuth2;
|
||||||
|
using Marco.Pms.CacheHelper;
|
||||||
using Marco.Pms.DataAccess.Data;
|
using Marco.Pms.DataAccess.Data;
|
||||||
using Marco.Pms.Helpers;
|
using Marco.Pms.Helpers;
|
||||||
using Marco.Pms.Helpers.CacheHelper;
|
using Marco.Pms.Helpers.CacheHelper;
|
||||||
@ -55,7 +55,7 @@ builder.Services.AddCors(options =>
|
|||||||
policy.AllowAnyOrigin()
|
policy.AllowAnyOrigin()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader()
|
.AllowAnyHeader()
|
||||||
.WithExposedHeaders("Authorization");
|
.WithExposedHeaders("Authorization", "X-Request-ID", "X-Correlation-ID");
|
||||||
});
|
});
|
||||||
|
|
||||||
// A stricter policy for production (loaded from config)
|
// A stricter policy for production (loaded from config)
|
||||||
@ -65,7 +65,8 @@ builder.Services.AddCors(options =>
|
|||||||
{
|
{
|
||||||
policy.WithOrigins(allowedOrigins)
|
policy.WithOrigins(allowedOrigins)
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader();
|
.AllowAnyHeader()
|
||||||
|
.WithExposedHeaders("Authorization", "X-Request-ID", "X-Correlation-ID");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
#endregion
|
#endregion
|
||||||
@ -190,6 +191,7 @@ builder.Services.AddScoped<UserHelper>();
|
|||||||
builder.Services.AddScoped<RolesHelper>();
|
builder.Services.AddScoped<RolesHelper>();
|
||||||
builder.Services.AddScoped<EmployeeHelper>();
|
builder.Services.AddScoped<EmployeeHelper>();
|
||||||
builder.Services.AddScoped<ReportHelper>();
|
builder.Services.AddScoped<ReportHelper>();
|
||||||
|
builder.Services.AddScoped<PaymentHelper>();
|
||||||
builder.Services.AddScoped<CacheUpdateHelper>();
|
builder.Services.AddScoped<CacheUpdateHelper>();
|
||||||
builder.Services.AddScoped<FeatureDetailsHelper>();
|
builder.Services.AddScoped<FeatureDetailsHelper>();
|
||||||
builder.Services.AddScoped<UtilityMongoDBHelper>();
|
builder.Services.AddScoped<UtilityMongoDBHelper>();
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
"Title": "Dev"
|
"Title": "Dev"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1"
|
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMSStage"
|
||||||
},
|
},
|
||||||
"SmtpSettings": {
|
"SmtpSettings": {
|
||||||
"SmtpServer": "smtp.gmail.com",
|
"SmtpServer": "smtp.gmail.com",
|
||||||
@ -50,5 +50,9 @@
|
|||||||
"SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs",
|
"SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs",
|
||||||
"ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches?socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500",
|
"ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches?socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500",
|
||||||
"ModificationConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/MarcoBMSLocalDev?authSource=admin&eplicaSet=rs01&directConnection=true"
|
"ModificationConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/MarcoBMSLocalDev?authSource=admin&eplicaSet=rs01&directConnection=true"
|
||||||
|
},
|
||||||
|
"Razorpay": {
|
||||||
|
"Key": "rzp_test_RXCzgEcXucbuAi",
|
||||||
|
"Secret": "YNAVBXxRsDg8Oat4M1C3m09W"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user