A test page to illustrate how to implement a PHP solution and effectively
test a SagePAY Form Integration. Read on…
SagePAY Form Integration - how to avoid the gotchas!
SagePAY has currently (as of Nov 2013) removed all the Integration Kits for
server solutions other than .net and Java. For those of you using PHP, Python
or any other Open Source solution it appears, from the Technical Support
people I have spoken to over the last few days, that they are refusing to
help solve any integration issues you may experience. This appears to be a
...and it is not just because the currency code is missing; it may be because
your encryption is wrong. Having built some nice integration classes and prepared
the data nicely, I thought it was going to be easy to integrate with SagePAY.
Unfortunately it is not if you do not know exactly what to do.
Default behaviour of PHP breaks the SagePAY integration; SagePAY's limited
instructions are wrong and if you do not pass the currency code as part of
your test string then you will never know when it is working or when it isn't.
SagePAY's server response does differentiate between an encryption issue or
a data issue.
The first problem is the mcrypt_generic function. Do not rely on it to pad
your plain text string - i.e. the string you want to encrypt. You have to
pad the string yourself before passing it to the mcrypt_generic function.
Secondly, do not use the base64_encode function as this does not work. Use
bin2hex function instead.
Thirdly, ensure you pass a valid name-value-pair currency value through as
part of your string. e.g. Currency=GBP. This ensures that you will not be
misled by the erroneous error code SagePAY issues.
Fourthly, prefix your encrypted string with an @ sign. Do all of those and
you should be OK.
Summary - see full code sample below
- Pad your plain text string to 16 byte multiples.
- Do not base64_encode function...
- ...use bin2hex instead
- Pass Currency=GBP (or equivalent) through on your test string
- Prefix your encryption string with an @
function pkcs5_pad($text, $blocksize)
$pad = $blocksize - (strlen($text) % $blocksize);
//echo "<br/>Padding:".str_repeat(chr($pad), $pad)."<";
return $text . str_repeat(chr($pad), $pad);
$key = "use your SagePAY encryption key here";
$iv = $key;
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, "", MCRYPT_MODE_CBC, "");
if (mcrypt_generic_init($cipher, $key, $iv) != -1)
$cipherText = mcrypt_generic($cipher,$input );
$enc = bin2hex($cipherText);
$str = "Currency=GBP";
$datapadded = pkcs5_pad($str,16);
$cryptpadded = "@" . encryptFieldData($datapadded);
<form name="pp_form" action="SagePay test url" method="post">
<input name="VPSProtocol" type="hidden" value=3.00 />
<input name="TxType" type="hidden" value=PAYMENT />
<input name="Vendor" type="hidden" value="YOUR SAGEPAY ACCOUNT NAME HERE" />
<input name="Crypt" type="hidden" value=<?php echo $cryptpadded;?> />
<p>Click here to submit
<input type="submit" value="here">