I am using a signing string and a private key to generate a public key using SHA-256 encryption.
The hashing function is a standard C# SHA-256 hashing function:
string CalculateHMAC256(string hmacKey, string signingstring)
{
byte[] key = Encoding.UTF8.GetBytes(hmacKey);
byte[] data = Encoding.UTF8.GetBytes(signingstring);
using (HMACSHA256 hmac = new HMACSHA256(key))
{
byte[] result = hmac.ComputeHash(data);
return Convert.ToBase64String(result);
}
}
The string signature looks like this: allowedMethods:blockedMethods:countryCode:currencyCode:merchantAccount:merchantReference:offset:orderData:paymentAmount:sessionValidity:shipBeforeDate:shopperEmail:shopperLocale:shopperReference:skinCode:::GB:GBP:MyTest:abc:::1:2017-04-28T15:07:10+01:00:2017-04-30::en_US::neDRF4H4
I have also tried this with escaped ':' as advised: allowedMethods:blockedMethods:countryCode:currencyCode:merchantAccount:merchantReference:offset:orderData:paymentAmount:sessionValidity:shipBeforeDate:shopperEmail:shopperLocale:shopperReference:skinCode:::GB:GBP:MyTest:abc:::1:2017-04-29T13:34:48+01:00:2017-05-01::en_US::neDRF4H4
And then my html form looks like this:
<form ngNoForm name="frmsp" id="frmsp" target="_blank"
action="https://test.barclaycardsmartpay.com/hpp/pay.shtml"
method="post">
<input type="hidden" name="merchantSig" [value]="merchantSignature" />
<input type="hidden" name="currencyCode" [value]="smartPayment?.currencyCode" />
<input type="hidden" name="merchantAccount" [value]="smartPayment?.merchantAccount" />
<input type="hidden" name="merchantReference" [value]="smartPayment?.merchantReference" />
<input type="hidden" name="paymentAmount" [value]="smartPayment?.paymentAmount" />
<input type="hidden" name="sessionValidity" [value]="smartPayment?.sessionValidity" />
<input type="hidden" name="shipBeforeDate" [value]="smartPayment?.shipBeforeDate" />
<input type="hidden" name="shopperLocale" [value]="smartPayment?.shopperLocale" />
<input type="hidden" name="orderData" [value]="smartPayment?.orderData" />
<input type="hidden" name="skinCode" [value]="smartPayment?.skinCode" />
<input type="hidden" name="countryCode" [value]="smartPayment?.countryCode" />
<input type="hidden" name="shopperEmail" [value]="smartPayment?.shopperEmail" />
<input type="hidden" name="shopperReference" [value]="smartPayment?.shopperReference" />
<input type="hidden" name="allowedMethods" [value]="smartPayment?.allowedMethods" />
<input type="hidden" name="blockedMethods" [value]="smartPayment?.blockedMethods" />
<input type="hidden" name="offset" [value]="smartPayment?.offset" />
<input type="submit" value="Process Payment" (click)="buttonClicked()">
Where the fields values are being calculated with angular2 - using the same ones used to build the signing string, so I am confident that the data matches.
When I send the form, I get an error stating that the merchant signature is incorrect.
Perhaps the format of the signing string could be incorrect? I am trying to implement a call to Barclaycard Smartpay using hosted payment. Documentation here: Hosted Payment Page Integration Guide
Note: that the barclays documentation is out of date (last updated 2012) and that the references to SHA-1 are now using SHA-256. It is built using Adyen payment systems and I have reused the string generation examples using the following example code: https://github.com/Adyen/adyen-asp.net-sample-code
There is a problem with your signing string. You need to replace "\" with "\" and ":" with ":" in all your vallues.
I also suggest to use the code from this sample on GIT to generate create your encrypted signature.
Using the code below I get the same signature as on the test page provided by Adyen.
// Computes the Base64 encoded signature using the HMAC algorithm with the HMACSHA256 hashing function.
string CalculateHMAC(string hmacKey, string signingstring)
{
byte[] key = PackH(hmacKey);
byte[] data = Encoding.UTF8.GetBytes(signingstring);
try
{
using (HMACSHA256 hmac = new HMACSHA256(key))
{
// Compute the hmac on input data bytes
byte[] rawHmac = hmac.ComputeHash(data);
// Base64-encode the hmac
return Convert.ToBase64String(rawHmac);
}
}
catch (Exception e)
{
throw new Exception("Failed to generate HMAC : " + e.Message);
}
}
byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1)
{
hex += '0';
}
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
Try to use only a limited amound of fields and see if you get any results. I used the fields below (also take their order into account!)
currencyCode:merchantAccount:merchantReference:paymentAmount:sessionValidity:shipBeforeDate:shopperLocale:skinCode