123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- <?php
- /**
- *
- * PHP Pro Bid $Id$ dewKK71K7ZWVYpZ56VQJGR/Vd+iQ6tJiFee6XhwPNyE=
- *
- * @link http://www.phpprobid.com
- * @copyright Copyright (c) 2014 Online Ventures Software LTD & CodeCube SRL
- * @license http://www.phpprobid.com/license Commercial License
- *
- * @version 7.2
- */
- /**
- * SagePay payment gateway model class
- */
- namespace Ppb\Model\PaymentGateway;
- use Cube\Controller\Request\AbstractRequest,
- Ppb\Service;
- class SagePay extends AbstractPaymentGateway
- {
- /**
- * payment gateway name
- */
- const NAME = 'SagePay';
- /**
- * required settings
- */
- const VENDOR = 'Vendor';
- const PASSWORD = 'Password';
- /**
- * form post url
- */
- const POST_URL = 'https://live.sagepay.com/gateway/service/vspform-register.vsp';
- /**
- * form post url (sandbox)
- */
- const SANDBOX_POST_URL = 'https://test.sagepay.com/gateway/service/vspform-register.vsp';
- /**
- * sagepay description
- */
- protected $_description = 'Click to pay through SagePay.';
- public function __construct($userId = null)
- {
- parent::__construct(self::NAME, $userId);
- }
- /**
- *
- * check if the gateway is enabled
- *
- * @return bool
- */
- public function enabled()
- {
- if (!empty($this->_data[self::VENDOR]) && !empty($this->_data[self::PASSWORD])) {
- return true;
- }
- return false;
- }
- /**
- *
- * get setup form elements
- *
- * @return array
- */
- public function getElements()
- {
- $translate = $this->getTranslate();
- return array(
- array(
- 'form_id' => 'SagePay',
- 'id' => self::VENDOR,
- 'element' => 'text',
- 'label' => $this->_('SagePay Vendor Name'),
- 'description' => $this->_('Enter your SagePay vendor name'),
- 'attributes' => array(
- 'class' => 'form-control input-medium',
- ),
- ),
- array(
- 'form_id' => 'SagePay',
- 'id' => self::PASSWORD,
- 'element' => 'text',
- 'label' => $this->_('SagePay Password'),
- 'description' => $translate->_('Enter your SagePay integration password <br>'
- . 'SagePay Success & Failure URL: <br>') . $this->getIpnUrl(),
- 'attributes' => array(
- 'class' => 'form-control input-medium',
- ),
- ),
- );
- }
- public function formElements()
- {
- return array(
- array(
- 'id' => 'VPSProtocol',
- 'value' => '3.00',
- 'element' => 'hidden',
- ),
- array(
- 'id' => 'TxType',
- 'value' => 'PAYMENT',
- 'element' => 'hidden',
- ),
- array(
- 'id' => self::VENDOR,
- 'value' => $this->_data[self::VENDOR],
- 'element' => 'hidden',
- ),
- array(
- 'id' => 'Crypt',
- 'value' => $this->_encryptAndEncode(
- $this->_getCryptFields()),
- 'element' => 'hidden',
- ),
- );
- }
- public function getPostUrl()
- {
- return self::POST_URL;
- }
- /**
- *
- * process ipn
- *
- * @param \Cube\Controller\Request\AbstractRequest $request
- *
- * @return bool
- */
- public function processIpn(AbstractRequest $request)
- {
- $response = false;
- $data = array();
- $result = explode('&', $this->_decodeAndDecrypt($request->getParam('crypt')));
- foreach ($result as $row) {
- list($key, $value) = explode('=', $row);
- $data[$key] = $value;
- }
- $this->setTransactionId($data['VendorTxCode'])
- ->setAmount($data['Amount'])
- ->setCurrency($data['Currency'])
- ->setGatewayPaymentStatus($data['Status'])
- ->setGatewayTransactionCode($data['VPSTxId']);
- if ($data['Status'] == 'OK') {
- $response = true;
- }
- return $response;
- }
- /**
- *
- * generate crypt form variable needed by the sagepay form
- *
- * @return string
- */
- private function _getCryptFields()
- {
- $transactionsService = new Service\Transactions();
- /** @var \Ppb\Db\Table\Row\User $user */
- $user = $transactionsService->findBy('id', $this->getTransactionId())
- ->findParentRow('\Ppb\Db\Table\Users');
- $user->setAddress();
- $locationsService = new Service\Table\Relational\Locations();
- $country = $locationsService->findBy('id', (int)$user->getData('country'));
- $state = null;
- if (strcasecmp($country['iso_code'], 'us') === 0) {
- $state = $user['state'];
- if (is_numeric($state)) {
- $locations = new Service\Table\Relational\Locations();
- $state = strtoupper(
- $locations->findBy('id', (int)$state)->getData('iso_code'));
- }
- }
- $data = array(
- 'VendorTxCode' => $this->getTransactionId(),
- 'Amount' => $this->_getAmount(),
- 'Currency' => $this->getCurrency(),
- 'Description' => $this->_shortenString($this->getName(), 100),
- 'SuccessURL' => $this->getSuccessUrl(),
- 'FailureURL' => $this->getFailureUrl(),
- 'BillingSurname' => $this->_shortenString($user['last_name'], 20),
- 'BillingFirstnames' => $this->_shortenString($user['first_name'], 20),
- 'BillingAddress1' => $this->_shortenString($user['address'], 100),
- 'BillingCity' => $this->_shortenString($user['city'], 40),
- 'BillingPostCode' => $this->_shortenString($user['zip_code'], 10),
- 'BillingCountry' => $country['iso_code'],
- 'BillingState' => $state,
- 'DeliverySurname' => $this->_shortenString($user['last_name'], 20),
- 'DeliveryFirstnames' => $this->_shortenString($user['first_name'], 20),
- 'DeliveryAddress1' => $this->_shortenString($user['address'], 100),
- 'DeliveryCity' => $this->_shortenString($user['city'], 40),
- 'DeliveryPostCode' => $this->_shortenString($user['zip_code'], 10),
- 'DeliveryCountry' => $country['iso_code'],
- 'DeliveryState' => $state,
- );
- $crypt = array();
- foreach ($data as $key => $value) {
- $crypt[] = $key . '=' . $value;
- }
- return implode('&', $crypt);
- }
- /**
- *
- * amount format required by sagepay, with commas to separate thousands
- *
- * @return string
- */
- private function _getAmount()
- {
- return number_format(
- $this->getAmount(), 2, '.', ',');
- }
- /**
- *
- * encrypt the crypt field
- *
- * @param $string
- *
- * @return string
- */
- private function _encryptAndEncode($string)
- {
- //** AES encryption, CBC blocking with PKCS5 padding then HEX encoding - DEFAULT **
- //** use initialization vector (IV) set from the account password
- $strIV = $this->_data[self::PASSWORD];
- //** add PKCS5 padding to the text to be encrypted
- $string = $this->_addPKCS5Padding($string);
- //** perform encryption with PHP's MCRYPT module
- $strCrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->_data[self::PASSWORD], $string, MCRYPT_MODE_CBC, $strIV);
- //** perform hex encoding and return
- return "@" . bin2hex($strCrypt);
- }
- /**
- *
- * decode then decrypt based on header of the encrypted field
- *
- * @param $string
- *
- * @return string
- */
- private function _decodeAndDecrypt($string)
- {
- //** HEX decoding then AES decryption, CBC blocking with PKCS5 padding - DEFAULT **
- //** use initialization vector (IV) set from $strEncryptionPassword
- $strIV = $this->_data[self::PASSWORD];
- //** remove the first char which is @ to flag this is AES encrypted
- $string = substr($string, 1);
- //** HEX decoding
- $string = pack('H*', $string);
- //** perform decryption with PHP's MCRYPT module
- return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->_data[self::PASSWORD], $string, MCRYPT_MODE_CBC, $strIV);
- }
- /**
- *
- * PHP's mcrypt does not have built in PKCS5 Padding, so we use this
- *
- * @param $input
- *
- * @return string
- */
- private function _addPKCS5Padding($input)
- {
- $blockSize = 16;
- $padding = "";
- // Pad input to an even block size boundary
- $padLength = $blockSize - (strlen($input) % $blockSize);
- for ($i = 1; $i <= $padLength; $i++) {
- $padding .= chr($padLength);
- }
- return $input . $padding;
- }
- }
|