diff --git a/ROADMAP.md b/ROADMAP.md
index 35b485f..85205cc 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -20,7 +20,7 @@
| Reportes QuestPDF (17 reportes Crystal) | ✅ COMPLETO |
| Reportes empresa (variantes) + controller | ✅ COMPLETO |
| Reportes QuestPDF (17 reportes) | ❌ PENDIENTE |
-| ServicesExternos.API | ❌ PENDIENTE |
+| ServicesExternos.API | ✅ COMPLETO |
| Frontend Next.js | ❌ PENDIENTE |
| Contenedores (Docker) | ❌ PENDIENTE |
| Tests E2E | ❌ PENDIENTE |
@@ -61,12 +61,19 @@
### FASE 2: SERVICES EXTERNOS API (~2-3 semanas)
-- [ ] **2.0 Setup**
- - [ ] ServicesExternos.sln + proyectos
- - [ ] Program.cs + Dockerfile
-- [ ] **2.1 LibreDTE** (~1 sem)
-- [ ] **2.2 Transbank Webpay** (~1 sem)
-- [ ] **2.3 Email con MailKit** (~2 días)
+- [x] **2.0 Setup**
+ - [x] ServicesExternos.slnx + API project + Dockerfile
+ - [x] Program.cs con DI (HttpClient factory + servicios)
+ - [x] appsettings.json con config de servicios
+- [x] **2.1 LibreDTE** (~1 sem)
+ - [x] DteService (emitir, generar PDF, consultar folio)
+ - [x] DteController (emitir endpoint with PDF download)
+- [x] **2.2 Transbank Webpay** (~1 sem)
+ - [x] TransbankService (crear transacción, confirmar, voucher)
+ - [x] TransbankController + Voucher SP integration
+- [x] **2.3 Email con MailKit** (~2 días)
+ - [x] EmailService (send with HTML templates + attachments)
+ - [x] EmailController (send endpoint)
### FASE 3: FRONTEND NEXT.JS (~6-8 semanas)
@@ -112,6 +119,7 @@
| 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.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) |
| | | | |
| | | | |
diff --git a/services-externos/ServicesExternos.slnx b/services-externos/ServicesExternos.slnx
new file mode 100644
index 0000000..dcda99a
--- /dev/null
+++ b/services-externos/ServicesExternos.slnx
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/services-externos/src/ServicesExternos.API/Controllers/DteController.cs b/services-externos/src/ServicesExternos.API/Controllers/DteController.cs
new file mode 100644
index 0000000..a2f8951
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Controllers/DteController.cs
@@ -0,0 +1,34 @@
+using Microsoft.AspNetCore.Mvc;
+using ServicesExternos.API.Models;
+using ServicesExternos.API.Services;
+
+namespace ServicesExternos.API.Controllers;
+
+[ApiController]
+[Route("api/dte")]
+public class DteController : ControllerBase
+{
+ private readonly DteService _dteService;
+
+ public DteController(DteService dteService)
+ {
+ _dteService = dteService;
+ }
+
+ [HttpPost("emitir")]
+ public async Task Emitir([FromBody] DteEmissionRequest request)
+ {
+ var result = await _dteService.EmitirYDescargarPdfAsync(request);
+ if (result.PdfBytes != null)
+ return File(result.PdfBytes, "application/pdf", $"dte_{result.Folio}.pdf");
+
+ return BadRequest(new { error = result.Estado });
+ }
+
+ [HttpGet("estado/{codigo}")]
+ public async Task ConsultarEstado(string codigo, [FromQuery] int dte, [FromQuery] long emisor)
+ {
+ var result = await _dteService.ConsultarSiguienteFolioAsync(dte, emisor);
+ return Ok(result);
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/Controllers/EmailController.cs b/services-externos/src/ServicesExternos.API/Controllers/EmailController.cs
new file mode 100644
index 0000000..b48d4bf
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Controllers/EmailController.cs
@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.Mvc;
+using ServicesExternos.API.Models;
+using ServicesExternos.API.Services;
+
+namespace ServicesExternos.API.Controllers;
+
+[ApiController]
+[Route("api/email")]
+public class EmailController : ControllerBase
+{
+ private readonly EmailService _emailService;
+
+ public EmailController(EmailService emailService)
+ {
+ _emailService = emailService;
+ }
+
+ [HttpPost("send")]
+ public async Task Send([FromBody] EmailRequest request)
+ {
+ var result = await _emailService.SendAsync(request);
+ if (result == "ok")
+ return Ok(new { mensaje = result });
+
+ return BadRequest(new { error = result });
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/Controllers/TransbankController.cs b/services-externos/src/ServicesExternos.API/Controllers/TransbankController.cs
new file mode 100644
index 0000000..0dca79e
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Controllers/TransbankController.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Mvc;
+using ServicesExternos.API.Models;
+using ServicesExternos.API.Services;
+
+namespace ServicesExternos.API.Controllers;
+
+[ApiController]
+[Route("api/pagos/transbank")]
+public class TransbankController : ControllerBase
+{
+ private readonly TransbankService _transbankService;
+
+ public TransbankController(TransbankService transbankService)
+ {
+ _transbankService = transbankService;
+ }
+
+ [HttpPost("crear-transaccion")]
+ public async Task CrearTransaccion([FromBody] TransbankTransactionRequest request)
+ {
+ var result = await _transbankService.CrearTransaccionAsync(request);
+ return Ok(result);
+ }
+
+ [HttpPost("confirmar")]
+ public async Task Confirmar([FromBody] TransbankConfirmRequest request)
+ {
+ var result = await _transbankService.ConfirmarTransaccionAsync(request.TokenWs!);
+ return Ok(result);
+ }
+
+ [HttpPost("voucher")]
+ public async Task GrabarVoucher([FromBody] Models.VoucherRequest request)
+ {
+ var result = await _transbankService.GrabarVoucherAsync(
+ request.Token, request.AccountingDate, request.BuyOrder,
+ request.CardNumber, request.AuthorizationCode, request.PaymentType,
+ request.SharesNumber, request.Amount);
+ return Ok(new { mensaje = result });
+ }
+
+ [HttpGet("buscar/{token}")]
+ public async Task Buscar(string token)
+ {
+ var result = await _transbankService.BuscarTransaccionAsync(token);
+ return Ok(result);
+ }
+}
+
diff --git a/services-externos/src/ServicesExternos.API/Models/DteModels.cs b/services-externos/src/ServicesExternos.API/Models/DteModels.cs
new file mode 100644
index 0000000..dd248cb
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Models/DteModels.cs
@@ -0,0 +1,67 @@
+namespace ServicesExternos.API.Models;
+
+public class DteEmissionRequest
+{
+ public int Dte { get; set; } = 33;
+ public int Emisor { get; set; }
+ public string? Fecha { get; set; }
+ public string? Sucursal { get; set; }
+ public int? SucursalSii { get; set; }
+ public string? Terminal { get; set; }
+ public string? IndicadorServicio { get; set; }
+ public string? TipoDespacho { get; set; }
+ public string? TipoTraslado { get; set; }
+ public string? TpoTranCompra { get; set; }
+ public string? TpoTranVenta { get; set; }
+ public string? FechaVencimiento { get; set; }
+ public Receptor? Receptor { get; set; }
+ public List? Detalles { get; set; }
+ public Referencia? Referencia { get; set; }
+}
+
+public class Receptor
+{
+ public string? RUT { get; set; }
+ public string? RazonSocial { get; set; }
+ public string? Direccion { get; set; }
+ public string? Comuna { get; set; }
+ public string? Ciudad { get; set; }
+}
+
+public class DetalleItem
+{
+ public string? Nombre { get; set; }
+ public int Cantidad { get; set; }
+ public int Precio { get; set; }
+ public string? Descuento { get; set; }
+}
+
+public class Referencia
+{
+ public int TipoDocReferencia { get; set; }
+ public int FolioReferencia { get; set; }
+ public string? FechaReferencia { get; set; }
+ public string? RazonReferencia { get; set; }
+}
+
+public class DteGenerarPorCodigo
+{
+ public string? Codigo { get; set; }
+ public int TipoDte { get; set; }
+ public int Emisor { get; set; }
+ public int Receptor { get; set; }
+}
+
+public class DteFolioInfo
+{
+ public int FoliosDisponibles { get; set; }
+ public int FolioActual { get; set; }
+ public int? Siguiente { get; set; }
+}
+
+public class DteResultado
+{
+ public byte[]? PdfBytes { get; set; }
+ public int Folio { get; set; }
+ public string Estado { get; set; } = string.Empty;
+}
diff --git a/services-externos/src/ServicesExternos.API/Models/EmailModels.cs b/services-externos/src/ServicesExternos.API/Models/EmailModels.cs
new file mode 100644
index 0000000..844082a
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Models/EmailModels.cs
@@ -0,0 +1,10 @@
+namespace ServicesExternos.API.Models;
+
+public class EmailRequest
+{
+ public string? To { get; set; }
+ public string? Subject { get; set; }
+ public string? Body { get; set; }
+ public bool IsHtml { get; set; } = true;
+ public List? AttachmentPaths { get; set; }
+}
diff --git a/services-externos/src/ServicesExternos.API/Models/TransbankModels.cs b/services-externos/src/ServicesExternos.API/Models/TransbankModels.cs
new file mode 100644
index 0000000..a4ca90f
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Models/TransbankModels.cs
@@ -0,0 +1,26 @@
+namespace ServicesExternos.API.Models;
+
+public class TransbankTransactionRequest
+{
+ public string? BuyOrder { get; set; }
+ public string? SessionId { get; set; }
+ public int Amount { get; set; }
+ public string? ReturnUrl { get; set; }
+}
+
+public class TransbankConfirmRequest
+{
+ public string? TokenWs { get; set; }
+}
+
+public class VoucherRequest
+{
+ public string Token { get; set; } = string.Empty;
+ public string AccountingDate { get; set; } = string.Empty;
+ public string BuyOrder { get; set; } = string.Empty;
+ public string CardNumber { get; set; } = string.Empty;
+ public string AuthorizationCode { get; set; } = string.Empty;
+ public string PaymentType { get; set; } = string.Empty;
+ public string SharesNumber { get; set; } = string.Empty;
+ public int Amount { get; set; }
+}
diff --git a/services-externos/src/ServicesExternos.API/Program.cs b/services-externos/src/ServicesExternos.API/Program.cs
new file mode 100644
index 0000000..4802785
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Program.cs
@@ -0,0 +1,27 @@
+using ServicesExternos.API.Services;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddControllers();
+builder.Services.AddOpenApi();
+
+builder.Services.AddHttpClient();
+builder.Services.AddHttpClient();
+builder.Services.AddScoped();
+
+builder.Services.AddCors(options =>
+{
+ options.AddDefaultPolicy(policy =>
+ {
+ policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
+ });
+});
+
+var app = builder.Build();
+
+if (app.Environment.IsDevelopment())
+ app.MapOpenApi();
+
+app.UseCors();
+app.MapControllers();
+app.Run();
diff --git a/services-externos/src/ServicesExternos.API/Properties/launchSettings.json b/services-externos/src/ServicesExternos.API/Properties/launchSettings.json
new file mode 100644
index 0000000..a904704
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Properties/launchSettings.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": false,
+ "applicationUrl": "http://localhost:5194",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/Services/DteService.cs b/services-externos/src/ServicesExternos.API/Services/DteService.cs
new file mode 100644
index 0000000..c70d14a
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Services/DteService.cs
@@ -0,0 +1,90 @@
+using System.Net.Http.Headers;
+using System.Text;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using ServicesExternos.API.Models;
+
+namespace ServicesExternos.API.Services;
+
+public class DteService
+{
+ private readonly HttpClient _client;
+ private readonly string _userHash;
+ private readonly string _ambiente;
+
+ public DteService(HttpClient client, IConfiguration configuration)
+ {
+ _client = client;
+ _client.BaseAddress = new Uri("https://libredte.cl");
+ _client.Timeout = TimeSpan.FromSeconds(60);
+ _userHash = configuration["LibreDTE:UserHash"] ?? throw new Exception("LibreDTE:UserHash required");
+ _ambiente = configuration["LibreDTE:Ambiente"] ?? "1";
+ }
+
+ private void SetAuth()
+ {
+ var authString = Convert.ToBase64String(Encoding.ASCII.GetBytes("X:" + _userHash));
+ _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authString);
+ }
+
+ public async Task EmitirYDescargarPdfAsync(DteEmissionRequest datos)
+ {
+ SetAuth();
+ string jsonFinal = JsonConvert.SerializeObject(datos, Formatting.Indented);
+ var jsonContent = new StringContent(jsonFinal, Encoding.UTF8, "application/json");
+
+ var response = await _client.PostAsync("/api/dte/documentos/emitir", jsonContent);
+ string respuestaJson = await response.Content.ReadAsStringAsync();
+
+ if (!response.IsSuccessStatusCode)
+ return new DteResultado { Estado = respuestaJson };
+
+ JObject jsonResp = JObject.Parse(respuestaJson);
+ string cod = (string)jsonResp["codigo"]!;
+ int emi = (int)jsonResp["emisor"]!;
+ int rec = (int)jsonResp["receptor"]!;
+ int dte = (int)jsonResp["dte"]!;
+
+ var payload = new DteGenerarPorCodigo
+ {
+ Codigo = cod,
+ TipoDte = dte,
+ Emisor = emi,
+ Receptor = rec
+ };
+
+ jsonFinal = JsonConvert.SerializeObject(payload);
+ jsonContent = new StringContent(jsonFinal, Encoding.UTF8, "application/json");
+
+ response = await _client.PostAsync("/api/dte/documentos/generar?getXML=0&links=1&email=1&retry=1&gzip=0", jsonContent);
+ respuestaJson = await response.Content.ReadAsStringAsync();
+
+ if (!response.IsSuccessStatusCode)
+ return new DteResultado { Estado = respuestaJson };
+
+ jsonResp = JObject.Parse(respuestaJson);
+ int folio = (int)jsonResp["folio"]!;
+
+ var responsePdf = await _client.GetAsync($"/api/dte/dte_emitidos/pdf/{dte}/{folio}/{emi}?formato=general&papelContinuo=0&copias_tributarias=1&copias_cedibles=1&cedible=0&compress=0&base64=0");
+
+ if (!responsePdf.IsSuccessStatusCode)
+ throw new Exception("Se generó el DTE pero falló la descarga del PDF.");
+
+ await _client.GetAsync($"/api/dte/dte_emitidos/actualizar_estado/{dte}/{folio}/{emi}?usarWebservice=1");
+
+ byte[] pdfBytes = await responsePdf.Content.ReadAsByteArrayAsync();
+ return new DteResultado { PdfBytes = pdfBytes, Folio = folio, Estado = "ok" };
+ }
+
+ public async Task ConsultarSiguienteFolioAsync(int dte, long emisor)
+ {
+ SetAuth();
+ var response = await _client.GetAsync($"/api/dte/admin/dte_folios/info/{dte}/{emisor}");
+ string respuestaJson = await response.Content.ReadAsStringAsync();
+
+ if (!response.IsSuccessStatusCode)
+ throw new Exception($"Error al consultar folio ({response.StatusCode}): {respuestaJson}");
+
+ return JsonConvert.DeserializeObject(respuestaJson)!;
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/Services/EmailService.cs b/services-externos/src/ServicesExternos.API/Services/EmailService.cs
new file mode 100644
index 0000000..839892e
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Services/EmailService.cs
@@ -0,0 +1,70 @@
+using MailKit.Net.Smtp;
+using MailKit.Security;
+using MimeKit;
+using ServicesExternos.API.Models;
+
+namespace ServicesExternos.API.Services;
+
+public class EmailService
+{
+ private readonly string _smtpHost;
+ private readonly int _smtpPort;
+ private readonly string _smtpUser;
+ private readonly string _smtpPassword;
+
+ public EmailService(IConfiguration configuration)
+ {
+ _smtpHost = configuration["Email:Host"] ?? "smtp.gmail.com";
+ _smtpPort = int.Parse(configuration["Email:Port"] ?? "587");
+ _smtpUser = configuration["Email:User"] ?? "noresponder@norteamericano.cl";
+ _smtpPassword = configuration["Email:Password"] ?? "";
+ }
+
+ public async Task SendAsync(EmailRequest request)
+ {
+ try
+ {
+ var message = new MimeMessage();
+ message.From.Add(new MailboxAddress("Norteamericano", _smtpUser));
+ message.To.Add(new MailboxAddress("", request.To));
+ message.Subject = request.Subject;
+
+ var body = new TextPart(request.IsHtml ? "html" : "plain")
+ {
+ Text = request.Body
+ };
+
+ if (request.AttachmentPaths != null && request.AttachmentPaths.Count > 0)
+ {
+ var multipart = new Multipart("mixed") { body };
+ foreach (var path in request.AttachmentPaths)
+ {
+ if (File.Exists(path))
+ multipart.Add(new MimePart("application", "pdf")
+ {
+ Content = new MimeContent(File.OpenRead(path), ContentEncoding.Default),
+ ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
+ FileName = Path.GetFileName(path)
+ });
+ }
+ message.Body = multipart;
+ }
+ else
+ {
+ message.Body = body;
+ }
+
+ using var client = new SmtpClient();
+ await client.ConnectAsync(_smtpHost, _smtpPort, SecureSocketOptions.StartTls);
+ await client.AuthenticateAsync(_smtpUser, _smtpPassword);
+ await client.SendAsync(message);
+ await client.DisconnectAsync(true);
+
+ return "ok";
+ }
+ catch (Exception ex)
+ {
+ return $"Error: {ex.Message}";
+ }
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/Services/TransbankService.cs b/services-externos/src/ServicesExternos.API/Services/TransbankService.cs
new file mode 100644
index 0000000..843039e
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/Services/TransbankService.cs
@@ -0,0 +1,86 @@
+using System.Text;
+using Newtonsoft.Json;
+using ServicesExternos.API.Models;
+using Dapper;
+using Npgsql;
+
+namespace ServicesExternos.API.Services;
+
+public class TransbankService
+{
+ private readonly HttpClient _client;
+ private readonly string _apiKey;
+ private readonly string _commerceCode;
+ private readonly string _connectionString;
+ private readonly string _environment;
+
+ public TransbankService(HttpClient client, IConfiguration configuration)
+ {
+ _client = client;
+ _apiKey = configuration["Transbank:ApiKey"] ?? throw new Exception("Transbank:ApiKey required");
+ _commerceCode = configuration["Transbank:CommerceCode"] ?? throw new Exception("Transbank:CommerceCode required");
+ _connectionString = configuration.GetConnectionString("Default")!;
+ _environment = configuration["Transbank:Environment"] ?? "integration";
+
+ var baseUrl = _environment == "production"
+ ? "https://webpay3g.transbank.cl"
+ : "https://webpay3gint.transbank.cl";
+
+ _client.BaseAddress = new Uri(baseUrl);
+ _client.DefaultRequestHeaders.Add("Tbk-Api-Key-Id", _commerceCode);
+ _client.DefaultRequestHeaders.Add("Tbk-Api-Key-Secret", _apiKey);
+ }
+
+ public async Task CrearTransaccionAsync(TransbankTransactionRequest request)
+ {
+ var payload = new
+ {
+ buy_order = request.BuyOrder,
+ session_id = request.SessionId,
+ amount = request.Amount,
+ return_url = request.ReturnUrl
+ };
+
+ var json = JsonConvert.SerializeObject(payload);
+ var content = new StringContent(json, Encoding.UTF8, "application/json");
+ var response = await _client.PostAsync("/rswebpaytransaction/api/webpay/v1.2/transactions", content);
+ return await response.Content.ReadAsStringAsync();
+ }
+
+ public async Task ConfirmarTransaccionAsync(string tokenWs)
+ {
+ var response = await _client.PutAsync($"/rswebpaytransaction/api/webpay/v1.2/transactions/{tokenWs}", null);
+ return await response.Content.ReadAsStringAsync();
+ }
+
+ public async Task GrabarVoucherAsync(string token, string accountingDate, string buyOrder,
+ string cardNumber, string authCode, string paymentType, string sharesNumber, int amount)
+ {
+ using var connection = new NpgsqlConnection(_connectionString);
+ await connection.ExecuteAsync(
+ "caja_tbk.GrabaVoucher",
+ new
+ {
+ token_id = token,
+ xaccountingDate = accountingDate,
+ xbuyOrder = buyOrder,
+ xcardDetailcardNumber = cardNumber,
+ xdetailOutputAuthorizationCode = authCode,
+ xdetailOutputPaymentTypeCode = paymentType,
+ xdetailOutputSharesNumber = sharesNumber,
+ xdetailOutputAmount = amount
+ },
+ commandType: System.Data.CommandType.StoredProcedure);
+ return "ok";
+ }
+
+ public async Task BuscarTransaccionAsync(string token)
+ {
+ using var connection = new NpgsqlConnection(_connectionString);
+ var rows = await connection.QueryAsync(
+ "caja_tbk.BuscarInfoToken",
+ new { tokenid = token },
+ commandType: System.Data.CommandType.StoredProcedure);
+ return JsonConvert.SerializeObject(rows);
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/ServicesExternos.API.csproj b/services-externos/src/ServicesExternos.API/ServicesExternos.API.csproj
new file mode 100644
index 0000000..7a69b1b
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/ServicesExternos.API.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/services-externos/src/ServicesExternos.API/ServicesExternos.API.http b/services-externos/src/ServicesExternos.API/ServicesExternos.API.http
new file mode 100644
index 0000000..ddbcd85
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/ServicesExternos.API.http
@@ -0,0 +1,6 @@
+@ServicesExternos.API_HostAddress = http://localhost:5194
+
+GET {{ServicesExternos.API_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/services-externos/src/ServicesExternos.API/appsettings.Development.json b/services-externos/src/ServicesExternos.API/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/services-externos/src/ServicesExternos.API/appsettings.json b/services-externos/src/ServicesExternos.API/appsettings.json
new file mode 100644
index 0000000..011d5dc
--- /dev/null
+++ b/services-externos/src/ServicesExternos.API/appsettings.json
@@ -0,0 +1,27 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "Default": "Host=192.168.0.254;Port=5432;Database=ichn;Username=postgres;Password=apoca11"
+ },
+ "LibreDTE": {
+ "UserHash": "",
+ "Ambiente": "1"
+ },
+ "Transbank": {
+ "ApiKey": "",
+ "CommerceCode": "",
+ "Environment": "integration"
+ },
+ "Email": {
+ "Host": "smtp.gmail.com",
+ "Port": 587,
+ "User": "noresponder@norteamericano.cl",
+ "Password": ""
+ }
+}