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:
2026-07-08 10:46:01 -04:00
parent c43dbcce8b
commit 9c1eb20132
15 changed files with 70 additions and 42 deletions
+2 -1
View File
@@ -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)
{ {
+6 -1
View File
@@ -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();
-1
View File
@@ -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": "",