Commit ca902401 authored by Brayan Sarmiento's avatar Brayan Sarmiento
Browse files

Creacion Servicios

parent 7734c707
......@@ -2,8 +2,8 @@
<configuration>
<appSettings>
<add key="BaseUrl" value="http://localhost:9000" />
<add key="UrlServicio" value="http://10.100.43.30:89/ServiciosRG.svc" />
<add key="Estacion" value="CONVIVENCIA3" />
<add key="ArchivoBines" value="C:\\RUTALOGPINPADADEFINIR\\BINES.TXT" />
<add key="UrlServicio" value="http://10.100.1.28:82/ReingankServicePinpad2/ServiciosRG.svc" />
<add key="Estacion" value="PG041KB" />
<add key="ArchivoBines" value="C:\\LOGPINPAD\\BINES\\BINES.TXT" />
</appSettings>
</configuration>
\ No newline at end of file
using app_datafono_difare.Services;
using app_datafono_difare.Entities;
using app_datafono_difare.Services;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
......@@ -11,18 +13,24 @@ namespace app_datafono_difare.Controllers
{
public class PinpadController : ApiController
{
[HttpPost]
public IHttpActionResult Inicializar([FromBody] string UrlServicio, string Estacion)
{
try
private readonly TransactionService _service;
public PinpadController()
{
var service = new TransactionService(
_service = new TransactionService(
RgService.Instance,
System.Configuration.ConfigurationManager.AppSettings["ArchivoBines"]
);
}
var resp = service.Inicializar(UrlServicio, Estacion);
[HttpPost]
public IHttpActionResult Inicializar([FromBody] InicializarRequest req)
{
try
{
var resp = _service.Inicializar(req.UrlServicio, req.Estacion);
return Ok(resp);
}
catch (Exception ex)
......@@ -31,17 +39,13 @@ namespace app_datafono_difare.Controllers
}
}
[HttpPost]
public async Task<IHttpActionResult> Autorizar([FromBody] decimal amount)
public async Task<IHttpActionResult> Autorizar([FromBody] PagarRequest pagar)
{
try
{
var service = new TransactionService(
RgService.Instance,
System.Configuration.ConfigurationManager.AppSettings["ArchivoBines"]
);
// SOLO se envía la venta — sin reconfigurar el pinpad
var resp = await service.EnviarVenta(amount, 0);
var resp = await _service.LeerYAutorizar(pagar);
return Ok(resp);
}
......@@ -50,5 +54,72 @@ namespace app_datafono_difare.Controllers
return InternalServerError(ex);
}
}
[HttpPost]
public async Task<IHttpActionResult> Cierrelote([FromBody] InicializarRequest req)
{
try
{
var resultado = _service.CerrarLote(req.Estacion);
if (!resultado.Exitoso)
return Content(HttpStatusCode.BadRequest, resultado);
return Ok(resultado);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPost]
public async Task<IHttpActionResult> AnularVoucher([FromBody] AnularRequest anular)
{
try
{
var resultado = await _service.AnularVoucher(anular.Req.Estacion, anular);
return Ok(resultado);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPost]
public async Task<IHttpActionResult> ConsultarTarjeta([FromBody] InicializarRequest req)
{
try
{
var resultado = _service.ConsultarTarjeta(req.Estacion);
if (!resultado.Exitoso)
return Content(HttpStatusCode.BadRequest, resultado);
return Ok(resultado);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPost]
public async Task<IHttpActionResult> ObtenerMidTid([FromBody] InicializarRequest req)
{
try
{
var resultado = _service.ObtenerMidTid(req.Estacion);
if (!resultado.Exitoso)
return Content(HttpStatusCode.BadRequest, resultado);
return Ok(resultado);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class AnularRequest
{
public InicializarRequest Req { get; set; }
public AnularRequest Anular { get; set; }
public string CodigoAutorizacion { get; set; }
public string TipoTransaccion { get; set; }
public int TipoCompraDatafast { get; set; }
public int Cuota { get; set; }
public decimal MontoTotal { get; set; }
public int Base12 { get; set; }
public decimal MontoBaseCero { get; set; }
public int Iva { get; set; }
public decimal MontoServicio { get; set; }
public decimal MontoPropina { get; set; }
public string Secuencia { get; set; }
public string Aprobacion { get; set; }
public string FechaAnulacion { get; set; }
public string HoraAnulacion { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class BaseResponse
{
public string CodigoRespuesta { get; set; }
public string Descripcion { get; set; }
public bool Declinado { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class InicializarRequest
{
public string UrlServicio { get; set; }
public string Estacion { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class ObtenerMidTid
{
public bool Exitoso { get; set; }
public string Mid1 { get; set; }
public string Tic1 { get; set; }
public string Mid2 { get; set; }
public string Tic2 { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class PagarRequest
{
public decimal Amount { get; set; }
public string TipoTarjeta { get; set; }
public decimal MontoBase0 { get; set; }
public decimal MontoBase12 { get; set; }
public decimal Iva { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace app_datafono_difare.Entities
{
public class ResultadoPinpad
{
public bool Exitoso { get; set; }
public string Codigo { get; set; }
public string Mensaje { get; set; }
public string RawResponse { get; set; }
public int Lote1 { get; set; }
public int Lote2 { get; set; }
public string RucEmpresa { get; set; }
public string MidRed1 { get; set; }
public string MidRed2 { get; set; }
public string TidRed1 { get; set; }
public string TidRed2 { get; set; }
}
}
......@@ -8,32 +8,15 @@ namespace app_datafono_difare.Entities
{
public class TransaccionResponse
{
//public bool Success { get; set; }
//public string AuthorizationCode { get; set; }
//public string TransactionId { get; set; }
//public string CardNumber { get; set; }
//public string CardType { get; set; }
//public string ResponseCode { get; set; }
//public string ResponseMessage { get; set; }
//public decimal Amount { get; set; }
//public DateTime Timestamp { get; set; }
//public string CommerceCode { get; set; }
//public string TerminalId { get; set; }
////Campos adicionales
//public string CodRed { get; set; }
//public string Metodo { get; set; }
//public string Lote { get; set; }
//public string Promocion { get; set; }
//public string codigoAdquiriente { get; set; }
//public string idAdquiriente { get; set; }
public bool ReturnFlag { get; set; } = false;
public bool DepositFlag { get; set; } = false;
public bool VoidFlag { get; set; } = false;
public decimal Amount { get; set; } = 0.00m;
public string LineItemType { get; set; } = "";
public bool BalanceDueSatisfied { get; set; } = false;
public string ReferenceNumber { get; set; } = "";
public string MaskedAccountNumber { get; set; } = "";
public bool returnflag { get; set; } = false;
public bool depositflag { get; set; } = false;
public bool voidflag { get; set; } = false;
public decimal amount { get; set; } = 0.00m;
public string lineitemtype { get; set; } = "";
public bool balanceduesatisfied { get; set; } = false;
public string referencenumber { get; set; } = "";
public string maskedaccountnumber { get; set; } = "";
public string ResponseCode { get; set; } = "";
public string ApprovalCode { get; set; } = "";
public string SequenceNumber { get; set; } = "";
......@@ -41,13 +24,67 @@ namespace app_datafono_difare.Entities
public bool IsDeclined { get; set; } = false;
public string ResponseCodeDescriptor { get; set; } = "";
public DateTime Timestamp { get; set; }
public string CommerceCode { get; set; }
public string TerminalId { get; set; }
public string RedCode { get; set; }
public string Lote { get; set; }
public string Promotion { get; set; }
public string CodAdquiriente { get; set; }
public string idAdquiriente { get; set; }
public string CardBrand { get; set; }
public string CommerceCode { get; set; } = "";
public string TerminalId { get; set; } = "";
public string RedCode { get; set; } = "";
public string Lote { get; set; } = "";
public string Promotion { get; set; } = "";
public string CodAdquiriente { get; set; } = "";
public string idAdquiriente { get; set; } = "";
public string CardBrand { get; set; } = "";
public string Comercio { get; set; } = "";
public string AID { get; set; } = "";
public string TC { get; set; } = "";
public string ARQC { get; set; } = "";
public string Ambiente1 { get; set; } = "";
public string fechaVencimiento { get; set; } = "";
//Nuevos campos para anulacion del voucher
public string FechaTransaccion { get; set; } = "";
public string HoraTransaccion { get; set; } = "";
public int Id { get; set; }
public string IdTipoCompra { get; set; } = "";
public string IdTipoTransaccion { get; set; } = "";
public string ValorMid { get; set; } = "";
public string ValorTid { get; set; } = "";
public decimal MontoFijo { get; set; }
public int MontoInteres { get; set; }
public int MontoIva { get; set; }
public int MontoServicio { get; set; }
public int MontoPropina { get; set; }
public int PorcentajeIva { get; set; }
public int Cuotas { get; set; }
public string Modo { get; set; } = "";
public string ErrorMessage { get; set; }
public bool BinEncontrado { get; set; }
//Mandar todos los campos
//public string iiCodigoRed { get; set; }
//public string iiCodRespuesta { get; set; }
//public string iiMensaje { get; set; }
//public string iiReferencia { get; set; }
//public string iiLote { get; set; }
//public string iiHora { get; set; }
//public string iiFecha { get; set; }
//public string iiAutorizacion { get; set; }
//public string iiTerminal { get; set; }
//public string iiComercio { get; set; }
//public string iiInteres { get; set; }
//public string iiPromocion { get; set; }
//public string iiCodAdq { get; set; }
//public string iiAdq { get; set; }
//public string iiMarca { get; set; }
//public string iiModo { get; set; }
//public string iiNombre { get; set; }
//public string iiMontoFijo { get; set; }
//public string iiEmv { get; set; }
//public string iiEmv2 { get; set; }
//public string iiEmv3 { get; set; }
//public string iiPin { get; set; }
//public string iiArqc { get; set; }
//public string iiTarjeta { get; set; }
//public string iiFecVen { get; set; }
//public string iiRespuesta { get; set; }
//public string iiMid2 { get; set; }
//public string iiTrack { get; set; }
}
}
......@@ -9,7 +9,7 @@ namespace app_datafono_difare.Helpers
{
public static class ObtenerTipoTarjetaHelper
{
public static string ObtenerTipoTarjetaPorBin(string cardNumber,string ruta)
public static string ObtenerTipoTarjetaPorBin(string cardNumber, string ruta)
{
if (string.IsNullOrWhiteSpace(cardNumber) || cardNumber.Length < 6)
return null;
......@@ -37,5 +37,22 @@ namespace app_datafono_difare.Helpers
return null;
}
public static string ObtenerRedPorCodigo(string codigoRed)
{
if (string.IsNullOrWhiteSpace(codigoRed))
return "Red no identificada";
codigoRed = codigoRed.Trim();
if (codigoRed == "01")
return "Datafast";
if (codigoRed == "02")
return "Medianet";
return "Red no identificada";
}
}
}
using app_datafono_difare.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace app_datafono_difare.Helpers
{
public class ResultadoPinpadHelpers
{
public static bool EsRespuestaOk(string resp)
{
return !string.IsNullOrEmpty(resp)
&& resp.Length >= 4
&& resp.Substring(0, 2) == "00";
}
public static ResultadoPinpad CrearError(string resp, string mensajeDefault)
{
return new ResultadoPinpad
{
Exitoso = false,
Codigo = resp.Length >= 2 ? resp.Substring(0, 2) : "ER",
Mensaje = resp.Length > 2 ? resp.Substring(2) : mensajeDefault,
RawResponse = resp
};
}
public static int ObtenerLoteAnterior(string rawResponse)
{
if (string.IsNullOrWhiteSpace(rawResponse))
return 0;
var match = Regex.Match(rawResponse, @"Lote\s*=\s*(\d+)");
if (!match.Success)
return 0;
int loteActual = int.Parse(match.Groups[1].Value);
return loteActual - 1;
}
public static string ObtenerRucEmpresa(string rawResponse)
{
if (string.IsNullOrWhiteSpace(rawResponse))
return string.Empty;
var match = Regex.Match(
rawResponse,
@"Ruc_Empresa\s*=\s*'([^']+)'"
);
if (!match.Success)
return string.Empty;
return match.Groups[1].Value;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="4.0" />
</startup>
<runtime>
<gcConcurrent enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="core;logic;ui" />
</assemblyBinding>
</runtime>
<appSettings>
<add key="ReigankRutaLog" value="C:\LOGPINPAD" />
<add key="ReigankRutaBines" value="C:\LOGPINPAD\BINES" />
<add key="ReigankRutaDump" value="C:\LOGPINPAD\DUMP" />
</appSettings>
</configuration>
\ No newline at end of file
......@@ -15,11 +15,18 @@ namespace app_datafono_difare
{
static void Main()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File("logs\\rest-pinpad.log", rollingInterval: RollingInterval.Day)
.WriteTo.File(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "C:\\logs_app_datafono\\rest-pinpad.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
//Redirige la salida a Serilog para logs
Console.SetOut(new SerilogTextWriter(Log.Logger));
Console.SetError(new SerilogTextWriter(Log.Logger));
HostFactory.Run(x =>
{
x.Service<PinpadService>(s =>
......
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>D:\Discod\SelfCheckout\Proyecto DIFARE\PublicacionPinPad</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
</PropertyGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<History>True|2025-12-17T19:20:54.5077654Z||;True|2025-12-15T12:04:29.3281583-05:00||;True|2025-12-12T10:42:20.7377788-05:00||;True|2025-12-08T11:25:43.7312482-05:00||;True|2025-12-04T15:37:16.2191665-05:00||;True|2025-12-03T15:46:16.2660630-05:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>D:\Discod\SelfCheckout\Proyecto DIFARE\PinPadServices</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
</PropertyGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<History>True|2025-12-10T16:54:10.1752303Z||;True|2025-12-09T15:40:43.3475849-05:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>
\ No newline at end of file
......@@ -17,10 +17,21 @@ namespace app_datafono_difare.Services
public RgFunciones Rg { get; }
public string Estacion { get; private set; }
public string TipoTarjeta { get; private set; }
private RgService()
{
Log.Information("Inicializando RgFunciones...");
Rg = RgFunciones.Instancia;
}
public void SetEstacion(string estacion)
{
Estacion = estacion;
}
public void SetTipoTarjeta(string tipoTarjeta)
{
TipoTarjeta = tipoTarjeta;
}
}
}
using app_datafono_difare.Entities;
using app_datafono_difare.Helpers;
using ClsRgFunciones;
using com.sun.codemodel.@internal;
using com.sun.xml.@internal.ws.util.xml;
using Newtonsoft.Json;
using org.omg.CosNaming;
using Serilog;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using static app_datafono_difare.Program;
namespace app_datafono_difare.Services
{
public class TransactionService
......@@ -21,6 +26,7 @@ namespace app_datafono_difare.Services
private readonly RgService _rg;
private readonly string _rutaBines;
public TransactionService(RgService rgService, string rutaBines)
{
_rg = rgService;
......@@ -31,11 +37,16 @@ namespace app_datafono_difare.Services
{
try
{
_rg.Rg.EstablecerServicio(url);
_rg.Rg.EstablecerEstacion(estacion);
_rg.SetEstacion(estacion);
_rg.Rg.ConfigurarTerminal(estacion);
_rg.Rg.ConfigurarPinpad();
var respuestaPinpad = _rg.Rg.ConfigurarPinpad();
//Log.Information($"Version: {version} estado: {estado} estacion: {pestacion}");
Log.Information("Respuesta Pinpad: {Respuesta}", respuestaPinpad);
Log.Information("Configuración del servicio exitosa.");
return true;
}
......@@ -47,7 +58,347 @@ namespace app_datafono_difare.Services
}
}
public async Task<TransaccionResponse> EnviarVenta(decimal monto, int cuotas)
public async Task<TransaccionResponse> LeerYAutorizar(PagarRequest pagar)
{
try
{
var estacion = _rg.Estacion;
if (string.IsNullOrEmpty(estacion))
{
Log.Error("La estación no está configurada.");
return new TransaccionResponse
{
ResponseCode = "99",
ResponseCodeDescriptor = "Estación no configurada"
};
}
//_rg.Rg.ConfigurarTerminal(estacion);
var adqCorr = "";
var adqDif = "";
var tarjeta = "";
var fecVen = "";
var track = "";
var tipoTarjeta = "";
var cuotas = 0;
//Log.Information("Leyendo tarjeta...");
//string estado = _rg.Rg.LeerTarjeta(
// ref adqCorr,
// ref adqDif,
// ref tarjeta,
// ref fecVen,
// ref track,
// ref tipoTarjeta
//);
////Captutar TipoTarjeta
_rg.SetTipoTarjeta(pagar.TipoTarjeta);
//if (!estado.Contains("00"))
//{
// return new TransaccionResponse
// {
// ResponseCode = "99",
// ResponseCodeDescriptor = "ERROR LEYENDO TARJETA"
// };
//}
Log.Information($"Tarjeta detectada: {tipoTarjeta}");
//if (tipoTarjeta != pagar.TipoTarjeta)
//{
// Log.Information($"La tarjeta ingresada: {pagar.TipoTarjeta} no es la misma que escogio el cliente :{tipoTarjeta}");
// return new TransaccionResponse
// {
// ResponseCode = "99",
// ResponseCodeDescriptor = "El tipo de tarjeta escogida no es igual a la ingresada"
// };
//}
return await EnviarVenta(pagar.Amount, pagar.MontoBase0, pagar.MontoBase12, pagar.Iva, cuotas);
}
catch (Exception ex)
{
Log.Error(ex, "Error en leer y autorizar");
return new TransaccionResponse
{
ResponseCode = "99",
ResponseCodeDescriptor = "Error interno al procesar la transacción"
};
}
}
public async Task<TransaccionResponse> AnularVoucher(string estacion, AnularRequest anular)
{
try
{
var respConfig = _rg.Rg.ConfigurarTerminal(estacion);
if (!ResultadoPinpadHelpers.EsRespuestaOk(respConfig))
{
return new TransaccionResponse
{
ResponseCode = "99",
ResponseCodeDescriptor = "Error configurando terminal",
};
}
string codigo = anular.CodigoAutorizacion;
string tipoTran = anular.TipoTransaccion;
int tipoCompra = anular.TipoCompraDatafast;
int cuota = anular.Cuota;
decimal montoTotal = (int)(anular.MontoTotal * 100);
string montoTotalStr = montoTotal.ToString();
double base12 = (double)anular.Base12;
int base0 = (int)(anular.MontoBaseCero * 100);
string base0Str = base0.ToString();
double iva = (double)anular.Iva;
int montoServicio = (int)(anular.MontoServicio * 100);
string montoServicioStr = montoServicio.ToString();
int montoPropina = (int)(anular.MontoPropina * 100);
string montoPropinaStr = montoPropina.ToString();
string secuencia = anular.Secuencia;
string aprobacion = anular.Aprobacion;
string fechaAnul = anular.FechaAnulacion;
string horaAnul = anular.HoraAnulacion;
string respuesta = "";
try
{
//TODO - Delay para que la DLL funcione correctamente
Log.Information("Esperando inicialización de la pinpad...");
await Task.Delay(1000);
Log.Information("Preparando venta...");
await Task.Delay(1000);
Log.Information("Enviando comando AUTORIZAR...");
// Delay justo antes del comando crítico
await Task.Delay(1500);
//Parsear valores
string resultado = _rg.Rg.Autorizar(
ref codigo,
int.Parse(tipoTran),
tipoCompra,
cuota,
double.Parse(montoTotalStr) / 100.0,
base12,
double.Parse(base0Str) / 100.0,
iva,
double.Parse(montoServicioStr) / 100.0,
double.Parse(montoPropinaStr) / 100.0,
int.Parse(secuencia),
aprobacion,
ref fechaAnul,
ref horaAnul,
ref respuesta
);
var error = ValidarResultado(resultado);
if (error != null)
{
//Log.Warning($"Error detectado en respuesta: {error.ResponseCodeDescriptor}");
return error;
}
var response = ProcesarRespuesta(resultado, montoTotal, tipoCompra.ToString(), tipoTran, iva, montoPropinaStr, montoServicioStr, cuota);
Log.Information($"Anulacion Procesada procesada: {response.ResponseCodeDescriptor}");
return response;
}
catch (Exception ex)
{
Log.Error(ex, "Error en anular transaccion");
throw;
}
}
catch (Exception ex)
{
Log.Error(ex, "Excepción anulando transaccion");
return new TransaccionResponse
{
ResponseCode = "99",
ResponseCodeDescriptor = "El servicio de anulacion fallo",
};
}
}
public ObtenerMidTid ObtenerMidTid(string estacion)
{
var respConfig = _rg.Rg.ConfigurarTerminal(estacion);
if (!ResultadoPinpadHelpers.EsRespuestaOk(respConfig))
{
return new ObtenerMidTid
{
Exitoso = false
};
}
var config = _rg.Rg;
return new ObtenerMidTid
{
Exitoso = true,
Mid1 = config.pMidRed1,
Tic1 = config.pTidRed1,
Mid2 = config.pMidRed2,
Tic2 = config.pTidRed2
};
}
public ResultadoPinpad ConsultarTarjeta(string estacion)
{
try
{
var respConfig = _rg.Rg.ConfigurarTerminal(estacion);
if (!ResultadoPinpadHelpers.EsRespuestaOk(respConfig))
{
return ResultadoPinpadHelpers.CrearError(respConfig, "Error configurando terminal");
}
var config = _rg.Rg;
string codigo = "";
string red = "";
string respuesta = "";
int lote1 = 0;
int lote2 = 0;
string sMensaje = "";
var respDll = _rg.Rg.ConsultarTarjeta(ref codigo, ref red, ref respuesta);
var responseLeerRangoBines = _rg.Rg.LeerRangoBines(estacion, ref respDll);
Log.Information("Respuesta de bines: " + responseLeerRangoBines);
if (codigo != "00")
{
return new ResultadoPinpad
{
Exitoso = false,
Codigo = codigo,
Mensaje = respuesta,
RawResponse = respDll
};
}
return new ResultadoPinpad
{
Exitoso = true,
Codigo = codigo,
Mensaje = respuesta,
RawResponse = respDll
};
}
catch (Exception ex)
{
Log.Error(ex, "Excepción Consultando");
return new ResultadoPinpad
{
Exitoso = false,
Codigo = "EX",
Mensaje = "Error interno al consultar tarjeta",
RawResponse = ex.Message
};
}
}
public ResultadoPinpad CerrarLote(string estacion)
{
try
{
var respConfig = _rg.Rg.ConfigurarTerminal(estacion);
if (!ResultadoPinpadHelpers.EsRespuestaOk(respConfig))
{
return ResultadoPinpadHelpers.CrearError(respConfig, "Error configurando terminal");
}
var config = _rg.Rg;
string midRed1 = config.pMidRed1;
string midRed2 = config.pMidRed2;
string tidRed1 = config.pTidRed1;
string tidRed2 = config.pTidRed2;
string codigo = "";
string red = "";
string respuesta = "";
int lote1 = 0;
int lote2 = 0;
string sMensaje = "";
var respDll = _rg.Rg.ProcesoControl(
ref codigo,
ref red,
ref respuesta,
ref lote1,
ref lote2
);
string rucEmpresa = ResultadoPinpadHelpers.ObtenerRucEmpresa(respDll);
if (codigo != "00")
{
return new ResultadoPinpad
{
Exitoso = false,
Codigo = codigo,
Mensaje = respuesta,
RawResponse = respDll
};
}
return new ResultadoPinpad
{
Exitoso = true,
Codigo = codigo,
Mensaje = respuesta,
RawResponse = respDll,
Lote1 = lote1,
Lote2 = lote2,
RucEmpresa = rucEmpresa,
MidRed1 = midRed1,
MidRed2 = midRed2,
TidRed1 = tidRed1,
TidRed2 = tidRed2
};
}
catch (Exception ex)
{
Log.Error(ex, "Excepción cerrando lote");
return new ResultadoPinpad
{
Exitoso = false,
Codigo = "EX",
Mensaje = "Error interno al cerrar lote",
RawResponse = ex.Message
};
}
}
public async Task<TransaccionResponse> EnviarVenta(decimal monto, decimal monto0, decimal monto12, decimal ivaTotal, int cuotas)
{
string codigo = string.Empty;
......@@ -77,6 +428,8 @@ namespace app_datafono_difare.Services
string horaAnul = "";
string respuesta = "";
try
{
//TODO - Delay para que la DLL funcione correctamente
......@@ -91,25 +444,79 @@ namespace app_datafono_difare.Services
// Delay justo antes del comando crítico
await Task.Delay(1500);
//Parsear valores
int tipoTranInt = int.Parse(tipoTran);
int tipoCompraInt = int.Parse(tipoCompra);
int cuotasInt = int.Parse(cuotaStr);
double montoTotalDouble = double.Parse(montoTotalStr) / 100.0;
//double base12Double = double.Parse(base12Str) / 100.0;
//double base0Double = double.Parse(base0Str) / 100.0;
//double ivaDouble = double.Parse(ivaStr) / 100.0;
double base12Double = (double)monto12;
double base0Double = (double)monto0;
double ivaDouble = (double)ivaTotal;
double servicioDouble = double.Parse(servicioStr) / 100.0;
double propinaDouble = double.Parse(propinaStr) / 100.0;
int secuenciaInt = int.Parse(secuenciaStr);
//string resultado = _rg.Rg.Autorizar(
// ref codigo,
// int.Parse(tipoTran),
// int.Parse(tipoCompra),
// int.Parse(cuotaStr),
// double.Parse(montoTotalStr) / 100.0,
// double.Parse(base12Str) / 100.0,
// double.Parse(base0Str) / 100.0,
// double.Parse(ivaStr) / 100.0,
// double.Parse(servicioStr) / 100.0,
// double.Parse(propinaStr) / 100.0,
// int.Parse(secuenciaStr),
// aprobacion,
// ref fechaAnul,
// ref horaAnul,
// ref respuesta
// );
//Log EXACTO de lo que se enviará
Log.Information(
"Enviando AUTORIZAR -> tipoTran:{tipoTran} tipoCompra:{tipoCompra} cuotas:{cuotas} montoTotal:{montoTotal} base12:{base12} base0:{base0} iva:{iva} servicio:{servicio} propina:{propina} secuencia:{secuencia}",
tipoTranInt,
tipoCompraInt,
cuotasInt,
montoTotalDouble,
base12Double,
base0Double,
ivaDouble,
servicioDouble,
propinaDouble,
secuenciaInt
);
//Llamada al método
string resultado = _rg.Rg.Autorizar(
ref codigo,
int.Parse(tipoTran),
int.Parse(tipoCompra),
int.Parse(cuotaStr),
double.Parse(montoTotalStr) / 100.0,
double.Parse(base12Str) / 100.0,
double.Parse(base0Str) / 100.0,
double.Parse(ivaStr) / 100.0,
double.Parse(servicioStr) / 100.0,
double.Parse(propinaStr) / 100.0,
int.Parse(secuenciaStr),
tipoTranInt,
tipoCompraInt,
cuotasInt,
montoTotalDouble,
base12Double,
base0Double,
ivaDouble,
servicioDouble,
propinaDouble,
secuenciaInt,
aprobacion,
ref fechaAnul,
ref horaAnul,
ref respuesta
);
Log.Information("Respuesta cruda: " + resultado);
if (resultado.IndexOf("FALLO", StringComparison.OrdinalIgnoreCase) >= 0 ||
resultado.IndexOf("CONNECTION", StringComparison.OrdinalIgnoreCase) >= 0)
......@@ -122,7 +529,7 @@ namespace app_datafono_difare.Services
}; ;
}
var response = ProcesarRespuesta(resultado, monto);
var response = ProcesarRespuesta(resultado, monto, tipoCompra, tipoTran, iva, propinaStr, servicioStr, numeroCuotas);
Log.Information($"Transacción procesada: {response.ResponseCodeDescriptor}");
return response;
......@@ -138,7 +545,8 @@ namespace app_datafono_difare.Services
}
private TransaccionResponse ProcesarRespuesta(string respuesta, decimal amount)
private TransaccionResponse ProcesarRespuesta(string respuesta, decimal amount, string tipoCompra,
string tipoTran, double iva, string propinaStr, string servicioStr, int numeroCuotas)
{
string iCodigo = string.Empty;
......@@ -206,27 +614,84 @@ namespace app_datafono_difare.Services
ref iRespuesta,
ref iMid2);
//Sacar Mid y el tid
var config = _rg.Rg;
string midRed2 = config.pMidRed2;
string tidRed2 = config.pTidRed2;
var tipoTarjeta = _rg.TipoTarjeta;
var tipoTarjetaBin = ObtenerTipoTarjetaHelper.ObtenerTipoTarjetaPorBin(iTarjeta?.Trim(), _rutaBines);
bool binEncontrado = tipoTarjetaBin != null;
var response = new TransaccionResponse
{
ReferenceNumber = iAutorizacion?.Trim(),
referencenumber = iAutorizacion?.Trim(),
SequenceNumber = iReferencia?.Trim(),
MaskedAccountNumber = iTarjeta?.Trim(),
maskedaccountnumber = iTarjeta?.Trim(),
CardBrand = iMarca?.Trim(),
ResponseCode = iCodRespuesta?.Trim(),
ResponseCodeDescriptor = iMensaje?.Trim(),
Amount = amount,
amount = amount,
Timestamp = DateHelper.ParseDate(iFecha, iHora),
CommerceCode = iComercio?.Trim(),
TerminalId = iTerminal?.Trim(),
RedCode = iCodigoRed?.Trim(),
RedCode = ObtenerTipoTarjetaHelper.ObtenerRedPorCodigo(iCodigoRed),
Lote = iLote?.Trim(),
Promotion = iPromocion?.Trim(),
CodAdquiriente = iCodAdq?.Trim(),
idAdquiriente = iAdq?.Trim(),
LineItemType = ObtenerTipoTarjetaHelper.ObtenerTipoTarjetaPorBin(iTarjeta?.Trim(), _rutaBines),
IsDeclined = iCodRespuesta?.Trim() != "00"
lineitemtype = tipoTarjetaBin ?? tipoTarjeta,
IsDeclined = iCodRespuesta?.Trim() != "00",
Comercio = iComercio?.Trim(),
AID = iEmv2?.Trim(),
TC = iEmv3?.Trim(),
ARQC = iArqc.Trim(),
Ambiente1 = iEmv.Trim(),
fechaVencimiento = iFecVen.Trim(),
FechaTransaccion = iFecha.Trim(),
HoraTransaccion = iHora.Trim(),
IdTipoCompra = tipoCompra,
IdTipoTransaccion = tipoTran,
MontoIva = (int)iva,
MontoPropina = int.Parse(propinaStr),
MontoServicio = int.Parse(servicioStr),
Cuotas = numeroCuotas,
ValorMid = midRed2.Trim(),
ValorTid = tidRed2.Trim(),
Modo = iModo.Trim(),
Id = 0,
BinEncontrado = binEncontrado,
//iiCodigoRed = iCodigoRed?.Trim(),
//iiCodRespuesta = iCodRespuesta?.Trim(),
//iiMensaje = iMensaje?.Trim(),
//iiReferencia = iReferencia?.Trim(),
//iiLote = iLote?.Trim(),
//iiHora = iHora?.Trim(),
//iiFecha = iFecha?.Trim(),
//iiAutorizacion = iAutorizacion?.Trim(),
//iiTerminal = iTerminal?.Trim(),
//iiComercio = iComercio?.Trim(),
//iiInteres = iInteres?.Trim(),
//iiPromocion = iPromocion?.Trim(),
//iiCodAdq = iCodAdq?.Trim(),
//iiAdq = iAdq?.Trim(),
//iiMarca = iMarca?.Trim(),
//iiModo = iModo?.Trim(),
//iiNombre = iNombre?.Trim(),
//iiMontoFijo = iMontoFijo?.Trim(),
//iiEmv = iEmv?.Trim(),
//iiEmv2 = iEmv2?.Trim(),
//iiEmv3 = iEmv3?.Trim(),
//iiPin = iPin?.Trim(),
//iiArqc = iArqc?.Trim(),
//iiTarjeta = iTarjeta?.Trim(),
//iiFecVen = iFecVen?.Trim(),
//iiTrack = iTrack?.Trim(),
//iiMid2 = iMid2?.Trim()
};
var json = JsonConvert.SerializeObject(response);
......@@ -313,5 +778,56 @@ namespace app_datafono_difare.Services
return resultado;
}
private TransaccionResponse CrearError(string codigo, string mensaje)
{
return new TransaccionResponse
{
ErrorMessage = mensaje,
IsDeclined = true
};
}
private static readonly Dictionary<string, (string Codigo, string Mensaje)> ERRORES =
new Dictionary<string, (string, string)>
{
{ "FALLO", ("99", "La pinpad o el servicio remoto no respondió correctamente") },
{ "CONNECTION", ("99", "La pinpad o el servicio remoto no respondió correctamente") },
{ "TRANSACCION YA ANULA", ("94", "La transacción ya fue anulada previamente") },
{ "TRANS. NO ENCONTRADA", ("94", "La transacción no fue encontrada") },
{ "LOTE VACIO", ("94", "El lote está vacío") },
{ "TIEMPO DE ESPERA AGO", ("94", "No se obtuvo respuesta del pinpad") },
{"TARJETA NO COINCIDE", ("94","Tarjeta no coincide") }
};
private TransaccionResponse ValidarResultado(string resultado)
{
var resultadoNormalizado = Normalizar(resultado);
foreach (var error in ERRORES)
{
var clave = Normalizar(error.Key);
if (resultadoNormalizado.Contains(clave))
{
return CrearError(error.Value.Codigo, error.Value.Mensaje);
}
}
return null; // todo OK
}
private string Normalizar(string texto)
{
if (string.IsNullOrEmpty(texto))
return string.Empty;
return Regex.Replace(
texto.ToUpperInvariant().Replace(".", ""),
@"\s+",
" "
).Trim();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>D:\Discod\SelfCheckout\Proyecto DIFARE\Integration_pinpad_difare\Integration_pinpad_difare\app_datafono_difare\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
</Project>
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment