Search code examples
opayo

Sagepay notification response fails with 5003


I have had some trouble with my SagePay integration at the moment. Everything works great up until I have to respond to the notification POST. My scripts respond to the notification post with correct information but I actually get a 5003 Internal Server Error back (in amongst other html) from SagePay.

I have rang SagePay support many times and had the logs checked for a couple of transactions and I can see that SagePay is not getting the POST data I am sending at all, which makes sense as I am getting this 5003 error back. I have confirmed that the notificationURL I give to SagePay earlier in the process works and SagePay is able to contact that URL successfully.

Below is the relevant code that sends my response to SagePay, this is also the same code that performs the initial communication with SagePay which works with no trouble:

    curl_setopt($curlSession, CURLOPT_URL, $url);
    curl_setopt($curlSession, CURLOPT_HEADER, 0);
    curl_setopt($curlSession, CURLOPT_POST, 1);
    curl_setopt($curlSession, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curlSession, CURLOPT_TIMEOUT, $ttl);
    curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2);

    if (!empty($caCertPath))
    {
        curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($curlSession, CURLOPT_CAINFO, $caCertPath);
    } 
    else
    {
        curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, 0);
    }

    $rawresponse = curl_exec($curlSession);

Here is a sample of the data that could be sent, the only variation is that the Status can be OK and the RedirectURL could point to checkout_thanks.php instead:

$data['Status'] = 'ERROR';
$data['StatusDetail'] = 'Transaction not found in our system';
$data['RedirectURL'] = 'https://www.e-side.co.uk/checkout_error.php';

As I have said I have it set so that the $rawresponse variable actually gets e-mailed to me so I can see the response which I put into PasteBin here: http://pastebin.com/73107ga

I just wanted to add that all of the links used are https versions and there is a valid SSL certificate in the site I am trying to integrate this onto.

Thanks


Solution

  • Ok so after much back and forth with SagePay support over the past couple weeks I have got it to work. There were two problems that caused the error.

    First (and this isn't clear above) but the data being sent to SagePay was being separated with & symbols, the notification request stage requires carriage-return-linefeeds (CRLF) instead.

    So changing the part that builds the string to http_build_query($data, "\n") solved that. A small note: in my research I found that the CRLF character was actually \r\n and not just the \n. Looking through the SagePay dev kits that they provide they just use \n so I went with that to ensure it worked.

    The next issue was that I was posting this notification request back to SagePay in the same way that I initiated the whole process using curl, however it turns out that you don't need to send a curl request at all and only echo out the data as SagePay will read it as its response to it contacting the notificationURL. so the final code now looks like this:

    $responseData = arrayToQueryString($data, "\n");
    if ($notificationResponse) {
            echo $responseData; //This line is very very important
            return;             
        } 
    

    You may notice I also swapped the data function to one that SagePay provide in there dev kit the arrayToQueryString($data, "\n") does exactly the same job as http_build_query($data, "\n") that I mentioned above.