Closed PyrusSp closed 3 years ago
Hola, lo que puedes hacer es enviarlo como parámetro la IP tal vez codificada en el parámetro Ds_MerchantData y luego al retornar ese dato el Banco poder decodificarlo y guardarlo.
Gracias. Buena idea. Lo probaré. Aunque no es muy lógico usar MerchantData para trasladar "ClientData" o "CustomerData".
Ya pero es lo que se me ocurre de momento, ya me contaras que tal.
Probado y funcionando. Le he pasado como parámetro _DS_MERCHANTMERCHANTDATA un JSON, resultado de serializar un objeto. Así se pueden pasar otros valores a parte de la IP, siempre y cuando no te pases de la longitud máxima (1024). Ojo, la respuesta _DsMerchantData devuelve el mismo JSON pero codificado. Hay que pasarle antes html_entity_decode() (creo que es lo que se usa para PHP) antes de analizar el objeto.
Muchas gracias @ssheduardo
Genial, si puedes poner el ejemplo para que le sirva a otro genial.
Sí, pero está en C#. Pay.cs
using System.Web.Script.Serialization;
using RedsysAPIPrj;
namespace TPV
{
public class Pay
{
private RedsysAPI r;
private readonly string ip = IPAddress.Parse(HttpContext.Current.Request.UserHostAddress).ToString();
...
public string MerchantParameters {
get {
var jss = new JavaScriptSerializer();
...
r.SetParameter("DS_MERCHANT_MERCHANTDATA", jss.Serialize(new MerchantData { IPClient = this.ip }));
return r.createMerchantParameters();
}
}
...
}
...
}
Response.cs
using Newtonsoft.Json;
using RedsysAPIPrj;
namespace TPV
{
public class Response
{
public static (bool valid, string message) IsValidResponse() { ... }
private static Dictionary<string, string> GetResponseParameters(string json) { ... }
public static (bool valid, string message) SaveTransaction(SqlConnection sqlConnection) {
var (valid, message) = IsValidResponse();
if (!valid) { return (valid, message); }
Dictionary<string, string> dParams = GetResponseParameters(message);
int ds_response = int.Parse(dParams["Ds_Response"]);
bool accepted = (ds_response < 100);
bool blockIP = (200 <= ds_response && ds_response < 300);
string decodeMerchantParameters = message;
string commandText = @"...";
int rowsAffected;
using (sqlConnection)
{
using (SqlCommand cmd = new SqlCommand(commandText, sqlConnection)) {
cmd.CommandType = CommandType.Text;
...
cmd.Parameters.AddWithValue("@ip", JsonConvert.DeserializeObject<MerchantData>(HttpUtility.HtmlDecode(dParams["Ds_MerchantData"])).IPClient);
cmd.Connection.Open();
rowsAffected = cmd.ExecuteNonQuery();
if (blockIP) {
cmd.CommandText = @"...";
cmd.ExecuteNonQuery();
}
}
}
...
}
}
}
Buenas. Estaba haciendo algo muy parecido sólo que para C#. No obstante creo que resolvería igual. Según el manual, cuando en la notificación asíncrona se reciba un Ds_Response del tipo 2XX, hay que gestionar (almacenar en base de datos, por ejemplo) la IP del cliente porque es un código de posible fraude. En los parámetros enviados no se indica la IP, aunque sí es un dato que almacena el TPV como se puede ver al acceder al módulo de administración. Me he puesto en contacto con soporte y me indican que es algo que tengo que resolver yo en el código de la página de notificación, pero aunque les he dicho que a esa página se conecta el banco, no el cliente, porque estoy usando el modo de redirección, no me explican cómo. ¿Has podido gestionar este tipo de respuestas? ¿Habría que recurrir a almacenar la IP antes de hacer la redirección a la pasarela? Gracias y un saludo