private bool VerifySignature(System.Collections.Specialized.NameValueCollection form, string signedFieldNames, string receivedSignature)
{
var signedFields = signedFieldNames.Split(',');
var keyValuePairs = new List<string>();
foreach (var field in signedFields)
{
keyValuePairs.Add($"{field}={form[field]}");
}
string dataToSign = string.Join(",", keyValuePairs);
string secretKey = ConfigurationManager.AppSettings["CyberSource_SecretKey"];
using (var hmac = new System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(secretKey)))
{
var computedSignature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(dataToSign)));
return computedSignature == receivedSignature;
}
}
private string GenerateSignature(CheckoutModel model, string[] signedFields)
{
var keyValuePairs = new List<string>();
foreach (var field in signedFields)
{
string value = GetFieldValue(model, field);
keyValuePairs.Add($"{field}={value}");
}
string dataToSign = string.Join(",", keyValuePairs);
string secretKey = ConfigurationManager.AppSettings["CyberSource_SecretKey"];
byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);
byte[] dataBytes = Encoding.UTF8.GetBytes(dataToSign);
using (var hmac = new HMACSHA256(keyBytes))
{
return Convert.ToBase64String(hmac.ComputeHash(dataBytes));
}
}
private string GetFieldValue(CheckoutModel model, string fieldName)
{
// Map CyberSource form field names to model properties
switch (fieldName)
{
case "access_key": return model.AccessKey;
case "profile_id": return model.ProfileId;
case "transaction_uuid": return model.TransactionUUID;
case "signed_field_names": return model.SignedFieldNames;
case "unsigned_field_names": return model.UnsignedFieldNames;
case "signed_date_time": return model.SignedDateTime;
case "locale": return model.Locale;
case "transaction_type": return model.TransactionType;
case "amount": return model.Amount;
case "currency": return model.Currency;
case "reference_number": return model.ReferenceNumber;
case "customer_email":
case "bill_to_email": return model.CustomerEmail;
case "bill_to_forename": return model.BillingFirstName;
case "bill_to_surname": return model.BillingLastName;
case "bill_to_address_line1": return model.BillingAddress;
case "bill_to_address_city": return model.BillingCity;
case "bill_to_address_state": return model.BillingState;
case "bill_to_address_postal_code": return model.BillingPostalCode;
case "bill_to_address_country": return model.BillingCountry;
default: return "";
}
}
@model Ecommerce.ViewModels.CheckoutModel
@{
Layout = null;
}
<h2>Redirecting to Secure Checkout...</h2>
<p>Please wait while we redirect you to the payment gateway...</p>
@Html.Hidden("access_key", Model.AccessKey)
@Html.Hidden("profile_id", Model.ProfileId)
@Html.Hidden("transaction_uuid", Model.TransactionUUID)
@Html.Hidden("signed_field_names", Model.SignedFieldNames)
@Html.Hidden("unsigned_field_names", Model.UnsignedFieldNames)
@Html.Hidden("signed_date_time", Model.SignedDateTime)
@Html.Hidden("locale", Model.Locale)
@Html.Hidden("transaction_type", Model.TransactionType)
@Html.Hidden("amount", Model.Amount)
@Html.Hidden("currency", Model.Currency)
@Html.Hidden("reference_number", Model.ReferenceNumber)
@Html.Hidden("signature", Model.Signature)
@Html.Hidden("override_custom_receipt_page", Model.ReturnUrl)
@Html.Hidden("override_custom_cancel_page", Model.CancelUrl)
<!-- Customer and billing fields -->
@Html.Hidden("customer_email", Model.CustomerEmail)
@Html.Hidden("bill_to_forename", Model.BillingFirstName)
@Html.Hidden("bill_to_surname", Model.BillingLastName)
@Html.Hidden("bill_to_email", Model.CustomerEmail)
@Html.Hidden("bill_to_address_line1", Model.BillingAddress)
@Html.Hidden("bill_to_address_city", Model.BillingCity)
@Html.Hidden("bill_to_address_state", Model.BillingState)
@Html.Hidden("bill_to_address_postal_code", Model.BillingPostalCode)
@Html.Hidden("bill_to_address_country", Model.BillingCountry)
<!-- Optional: In case JavaScript is disabled -->
<noscript>
<input type="submit" value="Click here to proceed if not redirected automatically" />
</noscript>
</form>
<script type="text/javascript">
window.onload = function () {
document.forms[0].submit();
};
</script>