Reputation: 199
I'm having a lot of trouble integrating Sagepay InFrame Server with PHP, as there are no integration kits available for the new protocol (v3). I have the old kits for v2.23 but much of the code therein is deprecated.
At the moment the only way i have been successful in retrieving an OK status from the Sagepay Server servers is to have a form with the collection of hidden values required by Sagepay, including the cryptography field, and using the server URL as the form action. This gives me a status of 'OK' and the SecurityKey etc in the browser tab, but its not much use in the browser tab as i need that POST response back on my server, not on theirs.
For this i opted for curl. I hold the return values for curl_exec in a variable called $rawresponse, and dump the response after each attempt, and as it stands $rawresponse is returning as a false boolean:
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
$data['Crypt'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 0);
$rawresponse = curl_exec($curlSession);
Now as you can see here I am having to force the Crypt value to be of type CurlFile, which is what i think is breaking the request, however if i dont do that i get the following error:
"The usage of the @filename API for file uploading is deprecated. Please use the CURLFile class instead"
I can only ascertain from this that the cryptography is being mistaken for a file (possibly because the string starts with @), and to counter this im trying to force it to be an image.
So my question is this - is there a particular way to use CurlFile so cryptography strings can be understood? Is there a better way of integrating this functionality with Sagepay that anyone knows about? It really is a very confusing system, and the good documentation is let down by a complete lack of example.
Upvotes: 0
Views: 894
Reputation: 199
Apologies for this, I was building the string the wrong way. Just in case anyone has a similar problem in the future i'll paste the code that works for me:
public function registerTransaction()
{
$VPSProtocol = urlencode($_POST['VPSProtocol']);
$TxType = urlencode($_POST['TxType']);
$Vendor = urlencode($_POST['Vendor']);
$VendorTxCode = urlencode($_POST['VendorTxCode']);
$Currency = urlencode($_POST['Currency']);
$Amount = urlencode($_POST['Amount']);
$NotificationURL = urlencode($_POST['NotificationURL']);
$Description = urlencode($_POST['Description']);
$BillingSurname = urlencode($_POST['BillingSurname']);
$BillingFirstnames = urlencode($_POST['BillingFirstnames']);
$BillingAddress1 = urlencode($_POST['BillingAddress1']);
$BillingCity = urlencode($_POST['BillingCity']);
$BillingPostCode = urlencode($_POST['BillingPostCode']);
$BillingCountry = urlencode($_POST['BillingCountry']);
$DeliverySurname = urlencode($_POST['DeliverySurname']);
$DeliveryFirstnames = urlencode($_POST['DeliveryFirstnames']);
$DeliveryAddress1 = urlencode($_POST['DeliveryAddress1']);
$DeliveryCity = urlencode($_POST['DeliveryCity']);
$DeliveryPostCode = urlencode($_POST['DeliveryPostCode']);
$DeliveryCountry = urlencode($_POST['DeliveryCountry']);
$url = "?VPSProtocol=" . $VPSProtocol;
$url .= "&TxType=" . $TxType;
$url .= "&Vendor=" . $Vendor;
$url .= "&VendorTxCode=" . $VendorTxCode;
$url .= "&Currency=" . $Currency;
$url .= "&Amount=" . $Amount;
$url .= "&NotificationURL=" . $NotificationURL;
$url .= "&Description=" . $Description;
$url .= "&BillingSurname=" . $BillingSurname;
$url .= "&BillingFirstnames=" . $BillingFirstnames;
$url .= "&BillingAddress1=" . $BillingAddress1;
$url .= "&BillingCity=" . $BillingCity;
$url .= "&BillingPostCode=" . $BillingPostCode;
$url .= "&BillingCountry=" . $BillingCountry;
$url .= "&DeliverySurname=" . $DeliverySurname;
$url .= "&DeliveryFirstnames=" . $DeliveryFirstnames;
$url .= "&DeliveryAddress1=" . $DeliveryAddress1;
$url .= "&DeliveryCity=" . $DeliveryCity;
$url .= "&DeliveryPostCode=" . $DeliveryPostCode;
$url .= "&DeliveryCountry=" . $DeliveryCountry;
$strPurchaseURL = "https://test.sagepay.com/gateway/service/vspserver-register.vsp";
$arrResponse = $this->requestPost($strPurchaseURL, $url);
dd($arrResponse);
}
public function requestPost($url, $data){
// Set a one-minute timeout for this script
set_time_limit(60);
// Initialise output variable
$output = array();
// Open the cURL session
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2);
$rawresponse = curl_exec($curlSession);
dd($rawresponse);
//Store the raw response for later as it's useful to see for integration and understanding
$_SESSION["rawresponse"]=$rawresponse;
//Split response into name=value pairs
$response = preg_split(chr(10), $rawresponse);
// Check that a connection was made
if (curl_error($curlSession)){
// If it wasn't...
$output['Status'] = "FAIL";
$output['StatusDetail'] = curl_error($curlSession);
}
// Close the cURL session
curl_close ($curlSession);
// Tokenise the response
for ($i=0; $i<count($response); $i++){
// Find position of first "=" character
$splitAt = strpos($response[$i], "=");
// Create an associative (hash) array with key/value pairs ('trim' strips excess whitespace)
$output[trim(substr($response[$i], 0, $splitAt))] = trim(substr($response[$i], ($splitAt+1)));
} // END for ($i=0; $i<count($response); $i++)
// Return the output
return $output;
} // END function requestPost()
Upvotes: 1