Skip to content

Commit 8995070

Browse files
committed
Merge pull request #28 from academe/protocol3
Support SagePay Protocol v3.00
2 parents eb7f0d4 + 9fc5c5b commit 8995070

14 files changed

+80
-57
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ The following gateways are provided by this package:
3333

3434
* SagePay_Direct
3535
* SagePay_Server
36+
* SagePay_Direct3
37+
* SagePay_Server3
3638

3739
For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay)
3840
repository.

src/DirectGateway.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
class DirectGateway extends AbstractGateway
1111
{
12+
// Gateway identification.
13+
1214
public function getName()
1315
{
1416
return 'Sage Pay Direct';
@@ -19,11 +21,12 @@ public function getDefaultParameters()
1921
return array(
2022
'vendor' => '',
2123
'testMode' => false,
22-
'simulatorMode' => false,
2324
'referrerId' => '',
2425
);
2526
}
2627

28+
// Vendor identification.
29+
2730
public function getVendor()
2831
{
2932
return $this->getParameter('vendor');
@@ -34,16 +37,16 @@ public function setVendor($value)
3437
return $this->setParameter('vendor', $value);
3538
}
3639

37-
public function getSimulatorMode()
38-
{
39-
return $this->getParameter('simulatorMode');
40-
}
40+
// Access to the HTTP client for debugging.
41+
// NOTE: this is likely to be removed or replaced with something
42+
// more appropriate.
4143

42-
public function setSimulatorMode($value)
44+
public function getHttpClient()
4345
{
44-
return $this->setParameter('simulatorMode', $value);
46+
return $this->httpClient;
4547
}
4648

49+
// Available services.
4750
public function getReferrerId()
4851
{
4952
return $this->getParameter('referrerId');

src/Message/AbstractRequest.php

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
namespace Omnipay\SagePay\Message;
44

5+
use Omnipay\Common\Exception\InvalidRequestException;
6+
57
/**
68
* Sage Pay Abstract Request
79
*/
810
abstract class AbstractRequest extends \Omnipay\Common\Message\AbstractRequest
911
{
1012
protected $liveEndpoint = 'https://live.sagepay.com/gateway/service';
1113
protected $testEndpoint = 'https://test.sagepay.com/gateway/service';
12-
protected $simulatorEndpoint = 'https://test.sagepay.com/Simulator';
1314

1415
public function getVendor()
1516
{
@@ -21,16 +22,6 @@ public function setVendor($value)
2122
return $this->setParameter('vendor', $value);
2223
}
2324

24-
public function getSimulatorMode()
25-
{
26-
return $this->getParameter('simulatorMode');
27-
}
28-
29-
public function setSimulatorMode($value)
30-
{
31-
return $this->setParameter('simulatorMode', $value);
32-
}
33-
3425
public function getService()
3526
{
3627
return $this->action;
@@ -115,7 +106,7 @@ public function setApply3DSecure($value)
115106
protected function getBaseData()
116107
{
117108
$data = array();
118-
$data['VPSProtocol'] = '2.23';
109+
$data['VPSProtocol'] = '3.00';
119110
$data['TxType'] = $this->action;
120111
$data['Vendor'] = $this->getVendor();
121112
$data['AccountType'] = $this->getAccountType() ?: 'E';
@@ -134,19 +125,6 @@ public function getEndpoint()
134125
{
135126
$service = strtolower($this->getService());
136127

137-
if ($this->getSimulatorMode()) {
138-
// hooray for consistency
139-
if ($service == 'vspdirect-register') {
140-
return $this->simulatorEndpoint.'/VSPDirectGateway.asp';
141-
} elseif ($service == 'vspserver-register') {
142-
return $this->simulatorEndpoint.'/VSPServerGateway.asp?Service=VendorRegisterTx';
143-
} elseif ($service == 'direct3dcallback') {
144-
return $this->simulatorEndpoint.'/VSPDirectCallback.asp';
145-
}
146-
147-
return $this->simulatorEndpoint.'/VSPServerGateway.asp?Service=Vendor'.ucfirst($service).'Tx';
148-
}
149-
150128
if ($this->getTestMode()) {
151129
return $this->testEndpoint."/$service.vsp";
152130
}

src/Message/ServerCompleteAuthorizeRequest.php

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,25 @@
99
*/
1010
class ServerCompleteAuthorizeRequest extends AbstractRequest
1111
{
12-
public function getData()
12+
/**
13+
* Get the signature calculated from the three pieces of saved local
14+
* information:
15+
* * VendorTxCode - merchant site ID (aka transactionId).
16+
* * VPSTxId - SagePay ID (aka transactionReference)
17+
* * SecurityKey - SagePay one-use token.
18+
* and the POSTed transaction results.
19+
* Note that the three items above are passed in as a single JSON structure
20+
* as the transactionReference. Would be nice if that were just the fallback,
21+
* if not passed in as three separate items to the relevant fields.
22+
*/
23+
public function getSignature()
1324
{
1425
$this->validate('transactionId', 'transactionReference');
1526

1627
$reference = json_decode($this->getTransactionReference(), true);
1728

18-
// validate VPSSignature
19-
$signature = md5(
29+
// Re-create the VPSSignature
30+
$signature_string =
2031
$reference['VPSTxId'].
2132
$reference['VendorTxCode'].
2233
$this->httpRequest->request->get('Status').
@@ -33,8 +44,24 @@ public function getData()
3344
$this->httpRequest->request->get('AddressStatus').
3445
$this->httpRequest->request->get('PayerStatus').
3546
$this->httpRequest->request->get('CardType').
36-
$this->httpRequest->request->get('Last4Digits')
37-
);
47+
$this->httpRequest->request->get('Last4Digits').
48+
// New for protocol v3.00
49+
// Described in the docs as "mandatory" but not supplied when PayPal is used,
50+
// so provide the defaults.
51+
$this->httpRequest->request->get('DeclineCode', '').
52+
$this->httpRequest->request->get('ExpiryDate', '').
53+
$this->httpRequest->request->get('FraudResponse', '').
54+
$this->httpRequest->request->get('BankAuthCode', '');
55+
56+
return md5($signature_string);
57+
}
58+
59+
/**
60+
* Get the POSTed data, checking that the signature is valid.
61+
*/
62+
public function getData()
63+
{
64+
$signature = $this->getSignature();
3865

3966
if (strtolower($this->httpRequest->request->get('VPSSignature')) !== $signature) {
4067
throw new InvalidResponseException;

tests/Message/ServerAuthorizeResponseTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ public function testServerPurchaseFailure()
4242
$this->assertFalse($response->isSuccessful());
4343
$this->assertFalse($response->isRedirect());
4444
$this->assertSame('{"VendorTxCode":"123456"}', $response->getTransactionReference());
45-
$this->assertSame('The Description field should be between 1 and 100 characters long.', $response->getMessage());
45+
$this->assertSame('3082 : The Description value is too long.', $response->getMessage());
4646
}
4747
}

tests/Message/ServerCompleteAuthorizeResponseTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public function testServerCompleteAuthorizeResponseSuccess()
2525
'PayerStatus' => 'k',
2626
'CardType' => 'l',
2727
'Last4Digits' => 'm',
28+
'DeclineCode' => '00',
29+
'ExpiryDate' => '0722',
30+
'BankAuthCode' => '999777',
2831
)
2932
);
3033

tests/Mock/CaptureFailure.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ Content-Type: Text/Plain
88
Set-Cookie: ASPSESSIONIDSEHSCTTR=NNBHGPBDLOMKKPGPNDDJFBAB; secure; path=/
99
Cache-control: private
1010

11-
VPSProtocol=2.23
11+
VPSProtocol=3.00
1212
Status=INVALID
1313
StatusDetail=You are trying to RELEASE a transaction that has already been RELEASEd or ABORTed.

tests/Mock/CaptureSuccess.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ Content-Type: Text/Plain
88
Set-Cookie: ASPSESSIONIDSEHSCTTR=FNBHGPBDMGDJCNLCDCDPGKCA; secure; path=/
99
Cache-control: private
1010

11-
VPSProtocol=2.23
11+
VPSProtocol=3.00
1212
Status=OK
1313
StatusDetail=The transaction was RELEASEed successfully.

tests/Mock/DirectPurchase3dSecure.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Content-Type: Text/Plain
88
Set-Cookie: ASPSESSIONIDSEHSCTTR=FDNGGPBDBPAHLBIMINACENLN; secure; path=/
99
Cache-control: private
1010

11-
VPSProtocol=2.23
11+
VPSProtocol=3.00
1212
Status=3DAUTH
1313
3DSecureStatus=OK
1414
MD=065379457749061954

tests/Mock/DirectPurchaseFailure.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ Content-Type: Text/Plain
88
Set-Cookie: ASPSESSIONIDSEHSCTTR=PIMGGPBDEAHAGKNHFGMICIAM; secure; path=/
99
Cache-control: private
1010

11-
VPSProtocol=2.23
11+
VPSProtocol=3.00
1212
Status=INVALID
1313
StatusDetail=The VendorTxCode '984297' has been used before. Each transaction you send should have a unique VendorTxCode.

0 commit comments

Comments
 (0)