From caf1bf5c1647fe79457648a252f9c508fbbc9782 Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Mon, 8 Jul 2013 17:39:53 +0100 Subject: [PATCH 1/9] Added getRequestTransactionId() to SagePay\Message\ServerCompleteAuthorizeRequest so that the receiving code can look up the right transactionReference and call setTransactionReference() before getData() is called as it needs the SecurityKey from the transactionReference to check the message signature --- .../Message/ServerCompleteAuthorizeRequest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php index 74b998cc..81d14543 100644 --- a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php +++ b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php @@ -18,6 +18,20 @@ */ class ServerCompleteAuthorizeRequest extends AbstractRequest { + /** + * This retrieves the transaction id from the raw request so that you can + * retrieve the full transactionReference from your stored + * and setTransactionReference() into this request before calling getData() + * since getData will validate the signature of this request and needs + * the VPSTxId, VendorTxCode and SecurityKey that were stashed in the + * transactionReference! + * @return string + */ + public function getRequestTransactionId() + { + return $this->httpRequest->request->get('VendorTxCode'); + } + public function getData() { $this->validate('transactionId', 'transactionReference'); From a225120962bf43a218696744cfe3d7ec68b3d2ed Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Mon, 8 Jul 2013 18:29:09 +0100 Subject: [PATCH 2/9] working on token support for SagePay --- example/index.php | 1 + .../ServerCompleteCreateCardRequest.php | 74 +++++++++++++++++++ .../ServerCompleteCreateCardResponse.php | 27 +++++++ .../Message/ServerCreateCardRequest.php | 43 +++++++++++ .../Message/ServerCreateCardResponse.php | 21 ++++++ src/Omnipay/SagePay/ServerGateway.php | 10 +++ 6 files changed, 176 insertions(+) create mode 100644 src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php create mode 100644 src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php create mode 100644 src/Omnipay/SagePay/Message/ServerCreateCardRequest.php create mode 100644 src/Omnipay/SagePay/Message/ServerCreateCardResponse.php diff --git a/example/index.php b/example/index.php index 81af49b5..94cc2f04 100644 --- a/example/index.php +++ b/example/index.php @@ -147,6 +147,7 @@ $params = $app['session']->get($sessionVar.'.purchase', array()); $params['returnUrl'] = str_replace('/purchase', '/completePurchase', $app['request']->getUri()); $params['cancelUrl'] = $app['request']->getUri(); + $params['transactionId'] = date('Y-m-d-H-i-s'); $card = new Omnipay\Common\CreditCard($app['session']->get($sessionVar.'.card')); return $app['twig']->render('request.twig', array( diff --git a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php new file mode 100644 index 00000000..0c1faff6 --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Exception\InvalidResponseException; + +/** + * Sage Pay Server Complete Authorize Request + */ +class ServerCompleteCreateCardRequest extends AbstractRequest +{ + public function getRequestTransactionId() + { + return $this->httpRequest->request->get('VendorTxCode'); + } + + public function getCardReference() + { + return isset($this->data['Token']) ? $this->data['Token'] : null; + } + + public function getCardType() + { + return isset($this->data['CardType']) ? $this->data['CardType'] : null; + } + + public function getLast4Digits() + { + return isset($this->data['Last4Digits']) ? $this->data['Last4Digits'] : null; + } + + public function getExpiryDate() + { + return isset($this->data['ExpiryDate']) ? $this->data['ExpiryDate'] : null; + } + + public function getData() + { + $this->validate('vendor', 'transactionReference'); + + $reference = json_decode($this->getTransactionReference(), true); + + // validate VPSSignature + $signature = md5( + $reference['VPSTxId']. + $reference['VendorTxCode']. + $this->httpRequest->request->get('Status'). + $this->httpRequest->request->get('TxAuthNo'). + $this->getVendor(). + $this->httpRequest->request->get('TOPKEN'). + $reference['SecurityKey'] + ); + + if (strtolower($this->httpRequest->request->get('VPSSignature')) !== $signature) { + throw new InvalidResponseException; + } + + return $this->httpRequest->request->all(); + } + + public function send() + { + return $this->response = new ServerCompleteCreateCardResponse($this, $this->getData()); + } +} diff --git a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php new file mode 100644 index 00000000..cb49cc3d --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Message\RequestInterface; + +/** + * Sage Pay Server Complete Authorize Response + */ +class ServerCompleteCreateCardResponse extends Response +{ + public function __construct(RequestInterface $request, $data) + { + $this->request = $request; + $this->data = $data; + } + +} diff --git a/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php b/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php new file mode 100644 index 00000000..2d5d6321 --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +/** + * Sage Pay Server CreateCard Request + */ +class ServerCreateCardRequest extends ServerPurchaseRequest +{ + protected $action = 'TOKEN'; + + public function getData() + { + $this->validate('returnUrl', 'transactionId'); + + $data = $this->getBaseData(); + $data['VendorTxCode'] = $this->getTransactionId(); + $data['Currency'] = $this->getCurrency(); + $data['NotificationURL'] = $this->getReturnUrl(); + $data['Profile'] = $this->getProfile(); + + return $data; + } + + public function getService() + { + return 'token'; + } + + protected function createResponse($data) + { + return $this->response = new ServerCreateCardResponse($this, $data); + } +} diff --git a/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php b/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php new file mode 100644 index 00000000..8d385e5f --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Message\RequestInterface; + +/** + * Sage Pay Server Complete Authorize Response + */ +class ServerCreateCardResponse extends ServerAuthorizeResponse +{ +} diff --git a/src/Omnipay/SagePay/ServerGateway.php b/src/Omnipay/SagePay/ServerGateway.php index 3d2b6e7a..df4da8c2 100644 --- a/src/Omnipay/SagePay/ServerGateway.php +++ b/src/Omnipay/SagePay/ServerGateway.php @@ -44,4 +44,14 @@ public function completePurchase(array $parameters = array()) { return $this->completeAuthorize($parameters); } + + public function createCard(array $parameters = array()) + { + return $this->createRequest('\Omnipay\SagePay\Message\ServerCreateCardRequest', $parameters); + } + + public function completeCreateCard(array $parameters = array()) + { + return $this->createRequest('\Omnipay\SagePay\Message\ServerCreateCardRequest', $parameters); + } } From 1dadd83cbbfae1f1be14b4d6e21c8090686d44a6 Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 14:34:13 +0100 Subject: [PATCH 3/9] change composer package to damphlett/omnipay --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7abb7d28..2b6bafea 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "omnipay/omnipay", + "name": "davelopware/omnipay", "type": "library", "description": "A framework agnostic, multi-gateway payment processing library", "keywords": [ From 989152727d7ec5950cbc79a893199099d0f2777e Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 15:05:08 +0100 Subject: [PATCH 4/9] tweak composer.json to explain this fork of adrianmacneil/omnipay is for inclusion in the WordPress OmniPay Payment Gateway Plugin by Davelopware --- composer.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2b6bafea..92f3af85 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "davelopware/omnipay", "type": "library", - "description": "A framework agnostic, multi-gateway payment processing library", + "description": "A version of adrianmacneil/omnipay (omnipay/omnipay on packagist) which is included in the WordPress OmniPay Payment Gateway Plugin by Davelopware", "keywords": [ "2checkout", "2co", @@ -46,6 +46,10 @@ { "name": "Adrian Macneil", "email": "adrian@adrianmacneil.com" + }, + { + "name": "Dave Amphlett (Davelopware Ltd)", + "email": "dave@davelopware.com" } ], "autoload": { From 37e3d3e0fbe0f8cf66e5c61c31467ecac90c2b03 Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 15:28:07 +0100 Subject: [PATCH 5/9] Added getRequestTransactionId() to SagePay\Message\ServerCompleteAutorizeRequest So that the receiving code can look up the right transactionReference and call setTransactionReference() before getData() is called as it needs the SecurityKey from the transactionReference to check the message signature --- .../Message/ServerCompleteAuthorizeRequest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php index 74b998cc..81d14543 100644 --- a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php +++ b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeRequest.php @@ -18,6 +18,20 @@ */ class ServerCompleteAuthorizeRequest extends AbstractRequest { + /** + * This retrieves the transaction id from the raw request so that you can + * retrieve the full transactionReference from your stored + * and setTransactionReference() into this request before calling getData() + * since getData will validate the signature of this request and needs + * the VPSTxId, VendorTxCode and SecurityKey that were stashed in the + * transactionReference! + * @return string + */ + public function getRequestTransactionId() + { + return $this->httpRequest->request->get('VendorTxCode'); + } + public function getData() { $this->validate('transactionId', 'transactionReference'); From 030e05f430d8e3afee89ed0cef1f25f0787491ea Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 16:03:05 +0100 Subject: [PATCH 6/9] added various access methods on SagePay\Message\ServerCompleteAuthorizeResponse to ease accessing the transaction infomation. Also includes comments explaining the contents of the fields, retyped from the 23 Aug 2011 version of the SagePay Server Protocol Integration Guidelines document --- .../ServerCompleteAuthorizeResponse.php | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php index 8916bce1..6f549163 100644 --- a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php +++ b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php @@ -35,6 +35,134 @@ public function getTransactionReference() } } + /** + * SagePay unique Authorisation Code for successfully authorised transactions + * aka VPSAuthCode. + * Only present if the transaction was successfully authorised (Status OK) + * @return string + */ + public function getTxAuthNo() + { + return (isset($this->data['TxAuthNo'])) ? $this->data['TxAuthNo'] : null; + } + + /** + * Response from AVS and CV2 checks. Will be one of the following: + * ALL MATCH, SECURITY CODE MATCH ONLY, ADDRESS MATCH ONLY, NO DATA MATCHES, + * DATA NOT CHECKED + * @return string + */ + public function getAVSCV2() + { + return (isset($this->data['AVSCV2'])) ? $this->data['AVSCV2'] : null; + } + + /** + * NOTPROVIDED, NOTCHECKED, MATCHED, NATMATCHED + * @return string + */ + public function getAddressResult() + { + return (isset($this->data['AddressResult'])) ? $this->data['AddressResult'] : null; + } + + /** + * NOTPROVIDED, NOTCHECKED, MATCHED, NATMATCHED + * @return string + */ + public function getPostCodeResult() + { + return (isset($this->data['PostCodeResult'])) ? $this->data['PostCodeResult'] : null; + } + + /** + * NOTPROVIDED, NOTCHECKED, MATCHED, NATMATCHED + * @return string + */ + public function getCV2Result() + { + return (isset($this->data['CV2Result'])) ? $this->data['CV2Result'] : null; + } + + /** + * 0 = The Gift Aid box was not checked for this transaction + * 1 = The user checked teh Gift Aid box on the payment page + * @return string + */ + public function getGitAid() + { + return (isset($this->data['GiftAid'])) ? $this->data['GiftAid'] : null; + } + + /** + * OK = 3D Secure checks carried out and user authenticated correctly. + * NOTCHECKED = 3D Secure checks were not performed. + * NOTAVAILABLE = The card used was either not part of the 3D Secure Scheme, + * or the authorisation was not possible. + * NOTAUTHED = 3D Secure authentication checked, but the user failed the + * authentication. + * INCOMPLETE = 3D Secure authentication was unable to complete. No + * authentication occured. + * ERROR = Authentication could not be attempted due to data errors or service + * unavailability in one of the parties involved in the check. + * @return string + */ + public function get3DSecureStatus() + { + return (isset($this->data['3DSecureStatus'])) ? $this->data['3DSecureStatus'] : null; + } + + /** + * The encoded result code from the 3D Secure checks (CAVV or UCAF) + * @return string + */ + public function getCAVV() + { + return (isset($this->data['CAVV'])) ? $this->data['CAVV'] : null; + } + + /** + * PayPal Transactions Only. If AddressStatus is confirmed and + * PayerStatus is verified, the transaction may be eligible for + * PayPal Seller Protection. + * NONE, CONFIRMED, UNCONFIRMED + * @return string + */ + public function getAddressStatus() + { + return (isset($this->data['AddressStatus'])) ? $this->data['AddressStatus'] : null; + } + + /** + * PayPal Transactions Only. + * VERIFIED, UNVERIFIED + * @return string + */ + public function getPayerStatus() + { + return (isset($this->data['PayerStatus'])) ? $this->data['PayerStatus'] : null; + } + + /** + * VISA, MC, DELTA, MAESTRO, UKE, AMEX, DC, JCB, LASER, PAYPAL + * @return string + */ + public function getCardType() + { + return (isset($this->data['CardType'])) ? $this->data['CardType'] : null; + } + + /** + * The last 4 digits of the card number used in this transaction. + * PayPal transactions have 0000 + * @return string + */ + public function getLast4Digits() + { + return (isset($this->data['Last4Digits'])) ? $this->data['Last4Digits'] : null; + } + + /** * Confirm (Sage Pay Server only) * From 6cdcbfa533a0e7da3c3e9dd5db1f4a5caacbd5cd Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 16:08:15 +0100 Subject: [PATCH 7/9] started trying to implement token system for SagePay --- .../ServerCompleteCreateCardRequest.php | 74 +++++++++++++++++++ .../ServerCompleteCreateCardResponse.php | 27 +++++++ .../Message/ServerCreateCardRequest.php | 43 +++++++++++ .../Message/ServerCreateCardResponse.php | 21 ++++++ 4 files changed, 165 insertions(+) create mode 100644 src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php create mode 100644 src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php create mode 100644 src/Omnipay/SagePay/Message/ServerCreateCardRequest.php create mode 100644 src/Omnipay/SagePay/Message/ServerCreateCardResponse.php diff --git a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php new file mode 100644 index 00000000..d785b02b --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Exception\InvalidResponseException; + +/** + * Sage Pay Server Complete Authorize Request + */ +class ServerCompleteCreateCardRequest extends AbstractRequest +{ + public function getRequestTransactionId() + { + return $this->httpRequest->request->get('VendorTxCode'); + } + + public function getCardReference() + { + return isset($this->data['Token']) ? $this->data['Token'] : null; + } + + public function getCardType() + { + return isset($this->data['CardType']) ? $this->data['CardType'] : null; + } + + public function getLast4Digits() + { + return isset($this->data['Last4Digits']) ? $this->data['Last4Digits'] : null; + } + + public function getExpiryDate() + { + return isset($this->data['ExpiryDate']) ? $this->data['ExpiryDate'] : null; + } + + public function getData() + { + $this->validate('vendor', 'transactionReference'); + + $reference = json_decode($this->getTransactionReference(), true); + + // validate VPSSignature + $signature = md5( + $reference['VPSTxId']. + $reference['VendorTxCode']. + $this->httpRequest->request->get('Status'). + $this->httpRequest->request->get('TxAuthNo'). + $this->getVendor(). + $this->httpRequest->request->get('TOPKEN'). + $reference['SecurityKey'] + ); + + if (strtolower($this->httpRequest->request->get('VPSSignature')) !== $signature) { + throw new InvalidResponseException; + } + + return $this->httpRequest->request->all(); + } + + public function send() + { + return $this->response = new ServerCompleteCreateCardResponse($this, $this->getData()); + } +} diff --git a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php new file mode 100644 index 00000000..3171755c --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardResponse.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Message\RequestInterface; + +/** + * Sage Pay Server Complete Authorize Response + */ +class ServerCompleteCreateCardResponse extends Response +{ + public function __construct(RequestInterface $request, $data) + { + $this->request = $request; + $this->data = $data; + } + +} diff --git a/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php b/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php new file mode 100644 index 00000000..2d5d6321 --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCreateCardRequest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +/** + * Sage Pay Server CreateCard Request + */ +class ServerCreateCardRequest extends ServerPurchaseRequest +{ + protected $action = 'TOKEN'; + + public function getData() + { + $this->validate('returnUrl', 'transactionId'); + + $data = $this->getBaseData(); + $data['VendorTxCode'] = $this->getTransactionId(); + $data['Currency'] = $this->getCurrency(); + $data['NotificationURL'] = $this->getReturnUrl(); + $data['Profile'] = $this->getProfile(); + + return $data; + } + + public function getService() + { + return 'token'; + } + + protected function createResponse($data) + { + return $this->response = new ServerCreateCardResponse($this, $data); + } +} diff --git a/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php b/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php new file mode 100644 index 00000000..8154f358 --- /dev/null +++ b/src/Omnipay/SagePay/Message/ServerCreateCardResponse.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Omnipay\SagePay\Message; + +use Omnipay\Common\Message\RequestInterface; + +/** + * Sage Pay Server Complete Authorize Response + */ +class ServerCreateCardResponse extends ServerAuthorizeResponse +{ +} From 7e4ba70520c7275fca27e561d54b0f24c23a0ae9 Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 16:17:58 +0100 Subject: [PATCH 8/9] last step of merge --- .../SagePay/Message/ServerCompleteCreateCardRequest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php index 3bbd0325..d785b02b 100644 --- a/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php +++ b/src/Omnipay/SagePay/Message/ServerCompleteCreateCardRequest.php @@ -3,11 +3,7 @@ /* * This file is part of the Omnipay package. * -<<<<<<< HEAD - * (c) Adrian Macneil -======= * (c) Dave Amphlett ->>>>>>> dev_to_core * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. From fc4b8d4e0836ed2abb537a8359bc3634d098573e Mon Sep 17 00:00:00 2001 From: Dave Amphlett Date: Tue, 9 Jul 2013 16:20:20 +0100 Subject: [PATCH 9/9] added getVPSTxId() to SagePay/Message/ServerCompleteAuthorizeResponse --- .../SagePay/Message/ServerCompleteAuthorizeResponse.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php index 6f549163..91de26d8 100644 --- a/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php +++ b/src/Omnipay/SagePay/Message/ServerCompleteAuthorizeResponse.php @@ -35,6 +35,15 @@ public function getTransactionReference() } } + /** + * SagePay's ID to uniquely identify the Transaction on their system. + * @return string + */ + public function getVPSTxId() + { + return (isset($this->data['VPSTxId'])) ? $this->data['VPSTxId'] : null; + } + /** * SagePay unique Authorisation Code for successfully authorised transactions * aka VPSAuthCode.