phpcurlopayo3d-secure

3DSv2 always returns Status=OK even when attempting to force 3D-Secure


I am attempting to get 3DSv2 set up, and am currently in a test environment.

Client URL (cURL)

$paymentUrl = 'https://test.sagepay.com/gateway/service/vspdirect-register.vsp';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $paymentUrl);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);

$curlResponse = curl_exec($ch);
$response = generateResponseArray($curlResponse);
var_dump($response);

function generateResponseArray($response)
{
    $output = [];

    $tempArray = explode(chr(10), $response);
    foreach ($tempArray as $row) {
        list($key, $value) = explode('=', $row, 2);
        $output[$key] = trim($value);
    }

    return $output;
}

Included in my $postData are the following items:

Apply3DSecure=1 // Force 3DS Challenge
CardNumber=4929000005559 // VERes = N

Response

array(15) {
  ["VPSProtocol"]=>
  string(4) "4.00"
  ["Status"]=>
  string(2) "OK"
  ["StatusDetail"]=>
  string(40) "0000 : The Authorisation was Successful."
  ["VPSTxId"]=>
  string(38) "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
  ["SecurityKey"]=>
  string(10) "XXXXXXXXXX"
  ["TxAuthNo"]=>
  string(7) "XXXXXXX"
  ["AVSCV2"]=>
  string(24) "SECURITY CODE MATCH ONLY"
  ["AddressResult"]=>
  string(10) "NOTMATCHED"
  ["PostCodeResult"]=>
  string(10) "NOTMATCHED"
  ["CV2Result"]=>
  string(7) "MATCHED"
  ["3DSecureStatus"]=>
  string(2) "OK"
  ["CAVV"]=>
  string(28) "TnVqajA3TjdxTjhrRGFIMWROTzI="
  ["DeclineCode"]=>
  string(2) "00"
  ["ExpiryDate"]=>
  string(4) "0225"
  ["BankAuthCode"]=>
  string(6) "999777"
}

Shouldn't my status be coming back as 3DAUTH at this point? I need to continue building our 3D-Secure system, but this payment shouldn't have an OK status here.

We have a rule set up in Sage Pay to require 3D-Secure on payments over 500 GBP. This one is.

This is the document I am working from: Direct Integration and Protocol 4 Guidelines


Solution

  • In the Sagepay Test environment, you need to send through a valid test card number (I use 4462 0000 000 0003), and crucially the CardHolder set to CHALLENGE.

    If you don't do this, the transaction will still go through 3-D Secure, but it will be frictionless (i.e the user won't see any iframes etc etc). You'll still get liability shift for frictionless transactions.

    Also note you can use the CardHolder field to test other scenarios. Here is a complete list: