public IMDResponse <EntOrder> CCreateOrder([FromBody] EntCreateOrder entCreateOrder) { IMDResponse <EntOrder> response = new IMDResponse <EntOrder>(); string metodo = nameof(this.CCreateOrder); logger.Info(IMDSerialize.Serialize(67823458121356, $"Inicia {metodo}([FromBody]EntCreateOrder entCreateOrder)", entCreateOrder)); try { response = busOrder.BCreateOrder(entCreateOrder); } catch (Exception ex) { response.Code = 67823458122133; response.Message = "No pudimos procesar el pago de tu pedido, revisa nuevamente los datos ingresados o intenta con otra tarjeta."; logger.Error(IMDSerialize.Serialize(67823458122133, $"Error en {metodo}([FromBody]EntCreateOrder entCreateOrder): {ex.Message}", entCreateOrder, ex, response)); } return(response); }
public IMDResponse<EntDetalleCompra> CNuevoFolio([FromBody] EntCreateOrder entCreateOrder) { IMDResponse<EntDetalleCompra> response = new IMDResponse<EntDetalleCompra>(); string metodo = nameof(this.CNuevoFolio); logger.Info(IMDSerialize.Serialize(67823458413508, $"Inicia {metodo}([FromBody]EntConecktaPago entConecktaPago)", entCreateOrder)); try { BusFolio busFolio = new BusFolio(); response = busFolio.BNuevoFolioCompra(entCreateOrder); } catch (Exception ex) { response.Code = 67823458414285; response.Message = "Ocurrió un error inesperado en el servicio al generar los folios del cliente."; logger.Error(IMDSerialize.Serialize(67823458414285, $"Error en {metodo}([FromBody]EntConecktaPago entConecktaPago): {ex.Message}", entCreateOrder, ex, response)); } return response; }
/// <summary> /// Función: Consume el servicio de Conekta para generar una orden /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="entCreateOrder">Datos de la compra</param> /// <param name="entUserAgent">Agente de usuario del server</param> /// <returns></returns> public IMDResponse <string> SCreateOrder(EntCreateOrder entCreateOrder, EntCreateUserAgent entUserAgent, string[] pPropiedadesOcultar = null) { IMDResponse <string> response = new IMDResponse <string>(); string metodo = nameof(this.SCreateOrder); logger.Info(IMDSerialize.Serialize(67823458103485, $"Inicia {metodo}(EntCreateOrder entCreateOrder, EntCreateUserAgent entUserAgent)", entCreateOrder, entUserAgent)); string mensajePagoError = "No pudimos procesar el pago de tu pedido, revisa nuevamente los datos ingresados o intenta con otra tarjeta."; try { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; HttpWebRequest peticion = (HttpWebRequest)WebRequest.Create(urlServicioConektaCrearOrden); peticion.Accept = $"application/vnd.conekta-v{conketaVersion}+json"; peticion.UserAgent = $"Conekta/v1 DotNetBindings10/Conekta::{conketaVersion}"; peticion.Method = "POST"; byte[] conektaApiKeyBytes = Encoding.UTF8.GetBytes(conketaApiKey); string conektaApiKeyBase64 = Convert.ToBase64String(conektaApiKeyBytes); string agenteUsuarioSerializado = JsonConvert.SerializeObject(entUserAgent); peticion.Headers.Add("Authorization", $"Basic {conektaApiKeyBase64}:"); peticion.Headers.Add("Accept-Language", conektaLocale); peticion.Headers.Add("X-Conekta-Client-User-Agent", agenteUsuarioSerializado); string datosCrearOrdenSerializado = string.Empty; if (pPropiedadesOcultar != null) { datosCrearOrdenSerializado = JsonConvert.SerializeObject(entCreateOrder, new JsonSerializerSettings { ContractResolver = new ServContractResolver(pPropiedadesOcultar) }); } else { datosCrearOrdenSerializado = JsonConvert.SerializeObject(entCreateOrder); } string json = JsonConvert.SerializeObject(entCreateOrder, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new ServContractResolver(pPropiedadesOcultar) }); byte[] bytesDatosCrearOrden = Encoding.UTF8.GetBytes(datosCrearOrdenSerializado); peticion.ContentLength = bytesDatosCrearOrden.Length; peticion.ContentType = "application/json"; Stream peticionStream = peticion.GetRequestStream(); peticionStream.Write(bytesDatosCrearOrden, 0, bytesDatosCrearOrden.Length); HttpWebResponse respuesta = (HttpWebResponse)peticion.GetResponse(); StreamReader respuestaStream = new StreamReader(respuesta.GetResponseStream()); string body = respuestaStream.ReadToEnd(); response.Code = 0; response.Message = "Respuesta de servicio obtenida."; response.Result = body; } catch (WebException webex) { if (webex.Status == WebExceptionStatus.ProtocolError) { HttpWebResponse httpResponse = (HttpWebResponse)webex.Response; string body = string.Empty; using (StreamReader content = new StreamReader(httpResponse.GetResponseStream())) { body = content.ReadToEnd(); } int statusCode = (int)httpResponse.StatusCode; if (statusCode == 402) { //No cambiar response.Code = -1500000; response.Message = "No pudimos procesar el pago, la transacción ha sido declinada. Intente con otra tarjeta o comuníquese con su banco emisor."; response.Result = body; } else { response.Code = 67823458104262; response.Message = mensajePagoError; } } else { response.Code = 67823458104262; response.Message = mensajePagoError; } } catch (Exception ex) { response.Code = 67823458104262; response.Message = mensajePagoError; logger.Error(IMDSerialize.Serialize(67823458104262, $"Error en {metodo}: {ex.Message}(EntCreateOrder entCreateOrder, EntCreateUserAgent entUserAgent)", entCreateOrder, entUserAgent, ex, response)); } return(response); }
/// <summary> /// Función: Crea un orden con los datos de la compra /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="entCreateOrder">Datos de la compra</param> /// <returns>Datos de la orden generada</returns> public IMDResponse <EntOrder> BCreateOrder(EntCreateOrder entCreateOrder) { IMDResponse <EntOrder> response = new IMDResponse <EntOrder>(); string metodo = nameof(this.BCreateOrder); logger.Info(IMDSerialize.Serialize(67823458108147, $"Inicia {metodo}(EntCreateOrder entCreateOrder)", entCreateOrder)); try { string defaultPhoneNumber = "+525555555555"; if (entCreateOrder == null) { response.Code = 67823458112809; response.Message = "No se ingresaron datos de la compra."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.currency)) { response.Code = 67823458217704; response.Message = "No se ingresó el tipo de moneda."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info?.email)) { response.Code = 67823458113586; response.Message = "El correo electrónico es requerido."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info.name)) { response.Code = 45654345434543; response.Message = "El nombre del cliente es requerido."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info.phone)) { entCreateOrder.customer_info.phone = defaultPhoneNumber; } else { entCreateOrder.customer_info.phone = entCreateOrder.customer_info.phone.Replace(" ", ""); if (entCreateOrder.customer_info.phone.Length != 10) { response.Code = 67823458114363; response.Message = "El número de teléfono proporcionado debe tener 10 dígitos."; return(response); } else { entCreateOrder.customer_info.phone = $"{ConfigurationManager.AppSettings["CONEKTA_PHONE_ACCESS"]}{entCreateOrder.customer_info.phone}"; } } if (entCreateOrder.line_items?.Count == 0 || entCreateOrder.line_items == null) { response.Code = 67823458114363; response.Message = "No se ingresaron artículos para generar la orden."; return(response); } foreach (EntCreateLineItem articulo in entCreateOrder.line_items) { if (string.IsNullOrWhiteSpace(articulo?.name) || articulo?.quantity <= 0 || articulo?.unit_price <= 0) { response.Code = 67823458115140; response.Message = "La información de los artículos es incompleta."; return(response); } } string mensajeErrorMetodoPago = "No se ingresó información de pago."; if (entCreateOrder.charges?.Count == 0) { response.Code = 67823458115917; response.Message = mensajeErrorMetodoPago; return(response); } if (entCreateOrder.charges?[0]?.payment_method == null) { response.Code = 67823458116694; response.Message = mensajeErrorMetodoPago; return(response); } entCreateOrder.charges[0].amount = entCreateOrder.line_items.Sum(articulo => articulo.unit_price * articulo.quantity); if (entCreateOrder.charges[0].payment_method.type == "oxxo_cash") { int horasLimitePagoOxxo = 24; try { int configurationHorasLimitePagoOxxo = Convert.ToInt32(ConfigurationManager.AppSettings["CONEKTA_CASH_EXPIRE_HOURS"]); horasLimitePagoOxxo = configurationHorasLimitePagoOxxo <= 0 ? 24 : configurationHorasLimitePagoOxxo; } catch (Exception) { } DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); long unixTimeStampInTicks = (DateTime.Now.AddHours(horasLimitePagoOxxo).ToUniversalTime() - unixStart).Ticks; entCreateOrder.charges[0].payment_method.expires_at = unixTimeStampInTicks / TimeSpan.TicksPerSecond; } else if (entCreateOrder.charges[0].payment_method.type == "card") { if (string.IsNullOrWhiteSpace(entCreateOrder.charges[0].payment_method.token_id)) { response.Code = 67823458117471; response.Message = mensajeErrorMetodoPago; return(response); } } else { response.Code = 67823458118248; response.Message = mensajeErrorMetodoPago; return(response); } long amount = entCreateOrder.charges[0].amount; bool aplicaPromocion = false; string couponCode = null; long discount = 0; if (entCreateOrder.coupon != null) { IMDResponse <EntCupon> respuestaValidarPromocion = busPromociones.BValidarCupon(piIdCupon: entCreateOrder.coupon); if (respuestaValidarPromocion.Code != 0) { entCreateOrder.coupon = null; } else { double porcentajeDescuentoMaximo = Convert.ToDouble(ConfigurationManager.AppSettings["CONEKTA_DESCUENTO_MAXIMO"]); switch (respuestaValidarPromocion.Result.fiIdCuponCategoria) { case (int)EnumCategoriaCupon.DescuentoMonto: double descuentoMaximo = entCreateOrder.charges[0].amount * porcentajeDescuentoMaximo; if (respuestaValidarPromocion.Result.fnMontoDescuento > descuentoMaximo) { respuestaValidarPromocion.Result.fnMontoDescuento = descuentoMaximo; } discount = (long)respuestaValidarPromocion.Result.fnMontoDescuento; entCreateOrder.discount_lines = new List <EntCreateDiscountLine> { new EntCreateDiscountLine { type = "coupon", amount = discount, code = respuestaValidarPromocion.Result.fsCodigo } }; aplicaPromocion = true; couponCode = respuestaValidarPromocion.Result.fsCodigo; break; case (int)EnumCategoriaCupon.DescuentoPorcentaje: if (respuestaValidarPromocion.Result.fnPorcentajeDescuento > porcentajeDescuentoMaximo) { respuestaValidarPromocion.Result.fnPorcentajeDescuento = porcentajeDescuentoMaximo; } discount = (long)(entCreateOrder.charges[0].amount * respuestaValidarPromocion.Result.fnPorcentajeDescuento); entCreateOrder.discount_lines = new List <EntCreateDiscountLine> { new EntCreateDiscountLine { type = "coupon", amount = discount, code = respuestaValidarPromocion.Result.fsCodigo } }; aplicaPromocion = true; couponCode = respuestaValidarPromocion.Result.fsCodigo; break; } } } entCreateOrder.charges[0].amount -= discount; long tax = 0; double taxIVA = Convert.ToDouble(ConfigurationManager.AppSettings["CONEKTA_IMPUESTO"]); if (taxIVA > 0d) { tax = (long)(entCreateOrder.charges[0].amount * taxIVA); entCreateOrder.tax_lines = new List <EntCreateTaxLine> { new EntCreateTaxLine { amount = tax, description = "IVA" } }; } entCreateOrder.charges[0].amount += tax; IMDResponse <EntCreateUserAgent> respuestaObtenerAgenteUsuario = busAgent.BGetUserAgent(); if (respuestaObtenerAgenteUsuario.Code != 0) { return(respuestaObtenerAgenteUsuario.GetResponse <EntOrder>()); } int[] mesesSinInteresesValidos = { 3, 6, 9, 12, 18 }; List <string> ocultarPropiedades = new List <string> { "coupon", "tax", "product_id", "monthsExpiration", "iIdOrigen" }; if (!mesesSinInteresesValidos.Contains(entCreateOrder.charges[0].payment_method.monthly_installments)) { ocultarPropiedades.Add("monthly_installments"); } IMDResponse <string> respuestaServicioCrearOrden = servOrder.SCreateOrder(entCreateOrder, respuestaObtenerAgenteUsuario.Result, ocultarPropiedades.ToArray()); if (respuestaServicioCrearOrden.Code != 0 && respuestaServicioCrearOrden.Code != -1500000) { return(respuestaServicioCrearOrden.GetResponse <EntOrder>()); } ///Guardar respuesta textual del servicio en log ///Intentar convetir la respuesta en la entidad EntOrder ///Si no se puede convertir solo lo dejamos en null pero no se marca error porque la compra ya se abrá realizado logger.Info(IMDSerialize.Serialize(67823458119025, $"Respuesta del servicio pago por Conekta", entCreateOrder, respuestaObtenerAgenteUsuario.Result, respuestaServicioCrearOrden)); EntOrder entOrder = null; try { if (respuestaServicioCrearOrden.Code == 0) { entOrder = JsonConvert.DeserializeObject <EntOrder>(respuestaServicioCrearOrden.Result); } else { EntOrderDeclined entOrderDeclined = JsonConvert.DeserializeObject <EntOrderDeclined>(respuestaServicioCrearOrden.Result); if (entOrderDeclined != null) { entOrder = entOrderDeclined.data; if (entOrder != null) { entOrder.payment_status = entOrder.charges?.data[0]?.status; } } } if (entOrder != null) { entOrder.amount = amount; entOrder.amount_paid = entCreateOrder.charges[0].amount; entOrder.coupon_code = couponCode; entOrder.amount_discount = discount; entOrder.amount_tax = tax; if (entOrder.customer_info?.phone == defaultPhoneNumber) { entOrder.customer_info.phone = null; } } } catch (Exception) { entOrder = null; } string guardarOrdenEnBD = ConfigurationManager.AppSettings["CONEKTA_SAVE_DB"]; if (Convert.ToBoolean(guardarOrdenEnBD) && entOrder != null) { IMDResponse <bool> respuestaGuardarBD = this.BSaveOrder(entOrder, entCreateOrder); if (respuestaGuardarBD.Code != 0) { logger.Error(IMDSerialize.Serialize(67823458119802, $"Error en guardado en base de datos de orden Conekta.", entOrder, respuestaGuardarBD)); } } if (respuestaServicioCrearOrden.Code == -1500000) { response.Code = respuestaServicioCrearOrden.Code; response.Result = entOrder; response.Message = respuestaServicioCrearOrden.Message; } else { if (aplicaPromocion) { IMDResponse <bool> respuestaAplicarCupon = busPromociones.BAplicarCupon((int)entCreateOrder.coupon); if (respuestaAplicarCupon.Code != 0) { logger.Error(IMDSerialize.Serialize(67823458119803, $"Error en aplicar promoción.", entCreateOrder)); } } response.Code = 0; response.Result = entOrder; response.Message = "Orden creada."; } } catch (Exception ex) { response.Code = 67823458108924; response.Message = "No pudimos procesar el pago de tu pedido, revisa nuevamente los datos ingresados o intenta con otra tarjeta."; logger.Error(IMDSerialize.Serialize(67823458108924, $"Error en {metodo}(EntCreateOrder entCreateOrder): {ex.Message}", entCreateOrder, ex, response)); } return(response); }
/// <summary> /// Función: Guarda los datos de la orden generada en la base de datos proporcionada /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="entOrder">Datos de la orden</param> /// <param name="piIdCupon">Cupón si aplicó</param> /// <returns>Guardado correcto</returns> private IMDResponse <bool> BSaveOrder(EntOrder entOrder, EntCreateOrder entCreateOrder) { IMDResponse <bool> response = new IMDResponse <bool>(); string metodo = nameof(this.BSaveOrder); logger.Info(IMDSerialize.Serialize(67823458111255, $"Inicia {metodo}(EntOrder entOrder, int? piIdCupon = null)", entOrder, entCreateOrder)); try { Guid uid = Guid.NewGuid(); string origin = "conekta_service"; //using (TransactionScope scope = new TransactionScope()) //{ IMDResponse <bool> respuestaGuardarOrden = datOrder.DSaveConektaOrder(uid, entOrder, origin, entCreateOrder.iIdOrigen, entCreateOrder.coupon); if (respuestaGuardarOrden.Code != 0) { return(respuestaGuardarOrden); } IMDResponse <bool> respuestaGuardarCliente = datOrder.DSaveCustomerInfo(uid, entOrder.customer_info); if (respuestaGuardarCliente.Code != 0) { return(respuestaGuardarCliente); } int consecutivoArticulo = 0; for (int i = 0; i < entOrder.line_items.data.Count; i++) { EntCreateLineItem itemRef = entCreateOrder.line_items.Find(x => x.name == entOrder.line_items.data[i].name); entOrder.line_items.data[i].consecutive = ++consecutivoArticulo; entOrder.line_items.data[i].product_id = itemRef.product_id; entOrder.line_items.data[i].months_expiration = itemRef.monthsExpiration; IMDResponse <bool> respuestaGuardarArticulo = datOrder.DSaveLineItem(uid, entOrder.line_items.data[i]); if (respuestaGuardarArticulo.Code != 0) { return(respuestaGuardarArticulo); } } IMDResponse <bool> respuestaGuardarDatosPago = datOrder.DSaveCharge(uid, entOrder.charges.data.First(), origin); if (respuestaGuardarDatosPago.Code != 0) { return(respuestaGuardarOrden); } // scope.Complete(); //} response.Code = 0; response.Message = "Guardado completo"; response.Result = true; } catch (Exception ex) { response.Code = 67823458112032; response.Message = "Ocurrió un error inesperado al guardar la información en la base de datos."; logger.Error(IMDSerialize.Serialize(67823458112032, $"Error en {metodo}(EntOrder entOrder, int? piIdCupon = null): {ex.Message}", entOrder, entCreateOrder, ex, response)); } return(response); }