Skip to content

Commit

Permalink
Merge pull request #173 from craftcms/master
Browse files Browse the repository at this point in the history
Update Server and Direct gateways to support protocol version 4.0
  • Loading branch information
barryvdh authored Feb 11, 2022
2 parents 2f47789 + 64e9904 commit 3d93910
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 6 deletions.
30 changes: 29 additions & 1 deletion src/Message/AbstractRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ abstract class AbstractRequest extends OmnipayAbstractRequest implements Constan
{
use GatewayParamsTrait;

/**
* Flag whether customer's browser can run javascript.
*/
const BROWSER_JAVASCRIPT_YES = 1;
const BROWSER_JAVASCRIPT_NO = 0;

/**
* Fallback browser language
*/
const BROWSER_LANGUAGE = 'en-GB';

/**
* Dimensions of the challenge window to be displayed to the cardholder.
*
* 01 = 250 x 400
* 02 = 390 x 400
* 03 = 500 x 600
* 04 = 600 x 400
* 05 = Full screen
*
* @var string
*/
const CHALLENGE_WINDOW_SIZE_01 = '01';
const CHALLENGE_WINDOW_SIZE_02 = '02';
const CHALLENGE_WINDOW_SIZE_03 = '03';
const CHALLENGE_WINDOW_SIZE_04 = '04';
const CHALLENGE_WINDOW_SIZE_05 = '05';

/**
* @var string The service name, used in the endpoint URL.
*/
Expand All @@ -25,7 +53,7 @@ abstract class AbstractRequest extends OmnipayAbstractRequest implements Constan
/**
* @var string The protocol version number.
*/
protected $VPSProtocol = '3.00';
protected $VPSProtocol = '4.00';

/**
* @var string Endpoint base URLs.
Expand Down
24 changes: 24 additions & 0 deletions src/Message/DirectAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ protected function getBaseAuthorizeData()
$data['VendorTxCode'] = $this->getTransactionId();
$data['ClientIPAddress'] = $this->getClientIp();

$data['BrowserJavascriptEnabled'] = $this->getBrowserJavascriptEnabled() ?: static::BROWSER_JAVASCRIPT_NO;
$data['BrowserLanguage'] = $this->getBrowserLanguage() ?: static::BROWSER_LANGUAGE;
$data['ThreeDSNotificationURL'] = $this->getThreeDSNotificationURL();
$data['BrowserAcceptHeader'] = $_SERVER['HTTP_ACCEPT'] ?? null;
$data['BrowserUserAgent'] = $_SERVER['HTTP_USER_AGENT'] ?? null;
$data['ChallengeWindowSize'] = $this->getChallengeWindowSize() ?: static::CHALLENGE_WINDOW_SIZE_05;

// Proctocol v4.00 - if BrowserJavascriptEnabled
$data['BrowserJavaEnabled'] = $this->getBrowserJavaEnabled();
$data['BrowserColorDepth'] = $this->getBrowserColorDepth();
$data['BrowserScreenHeight'] = $this->getBrowserScreenHeight();
$data['BrowserScreenWidth'] = $this->getBrowserScreenWidth();
$data['BrowserTZ'] = $this->getBrowserTZ();

// repeat payments required fields
$data['MITType'] = $this->getMITType();
$data['COFUsage'] = $this->getCOFUsage();
$data['InitiatedType'] = $this->getInitiatedType();
$data['SchemeTraceID'] = $this->getSchemeTraceID();
$data['RecurringExpiry'] = $this->getRecurringExpiry();
$data['RecurringFrequency'] = $this->getRecurringFrequency();
$data['ACSTransID'] = $this->getACSTransID();
$data['DSTransID'] = $this->getDSTransID();

$data['ApplyAVSCV2'] = $this->getApplyAVSCV2() ?: static::APPLY_AVSCV2_DEFAULT;
$data['Apply3DSecure'] = $this->getApply3DSecure() ?: static::APPLY_3DSECURE_APPLY;

Expand Down
20 changes: 20 additions & 0 deletions src/Message/DirectCompleteAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,32 @@ public function getService()
return static::SERVICE_DIRECT3D;
}

/**
* @return array|mixed|string[]
* @throws InvalidResponseException
*/
public function getData()
{
// Inconsistent letter case is intentional.
// The issuing bank will return PaRes, but the merchant
// site must send this result as PARes to Sage Pay.

// New 3D secure logic
if ($this->httpRequest->request->has('cres')) {
$CRes = $this->httpRequest->request->get('cres');
$VPSTxId = $this->httpRequest->request->get('threeDSSessionData');

if (!$VPSTxId) {
throw new InvalidResponseException('3DSecure: Missing VPSTxId');
}

if (!$CRes) {
throw new InvalidResponseException('3DSecure: Missing CRes');
}

return compact('CRes', 'VPSTxId');
}

$data = array(
'MD' => $this->getMd() ?: $this->httpRequest->request->get('MD'),
'PARes' => $this->getPaRes() ?: $this->httpRequest->request->get('PaRes'),
Expand Down
7 changes: 7 additions & 0 deletions src/Message/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ public function getRedirectMethod()
public function getRedirectData()
{
if ($this->isRedirect()) {
if ($creq = $this->getDataItem('CReq')) {
return [
'creq' => $creq,
'threeDSSessionData' => $this->getVPSTxId(),
];
}

return array(
'PaReq' => $this->getDataItem('PAReq'),
'TermUrl' => $this->getRequest()->getReturnUrl(),
Expand Down
10 changes: 10 additions & 0 deletions src/Message/SharedRepeatAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public function getData()
$data['BasketXML'] = $basketXML;
}

// Protocol v4.00 support
$data['MITType'] = $this->getMITType();
$data['COFUsage'] = $this->getCOFUsage();
$data['InitiatedType'] = $this->getInitiatedType();
$data['SchemeTraceID'] = $this->getSchemeTraceID();
$data['RecurringExpiry'] = $this->getRecurringExpiry();
$data['RecurringFrequency'] = $this->getRecurringFrequency();
$data['ACSTransID'] = $this->getACSTransID();
$data['DSTransID'] = $this->getDSTransID();

return $data;
}

Expand Down
Loading

0 comments on commit 3d93910

Please sign in to comment.