Could someone confirm if the Sermepa payment module (Spain) version Nop 3.60 can use SHA-256?
Redsys warns that from 23/11/2015 SHA-256 will replace the obsolete SHA-1 and the key change will be necessary.
public void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest)
{
//**********
//PARAMETERS
//**********
//Notificación On-Line
string strDs_Merchant_MerchantURL = _webHelper.GetStoreLocation(false) + "Plugins/PaymentSermepa/Return";
//URL OK
string strDs_Merchant_UrlOK = _webHelper.GetStoreLocation(false) + "checkout/completed";
//URL KO
string strDs_Merchant_UrlKO = _webHelper.GetStoreLocation(false) + "Plugins/PaymentSermepa/Error";
//Numero de pedido
//You have to change the id of the orders table to begin with a number of at least 4 digits.
string strDs_Merchant_Order = postProcessPaymentRequest.Order.Id.ToString("0000");
//Nombre del comercio
string strDs_Merchant_MerchantName = _sermepaPaymentSettings.NombreComercio;
//Importe
string amount = ((int)Convert.ToInt64(postProcessPaymentRequest.Order.OrderTotal * 100)).ToString();
string strDs_Merchant_Amount = amount;
//Código de comercio
string strDs_Merchant_MerchantCode = _sermepaPaymentSettings.FUC;
//Moneda
string strDs_Merchant_Currency = _sermepaPaymentSettings.Moneda;
//Terminal
string strDs_Merchant_Terminal = _sermepaPaymentSettings.Terminal;
//Tipo de transaccion (0 - Autorización)
string strDs_Merchant_TransactionType = "0";
//Clave
string clave = "";
if (_sermepaPaymentSettings.Pruebas)
{
clave = _sermepaPaymentSettings.ClavePruebas;
}
else
{
clave = _sermepaPaymentSettings.ClaveReal;
}
//Creamos el POST
var remotePostHelper = new RemotePost();
remotePostHelper.FormName = "form1";
remotePostHelper.Url = GetSermepaUrl();
//*******************************************************************
//Create a JSON string with above parameters and convert it to base64
//Ds_MerchantParameters
//*******************************************************************
var merchantParameters = new
{
Ds_Merchant_MerchantName = strDs_Merchant_MerchantName,
Ds_Merchant_Amount = strDs_Merchant_Amount,
Ds_Merchant_Order = strDs_Merchant_Order,
Ds_Merchant_MerchantCode = strDs_Merchant_MerchantCode,
Ds_Merchant_Currency = strDs_Merchant_Currency,
Ds_Merchant_TransactionType = strDs_Merchant_TransactionType,
Ds_Merchant_Terminal = strDs_Merchant_Terminal,
Ds_Merchant_MerchantURL = strDs_Merchant_MerchantURL,
Ds_Merchant_UrlOK = strDs_Merchant_UrlOK,
Ds_Merchant_UrlKO = strDs_Merchant_UrlKO
};
string strDs_MerchantParameters = JsonConvert.SerializeObject(merchantParameters);
strDs_MerchantParameters = Convert.ToBase64String(Encoding.UTF8.GetBytes(strDs_MerchantParameters));
//****************
//Create signature
//Ds_Signature
//****************
//Get 3DES key
byte[] key3DES;
using (var tdes = new TripleDESCryptoServiceProvider())
{
tdes.Key = Convert.FromBase64String(clave);
tdes.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
var cTransform = tdes.CreateEncryptor();
var orderByteArray = Encoding.UTF8.GetBytes(strDs_Merchant_Order);
key3DES = cTransform.TransformFinalBlock(orderByteArray, 0, orderByteArray.Length);
}
//Get HMAC SHA256 signature with 3DES key and DS_MerchantParameters value
string strDs_Signature;
using (var hmac = new HMACSHA256(key3DES))
{
strDs_Signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(strDs_MerchantParameters)));
}
remotePostHelper.Add("Ds_SignatureVersion", "HMAC_SHA256_V1");
remotePostHelper.Add("Ds_MerchantParameters", strDs_MerchantParameters);
remotePostHelper.Add("Ds_Signature", strDs_Signature);
remotePostHelper.Post();
}
public ActionResult Return(FormCollection form)
{
var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.Sermepa") as SermepaPaymentProcessor;
if (processor == null ||
!processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
throw new NopException("Sermepa module cannot be loaded");
string version = Request["Ds_SignatureVersion"];
string data = Request["Ds_MerchantParameters"];
string receivedSignature = Request["Ds_Signature"];
string decodeData = Encoding.UTF8.GetString(Convert.FromBase64String(data));
var objData = JsonConvert.DeserializeObject<IDictionary<string, string>>(decodeData);
//ID de Pedido
string orderId = objData["Ds_Order"];
string strDs_Merchant_Order = objData["Ds_Order"];
string strDs_Merchant_Amount = objData["Ds_Amount"];
string strDs_Merchant_MerchantCode = objData["Ds_MerchantCode"];
string strDs_Merchant_Currency = objData["Ds_Currency"];
//Respuesta del TPV
string str_Merchant_Response = objData["Ds_Response"];
int Ds_Response = Convert.ToInt32(objData["Ds_Response"]);
//Clave
bool pruebas = _sermepaPaymentSettings.Pruebas;
string clave = "";
if (pruebas) { clave = _sermepaPaymentSettings.ClavePruebas; }
else { clave = _sermepaPaymentSettings.ClaveReal; };
//Calculo de la firma
//Get 3DES key
byte[] key3DES;
using (var tdes = new TripleDESCryptoServiceProvider())
{
tdes.Key = Convert.FromBase64String(clave);
tdes.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
tdes.Mode = CipherMode.CBC;
tdes.Padding = PaddingMode.Zeros;
var cTransform = tdes.CreateEncryptor();
var orderByteArray = Encoding.UTF8.GetBytes(strDs_Merchant_Order);
key3DES = cTransform.TransformFinalBlock(orderByteArray, 0, orderByteArray.Length);
tdes.Clear();
}
//Get HMAC SHA256 signature with 3DES key and DS_MerchantParameters value
string signature;
using (var hmac = new HMACSHA256(key3DES))
{
signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(data)));
signature = signature.Replace("+", "-").Replace("/", "_");
}
//Firma enviada
string recivedSignature = CommonHelper.EnsureNotNull(receivedSignature);
//Comprobamos la integridad de las comunicaciones con las claves
//LogManager.InsertLog(LogTypeEnum.OrderError, "TPV SERMEPA: Clave generada", "CLAVE GENERADA: " + SHAresultStr);
//LogManager.InsertLog(LogTypeEnum.OrderError, "TPV SERMEPA: Clave obtenida", "CLAVE OBTENIDA: " + signature);
if (!recivedSignature.Equals(signature))
{
_logger.Error("TPV SERMEPA: Clave incorrecta. Las claves enviada y generada no coinciden: " + receivedSignature + " != " + signature);
return RedirectToAction("Index", "Home", new { area = "" });
}
//Pedido
var order = _orderService.GetOrderById(Convert.ToInt32(orderId));
if (order == null)
throw new NopException(string.Format("El pedido de ID {0} no existe", orderId));
//Actualizamos el pedido
if (Ds_Response > -1 && Ds_Response < 100)
{
//Lo marcamos como pagado
if (_orderProcessingService.CanMarkOrderAsPaid(order))
{
_orderProcessingService.MarkOrderAsPaid(order);
}
//order note
order.OrderNotes.Add(new OrderNote()
{
Note = "Información del pago: " + decodeData,
DisplayToCustomer = false,
CreatedOnUtc = DateTime.UtcNow
});
_orderService.UpdateOrder(order);
return RedirectToRoute("CheckoutCompleted");
}
else
{
_logger.Error("TPV SERMEPA: Pago no autorizado con ERROR: " + Ds_Response);
//order note
order.OrderNotes.Add(new OrderNote()
{
Note = "!!! PAGO DENEGADO !!! " + decodeData,
DisplayToCustomer = false,
CreatedOnUtc = DateTime.UtcNow
});
_orderService.UpdateOrder(order);
return RedirectToAction("Index", "Home", new { area = "" });
}
}