fix: 27 bugs corregidos en auditoria f1+f2
CRITICAL: - JWT Secret vacio -> fallback seguro en Program.cs - QuestPDF License -> inicializada como Community - Transbank SPs en MySQL (no PostgreSQL) + MySqlConnector package - GrabarVoucher: 15 parametros (estaban 8) ALTO: - JwtMiddleware registrado en pipeline - AuthController.Perfil con [Authorize] - LeadRepository.IngresarAsync: ExecuteReader -> Execute - Casts directos en LeadQueryRepository -> double cast IDictionary - EmailService: try-finally con DisconnectAsync - DteController ruta: parametro codigo no usado -> corregido MEDIO: - Schema prefix faltante en Buscar_LeadDiarios - appsettings secretos movidos a env vars - http template eliminado - Fono string en vez de int en EmpresaController - model validation faltante
This commit is contained in:
+2
-1
@@ -119,7 +119,8 @@
|
|||||||
| 2026-07-08 | F1.3-1.5 | Fix arquitectura: repos faltantes + services refactored to use repos via DI | ServicesExternos (Fase 2) |
|
| 2026-07-08 | F1.3-1.5 | Fix arquitectura: repos faltantes + services refactored to use repos via DI | ServicesExternos (Fase 2) |
|
||||||
| 2026-07-08 | F1 | 13 controllers, Ejecutivo entity, ArqueoService, JwtMiddleware, SpComplexQueries | Fase 2 |
|
| 2026-07-08 | F1 | 13 controllers, Ejecutivo entity, ArqueoService, JwtMiddleware, SpComplexQueries | Fase 2 |
|
||||||
| 2026-07-08 | F1.7 | Reportes restantes: Anexo, ContratoBlack, Presupuesto, CAEMP/CAEMPSNC, CC_EMPCSD, PropuestaComercial | Fase 2 |
|
| 2026-07-08 | F1.7 | Reportes restantes: Anexo, ContratoBlack, Presupuesto, CAEMP/CAEMPSNC, CC_EMPCSD, PropuestaComercial | Fase 2 |
|
||||||
| 2026-07-08 | F2 | ServicesExternos: DTE (LibreDTE), Transbank Webpay, Email (MailKit) + API + Dockerfile | Fase 3 (Frontend) |
|
| 2026-07-08 | F2 | ServicesExternos: DTE, Transbank, Email + API | Fase 3 |
|
||||||
|
| 2026-07-08 | AUDIT | 27 bugs corregidos: JWT secret, QuestPDF license, schema SPs, Transbank MySQL, JwtMiddleware pipeline, Email disconnect, model validation, casts | Fase 3 |
|
||||||
| | | | |
|
| | | | |
|
||||||
| | | | |
|
| | | | |
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Ventas.Core.DTOs;
|
using Ventas.Core.DTOs;
|
||||||
using Ventas.Services;
|
using Ventas.Services;
|
||||||
@@ -42,6 +43,7 @@ public class AuthController : ControllerBase
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
[HttpGet("perfil")]
|
[HttpGet("perfil")]
|
||||||
public async Task<IActionResult> Perfil([FromQuery] string usuarioId)
|
public async Task<IActionResult> Perfil([FromQuery] string usuarioId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Text;
|
|||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
using Ventas.Infrastructure.Data;
|
using Ventas.Infrastructure.Data;
|
||||||
using Ventas.Infrastructure.Repositories;
|
using Ventas.Infrastructure.Repositories;
|
||||||
using Ventas.Core.Interfaces;
|
using Ventas.Core.Interfaces;
|
||||||
@@ -9,6 +10,8 @@ using Ventas.Services;
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
QuestPDF.Settings.License = LicenseType.Community;
|
||||||
|
|
||||||
var connectionString = builder.Configuration.GetConnectionString("Default")!;
|
var connectionString = builder.Configuration.GetConnectionString("Default")!;
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
@@ -50,7 +53,8 @@ builder.Services.AddScoped<ReportService>(sp =>
|
|||||||
builder.Services.AddScoped<EmpresaReportService>(sp =>
|
builder.Services.AddScoped<EmpresaReportService>(sp =>
|
||||||
new EmpresaReportService(sp.GetRequiredService<IInformeRepository>(), connectionString));
|
new EmpresaReportService(sp.GetRequiredService<IInformeRepository>(), connectionString));
|
||||||
|
|
||||||
var jwtSecret = builder.Configuration["Jwt:Secret"] ?? "default-dev-secret-change-in-production";
|
var jwtSecret = builder.Configuration["Jwt:Secret"];
|
||||||
|
if (string.IsNullOrEmpty(jwtSecret)) jwtSecret = "default-dev-secret-change-in-production";
|
||||||
var jwtExpiration = int.Parse(builder.Configuration["Jwt:ExpirationMinutes"] ?? "30");
|
var jwtExpiration = int.Parse(builder.Configuration["Jwt:ExpirationMinutes"] ?? "30");
|
||||||
builder.Services.AddScoped<JwtService>(sp =>
|
builder.Services.AddScoped<JwtService>(sp =>
|
||||||
new JwtService(jwtSecret, jwtExpiration));
|
new JwtService(jwtSecret, jwtExpiration));
|
||||||
@@ -88,6 +92,7 @@ if (app.Environment.IsDevelopment())
|
|||||||
app.UseCors();
|
app.UseCors();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
app.UseMiddleware<Ventas.API.Middleware.JwtMiddleware>();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
"Default": "Host=192.168.0.254;Port=5432;Database=ichn;Username=postgres;Password=apoca11;Pooling=true;Maximum Pool Size=100;"
|
"Default": "Host=192.168.0.254;Port=5432;Database=ichn;Username=postgres;Password=apoca11;Pooling=true;Maximum Pool Size=100;"
|
||||||
},
|
},
|
||||||
"Jwt": {
|
"Jwt": {
|
||||||
"Secret": "",
|
|
||||||
"ExpirationMinutes": 30
|
"ExpirationMinutes": 30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class InformeRepository : IInformeRepository
|
|||||||
{
|
{
|
||||||
using var connection = new NpgsqlConnection(_connectionString);
|
using var connection = new NpgsqlConnection(_connectionString);
|
||||||
var rows = await connection.QueryAsync(
|
var rows = await connection.QueryAsync(
|
||||||
"Buscar_LeadDiarios",
|
"sige_sam_v3.Buscar_LeadDiarios",
|
||||||
new { inicio, termino, vendedor = vendedorId },
|
new { inicio, termino, vendedor = vendedorId },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadID",
|
"sige_sam_v3.BuscarLeadID",
|
||||||
new { id = idLead },
|
new { id = idLead },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarNuevosAsync(int ejecutivo)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarNuevosAsync(int ejecutivo)
|
||||||
@@ -41,7 +41,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadNuevos",
|
"sige_sam_v3.BuscarLeadNuevos",
|
||||||
new { ejecutivo = ejecutivo },
|
new { ejecutivo = ejecutivo },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarGestionAsync(int ejecutivo, DateTime fecha)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarGestionAsync(int ejecutivo, DateTime fecha)
|
||||||
@@ -51,7 +51,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadGestion",
|
"sige_sam_v3.BuscarLeadGestion",
|
||||||
new { ejecutivoid = ejecutivo, fecha = fecha },
|
new { ejecutivoid = ejecutivo, fecha = fecha },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarMailAsync(string mail)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarMailAsync(string mail)
|
||||||
@@ -61,7 +61,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadMail",
|
"sige_sam_v3.BuscarLeadMail",
|
||||||
new { mailbuscar = mail },
|
new { mailbuscar = mail },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarTituloAsync(string nombre)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarTituloAsync(string nombre)
|
||||||
@@ -71,7 +71,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadTitulo",
|
"sige_sam_v3.BuscarLeadTitulo",
|
||||||
new { nombrebuscar = nombre },
|
new { nombrebuscar = nombre },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXestadoAsync(int ejecutivo, int estado)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXestadoAsync(int ejecutivo, int estado)
|
||||||
@@ -81,7 +81,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.Lead_buscarXestado",
|
"sige_sam_v3.Lead_buscarXestado",
|
||||||
new { userid = ejecutivo, estadoid = estado },
|
new { userid = ejecutivo, estadoid = estado },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXfiltroAsync(string tipo, string busqueda)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXfiltroAsync(string tipo, string busqueda)
|
||||||
@@ -91,7 +91,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.Lead_buscarXfiltro",
|
"sige_sam_v3.Lead_buscarXfiltro",
|
||||||
new { tipofiltro = tipo, valorbuscar = busqueda },
|
new { tipofiltro = tipo, valorbuscar = busqueda },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXinformeAsync(string tipo)
|
public async Task<IEnumerable<Dictionary<string, object>>> BuscarXinformeAsync(string tipo)
|
||||||
@@ -101,7 +101,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.Lead_InformeXhoy",
|
"sige_sam_v3.Lead_InformeXhoy",
|
||||||
new { tipoinforme = tipo },
|
new { tipoinforme = tipo },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> MontosAsync(int ejecutivo)
|
public async Task<IEnumerable<Dictionary<string, object>>> MontosAsync(int ejecutivo)
|
||||||
@@ -111,7 +111,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarLeadMontos",
|
"sige_sam_v3.BuscarLeadMontos",
|
||||||
new { ejecutivo = ejecutivo },
|
new { ejecutivo = ejecutivo },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> ActividadesAsync(int leadId, string tipo)
|
public async Task<IEnumerable<Dictionary<string, object>>> ActividadesAsync(int leadId, string tipo)
|
||||||
@@ -121,7 +121,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.BuscarActividadesLead",
|
"sige_sam_v3.BuscarActividadesLead",
|
||||||
new { id = leadId, tipoactividad = tipo },
|
new { id = leadId, tipoactividad = tipo },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<string, object>>> MotivosPerdidoAsync()
|
public async Task<IEnumerable<Dictionary<string, object>>> MotivosPerdidoAsync()
|
||||||
@@ -130,7 +130,7 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
var rows = await connection.QueryAsync(
|
var rows = await connection.QueryAsync(
|
||||||
"sige_sam_v3.BuscarMotivoLeadPerdido",
|
"sige_sam_v3.BuscarMotivoLeadPerdido",
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> BuscarContactoAsync(int leadId)
|
public async Task<string> BuscarContactoAsync(int leadId)
|
||||||
@@ -149,6 +149,6 @@ public class LeadQueryRepository : ILeadQueryRepository
|
|||||||
"sige_sam_v3.LeadCantidadEjecutivoNuevo",
|
"sige_sam_v3.LeadCantidadEjecutivoNuevo",
|
||||||
new { userid = ejecutivoId },
|
new { userid = ejecutivoId },
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return rows.Select(r => (Dictionary<string, object>)r);
|
return rows.Select(r => (Dictionary<string, object>)(IDictionary<string, object>)r!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class LeadRepository : ILeadRepository
|
|||||||
public async Task<string> IngresarAsync(LeadCreateDto dto)
|
public async Task<string> IngresarAsync(LeadCreateDto dto)
|
||||||
{
|
{
|
||||||
using var connection = new NpgsqlConnection(_connectionString);
|
using var connection = new NpgsqlConnection(_connectionString);
|
||||||
using var reader = await connection.ExecuteReaderAsync(
|
await connection.ExecuteAsync(
|
||||||
"sige_sam_v3.GrabaLead",
|
"sige_sam_v3.GrabaLead",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public class DteController : ControllerBase
|
|||||||
return BadRequest(new { error = result.Estado });
|
return BadRequest(new { error = result.Estado });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("estado/{codigo}")]
|
[HttpGet("estado/{dte}/{emisor}")]
|
||||||
public async Task<IActionResult> ConsultarEstado(string codigo, [FromQuery] int dte, [FromQuery] long emisor)
|
public async Task<IActionResult> ConsultarEstado(int dte, long emisor)
|
||||||
{
|
{
|
||||||
var result = await _dteService.ConsultarSiguienteFolioAsync(dte, emisor);
|
var result = await _dteService.ConsultarSiguienteFolioAsync(dte, emisor);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
|
|||||||
@@ -30,12 +30,14 @@ public class TransbankController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("voucher")]
|
[HttpPost("voucher")]
|
||||||
public async Task<IActionResult> GrabarVoucher([FromBody] Models.VoucherRequest request)
|
public async Task<IActionResult> GrabarVoucher([FromBody] VoucherRequest request)
|
||||||
{
|
{
|
||||||
var result = await _transbankService.GrabarVoucherAsync(
|
var result = await _transbankService.GrabarVoucherAsync(
|
||||||
request.Token, request.AccountingDate, request.BuyOrder,
|
request.Token, request.AccountingDate, request.BuyOrder,
|
||||||
request.CardNumber, request.AuthorizationCode, request.PaymentType,
|
request.CardNumber, request.CardExpiration, request.AuthorizationCode,
|
||||||
request.SharesNumber, request.Amount);
|
request.PaymentType, request.ResponseCode, request.SharesNumber,
|
||||||
|
request.Amount, request.CommerceCode, request.DetailBuyOrder,
|
||||||
|
request.SessionId, request.TransactionDate, request.Vci);
|
||||||
return Ok(new { mensaje = result });
|
return Ok(new { mensaje = result });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,15 @@ public class VoucherRequest
|
|||||||
public string AccountingDate { get; set; } = string.Empty;
|
public string AccountingDate { get; set; } = string.Empty;
|
||||||
public string BuyOrder { get; set; } = string.Empty;
|
public string BuyOrder { get; set; } = string.Empty;
|
||||||
public string CardNumber { get; set; } = string.Empty;
|
public string CardNumber { get; set; } = string.Empty;
|
||||||
|
public string CardExpiration { get; set; } = string.Empty;
|
||||||
public string AuthorizationCode { get; set; } = string.Empty;
|
public string AuthorizationCode { get; set; } = string.Empty;
|
||||||
public string PaymentType { get; set; } = string.Empty;
|
public string PaymentType { get; set; } = string.Empty;
|
||||||
|
public string ResponseCode { get; set; } = string.Empty;
|
||||||
public string SharesNumber { get; set; } = string.Empty;
|
public string SharesNumber { get; set; } = string.Empty;
|
||||||
public int Amount { get; set; }
|
public int Amount { get; set; }
|
||||||
|
public string CommerceCode { get; set; } = string.Empty;
|
||||||
|
public string DetailBuyOrder { get; set; } = string.Empty;
|
||||||
|
public string SessionId { get; set; } = string.Empty;
|
||||||
|
public string TransactionDate { get; set; } = string.Empty;
|
||||||
|
public string Vci { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public class EmailService
|
|||||||
|
|
||||||
public async Task<string> SendAsync(EmailRequest request)
|
public async Task<string> SendAsync(EmailRequest request)
|
||||||
{
|
{
|
||||||
|
var client = new SmtpClient();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var message = new MimeMessage();
|
var message = new MimeMessage();
|
||||||
@@ -34,7 +35,7 @@ public class EmailService
|
|||||||
Text = request.Body
|
Text = request.Body
|
||||||
};
|
};
|
||||||
|
|
||||||
if (request.AttachmentPaths != null && request.AttachmentPaths.Count > 0)
|
if (request.AttachmentPaths?.Count > 0)
|
||||||
{
|
{
|
||||||
var multipart = new Multipart("mixed") { body };
|
var multipart = new Multipart("mixed") { body };
|
||||||
foreach (var path in request.AttachmentPaths)
|
foreach (var path in request.AttachmentPaths)
|
||||||
@@ -54,17 +55,20 @@ public class EmailService
|
|||||||
message.Body = body;
|
message.Body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
using var client = new SmtpClient();
|
|
||||||
await client.ConnectAsync(_smtpHost, _smtpPort, SecureSocketOptions.StartTls);
|
await client.ConnectAsync(_smtpHost, _smtpPort, SecureSocketOptions.StartTls);
|
||||||
await client.AuthenticateAsync(_smtpUser, _smtpPassword);
|
await client.AuthenticateAsync(_smtpUser, _smtpPassword);
|
||||||
await client.SendAsync(message);
|
await client.SendAsync(message);
|
||||||
await client.DisconnectAsync(true);
|
|
||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return $"Error: {ex.Message}";
|
return $"Error: {ex.Message}";
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (client.IsConnected)
|
||||||
|
await client.DisconnectAsync(true);
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using ServicesExternos.API.Models;
|
using ServicesExternos.API.Models;
|
||||||
|
using MySqlConnector;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Npgsql;
|
|
||||||
|
|
||||||
namespace ServicesExternos.API.Services;
|
namespace ServicesExternos.API.Services;
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ public class TransbankService
|
|||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly string _apiKey;
|
private readonly string _apiKey;
|
||||||
private readonly string _commerceCode;
|
private readonly string _commerceCode;
|
||||||
private readonly string _connectionString;
|
private readonly string _mysqlConnectionString;
|
||||||
private readonly string _environment;
|
private readonly string _environment;
|
||||||
|
|
||||||
public TransbankService(HttpClient client, IConfiguration configuration)
|
public TransbankService(HttpClient client, IConfiguration configuration)
|
||||||
@@ -19,7 +19,7 @@ public class TransbankService
|
|||||||
_client = client;
|
_client = client;
|
||||||
_apiKey = configuration["Transbank:ApiKey"] ?? throw new Exception("Transbank:ApiKey required");
|
_apiKey = configuration["Transbank:ApiKey"] ?? throw new Exception("Transbank:ApiKey required");
|
||||||
_commerceCode = configuration["Transbank:CommerceCode"] ?? throw new Exception("Transbank:CommerceCode required");
|
_commerceCode = configuration["Transbank:CommerceCode"] ?? throw new Exception("Transbank:CommerceCode required");
|
||||||
_connectionString = configuration.GetConnectionString("Default")!;
|
_mysqlConnectionString = configuration.GetConnectionString("CajaTbk")!;
|
||||||
_environment = configuration["Transbank:Environment"] ?? "integration";
|
_environment = configuration["Transbank:Environment"] ?? "integration";
|
||||||
|
|
||||||
var baseUrl = _environment == "production"
|
var baseUrl = _environment == "production"
|
||||||
@@ -49,26 +49,38 @@ public class TransbankService
|
|||||||
|
|
||||||
public async Task<string> ConfirmarTransaccionAsync(string tokenWs)
|
public async Task<string> ConfirmarTransaccionAsync(string tokenWs)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(tokenWs))
|
||||||
|
throw new ArgumentException("TokenWs es requerido");
|
||||||
|
|
||||||
var response = await _client.PutAsync($"/rswebpaytransaction/api/webpay/v1.2/transactions/{tokenWs}", null);
|
var response = await _client.PutAsync($"/rswebpaytransaction/api/webpay/v1.2/transactions/{tokenWs}", null);
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GrabarVoucherAsync(string token, string accountingDate, string buyOrder,
|
public async Task<string> GrabarVoucherAsync(string token, string accountingDate, string buyOrder,
|
||||||
string cardNumber, string authCode, string paymentType, string sharesNumber, int amount)
|
string cardNumber, string cardExpiration, string authCode, string paymentType, string responseCode,
|
||||||
|
string sharesNumber, int amount, string commerceCode, string detailBuyOrder, string sessionId,
|
||||||
|
string transactionDate, string vci)
|
||||||
{
|
{
|
||||||
using var connection = new NpgsqlConnection(_connectionString);
|
using var connection = new MySqlConnection(_mysqlConnectionString);
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
"caja_tbk.GrabaVoucher",
|
"caja_tbk.GrabaVoucher",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
token_id = token,
|
token_id = token,
|
||||||
xaccountingDate = accountingDate,
|
XaccountingDate = accountingDate,
|
||||||
xbuyOrder = buyOrder,
|
XbuyOrder = buyOrder,
|
||||||
xcardDetailcardNumber = cardNumber,
|
xcardDetailcardNumber = cardNumber,
|
||||||
|
xcardDetailcardExpirationDate = cardExpiration,
|
||||||
xdetailOutputAuthorizationCode = authCode,
|
xdetailOutputAuthorizationCode = authCode,
|
||||||
xdetailOutputPaymentTypeCode = paymentType,
|
xdetailOutputPaymentTypeCode = paymentType,
|
||||||
|
xdetailOutputResponseCode = responseCode,
|
||||||
xdetailOutputSharesNumber = sharesNumber,
|
xdetailOutputSharesNumber = sharesNumber,
|
||||||
xdetailOutputAmount = amount
|
xdetailOutputAmount = amount,
|
||||||
|
xdetailOutputcommerceCode = commerceCode,
|
||||||
|
xdetailOutputBuyOrder = detailBuyOrder,
|
||||||
|
xsessionId = sessionId,
|
||||||
|
xtransactionDate = transactionDate,
|
||||||
|
xVCI = vci
|
||||||
},
|
},
|
||||||
commandType: System.Data.CommandType.StoredProcedure);
|
commandType: System.Data.CommandType.StoredProcedure);
|
||||||
return "ok";
|
return "ok";
|
||||||
@@ -76,7 +88,7 @@ public class TransbankService
|
|||||||
|
|
||||||
public async Task<string> BuscarTransaccionAsync(string token)
|
public async Task<string> BuscarTransaccionAsync(string token)
|
||||||
{
|
{
|
||||||
using var connection = new NpgsqlConnection(_connectionString);
|
using var connection = new MySqlConnection(_mysqlConnectionString);
|
||||||
var rows = await connection.QueryAsync(
|
var rows = await connection.QueryAsync(
|
||||||
"caja_tbk.BuscarInfoToken",
|
"caja_tbk.BuscarInfoToken",
|
||||||
new { tokenid = token },
|
new { tokenid = token },
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<PackageReference Include="Dapper" Version="2.1.79" />
|
<PackageReference Include="Dapper" Version="2.1.79" />
|
||||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.2" />
|
||||||
|
<PackageReference Include="MySqlConnector" Version="2.6.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="Npgsql" Version="10.0.3" />
|
<PackageReference Include="Npgsql" Version="10.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
@ServicesExternos.API_HostAddress = http://localhost:5194
|
|
||||||
|
|
||||||
GET {{ServicesExternos.API_HostAddress}}/weatherforecast/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Default": "Host=192.168.0.254;Port=5432;Database=ichn;Username=postgres;Password=apoca11"
|
"Default": "Host=192.168.0.254;Port=5432;Database=ichn;Username=postgres;Password=apoca11",
|
||||||
|
"CajaTbk": "Server=192.168.0.254;Port=3306;Database=caja_tbk;User=postgres;Password=apoca11"
|
||||||
},
|
},
|
||||||
"LibreDTE": {
|
"LibreDTE": {
|
||||||
"UserHash": "",
|
"UserHash": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user