├── docs └── paranioa.markdown ├── .gitignore ├── src └── Paranoia │ ├── Payment │ ├── Exception │ │ ├── UnknownPos.php │ │ ├── UnknownAdapter.php │ │ ├── UnexpectedResponse.php │ │ ├── UnimplementedMethod.php │ │ ├── UnknownTransactionType.php │ │ ├── ConfigurationError.php │ │ └── UnknownCurrencyCode.php │ ├── Response │ │ ├── InquiryResponse.php │ │ ├── PaymentResponse.php │ │ ├── ResponseInterface.php │ │ └── ResponseAbstract.php │ ├── TransferInterface.php │ ├── Factory.php │ ├── Adapter │ │ ├── AdapterInterface.php │ │ ├── Est.php │ │ ├── Posnet.php │ │ ├── AdapterAbstract.php │ │ └── Gvp.php │ └── Request.php │ ├── Common │ └── Serializer │ │ ├── Exception │ │ ├── OptionError.php │ │ └── UnknownSerializer.php │ │ ├── Adapter │ │ ├── SerializerInterface.php │ │ └── Xml.php │ │ └── Serializer.php │ ├── Communication │ ├── Exception │ │ ├── CommunicationFailed.php │ │ ├── UndefinedHttpMethod.php │ │ └── UnknownCommunicationAdapter.php │ ├── Adapter │ │ ├── AdapterAbstract.php │ │ ├── AdapterInterface.php │ │ ├── Soap.php │ │ └── Http.php │ └── Connector.php │ └── EventManager │ ├── Exception │ └── UndefinedListenerMethod.php │ ├── Listener │ ├── PaymentListener.php │ ├── CommunicationListener.php │ └── ListenerAbstract.php │ ├── EventManagerAbstract.php │ └── EventParameter.php ├── .travis.yml ├── phpunit.xml ├── composer.json ├── config.json-dist ├── tests ├── Paranoia │ └── Test │ │ └── Payment │ │ ├── FactoryTest.php │ │ └── Adapter │ │ ├── EstTest.php │ │ ├── GvpTest.php │ │ └── PosnetTest.php └── Resources │ └── config │ └── config.json └── README.md /docs/paranioa.markdown: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .build 3 | config.php 4 | vendor 5 | composer.lock 6 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Exception/UnknownPos.php: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | tests/ 6 | 7 | 8 | 9 | ./libs 10 | ./src 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Paranoia/EventManager/Listener/PaymentListener.php: -------------------------------------------------------------------------------- 1 | =5.3.0", 8 | "monolog/monolog": "~1.7" 9 | }, 10 | "require-dev": { 11 | "squizlabs/php_codesniffer": "~1.5.2", 12 | "phpmd/phpmd" : "1.4.*", 13 | "phpunit/phpunit": "3.7.*" 14 | }, 15 | "license": "MIT", 16 | "authors": [ 17 | { 18 | "name": "ibrahimgunduz34", 19 | "email": "ibrahimgunduz34@gmail.com", 20 | "homepage": "http://ibrahimgunduz.net" 21 | } 22 | ], 23 | "autoload": { 24 | "psr-0": { 25 | "Paranoia": "src/", 26 | "Paranoia\\Tests": "tests/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Paranoia/EventManager/Listener/CommunicationListener.php: -------------------------------------------------------------------------------- 1 | getData('url'), 15 | 'Data: ' . $parameter->getData('data') 16 | ) 17 | ) . PHP_EOL; 18 | } 19 | 20 | protected function afterRequest(EventParameter $parameter) 21 | { 22 | print implode( 23 | PHP_EOL, 24 | array( 25 | 'Type: Response', 26 | 'Url:' . $parameter->getData('url'), 27 | 'Data: ' . $parameter->getData('data') 28 | ) 29 | ) . PHP_EOL; 30 | } 31 | 32 | protected function onException(EventParameter $parameter) 33 | { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /config.json-dist: -------------------------------------------------------------------------------- 1 | { 2 | "estbank": { 3 | "adapter": "Est", 4 | "api_url": "", 5 | "client_id": "", 6 | "username": "", 7 | "password": "", 8 | "mode": "", 9 | "currencyCodes": { 10 | "TRY": 949, 11 | "USD": 840, 12 | "EUR": 978 13 | } 14 | }, 15 | "gvpbank": { 16 | "adapter": "Gvp", 17 | "api_url": "", 18 | "terminal_id": "", 19 | "merchant_id": "", 20 | "auth_username": "", 21 | "auth_password": "", 22 | "refund_username": "", 23 | "refund_password": "", 24 | "mode": "", 25 | "currencyCodes": { 26 | "TRY": 949, 27 | "USD": 840, 28 | "EUR": 978 29 | } 30 | }, 31 | "posnetbank": { 32 | "adapter": "Posnet", 33 | "api_url": "https://www.posnet.ykb.com/PosnetWebService/XML", 34 | "client_id": "", 35 | "terminal_id": "", 36 | "username": "", 37 | "password": "", 38 | "currencyCodes": { 39 | "TRY": "YT", 40 | "USD": "US", 41 | "EUR": "EU" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Paranoia/Communication/Adapter/Soap.php: -------------------------------------------------------------------------------- 1 | lastSentRequest; 29 | } 30 | 31 | /** 32 | * returns last received response from provider. 33 | * 34 | * @return string 35 | */ 36 | public function getLastReceivedResponse() 37 | { 38 | return $this->lastReceivedResponse; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/TransferInterface.php: -------------------------------------------------------------------------------- 1 | serializer = new Xml(); 26 | break; 27 | case self::JSON: 28 | $this->serializer = new Json(); 29 | break; 30 | default: 31 | throw new UnknownSerializer('Unknown serializer: ' . $type); 32 | } 33 | } 34 | 35 | /** 36 | * @see \Pext\Serializer\Adapter\SerializerInterface::serialize() 37 | */ 38 | public function serialize($data, $options = array()) 39 | { 40 | return $this->serializer->serialize($data, $options); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Paranoia/Test/Payment/FactoryTest.php: -------------------------------------------------------------------------------- 1 | config = json_decode($config); 22 | } 23 | 24 | public function provider() 25 | { 26 | return array( 27 | array( 'estbank', '\\Paranoia\\Payment\\Adapter\\Est' ), 28 | array( 'garantibank', '\\Paranoia\\Payment\\Adapter\\Gvp' ), 29 | ); 30 | } 31 | 32 | /** 33 | * @param $configKey 34 | * @param string $className 35 | * 36 | * @dataProvider provider 37 | */ 38 | public function testInstanceCreation( $configKey, $className ) 39 | { 40 | $instance = Factory::createInstance($this->config, $configKey); 41 | $this->assertInstanceOf($className, $instance); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Factory.php: -------------------------------------------------------------------------------- 1 | adapter; 20 | $adapterClass = "\\Paranoia\\Payment\\Adapter\\{$adapter}"; 21 | if (! class_exists($adapterClass)) { 22 | throw new UnknownAdapter( 23 | 'Unknown payment adapter : ' . $adapterClass 24 | ); 25 | } 26 | return new $adapterClass( $config ); 27 | } 28 | 29 | /** 30 | * creates a new adapter instance by the specified pos key. 31 | * 32 | * @param StdClass $config 33 | * @param string $paymentMethod 34 | * 35 | * @throws Exception\UnknownPos 36 | * @return AdapterInterface 37 | */ 38 | public static function createInstance(StdClass$config, $paymentMethod) 39 | { 40 | if (! isset($config->{$paymentMethod})) { 41 | throw new UnknownPos('Unknown pos : ' . $paymentMethod); 42 | } 43 | return self::getAdapter($config->{$paymentMethod}); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Adapter/AdapterInterface.php: -------------------------------------------------------------------------------- 1 | validateEvent($eventName); 19 | $method = $this->getEventMethodName($eventName); 20 | $this->{$method}($parameter); 21 | } 22 | 23 | /** 24 | * returns generic method name for the 25 | * specified event name. 26 | * 27 | * @param string $eventName 28 | * 29 | * @return string 30 | */ 31 | private function getEventMethodName($eventName) 32 | { 33 | return ucfirst($eventName); 34 | } 35 | 36 | /** 37 | * validates eventname. 38 | * 39 | * @param string $eventName 40 | * 41 | * @return boolean 42 | * @throws \Paranoia\EventManager\Exception\UndefinedListenerMethod 43 | */ 44 | private function validateEvent($eventName) 45 | { 46 | $method = $this->getEventMethodName($eventName); 47 | if (!method_exists($this, $method)) { 48 | throw new UndefinedListenerMethod( 49 | 'Listener method is not defined for ' . $eventName 50 | ); 51 | } 52 | return true; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Paranoia/EventManager/EventManagerAbstract.php: -------------------------------------------------------------------------------- 1 | listeners[$eventName])) { 23 | $this->listeners[$eventName] = array(); 24 | } 25 | $this->listeners[$eventName][] = $listener; 26 | } 27 | 28 | /** 29 | * returns listener collection for the specified eventname. 30 | * 31 | * @param string $eventName 32 | * 33 | * @return array 34 | */ 35 | private function getListeners($eventName) 36 | { 37 | if (isset($this->listeners[$eventName])) { 38 | return $this->listeners[$eventName]; 39 | } 40 | return array(); 41 | } 42 | 43 | /** 44 | * trigger listener for the specified event. 45 | * 46 | * @param string $eventName 47 | * @param array $data (optional) 48 | */ 49 | protected function triggerEvent($eventName, $data = array()) 50 | { 51 | $parameter = new EventParameter( 52 | $this, 53 | $eventName, 54 | $data, 55 | microtime(true) 56 | ); 57 | 58 | /* @var $listener \Paranoia\EventManager\Listener\ListenerAbstract */ 59 | foreach ($this->getListeners($eventName) as $listener) { 60 | $listener->triggerEvent($eventName, $parameter); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Response/ResponseInterface.php: -------------------------------------------------------------------------------- 1 | adapter = new Http(); 28 | break; 29 | case self::CONNECTOR_TYPE_SOAP: 30 | $this->adapter = new Soap(); 31 | break; 32 | default: 33 | throw new UnknownCommunicationAdapter( 34 | 'Unknown communication adapter: ' . $connectorType 35 | ); 36 | } 37 | } 38 | 39 | /** 40 | * @see Paranoia\Communication\Adapter\AdapterInterface::sendRequest() 41 | */ 42 | public function sendRequest($url, $data, $options = null) 43 | { 44 | return $this->adapter->sendRequest($url, $data, $options); 45 | } 46 | 47 | /** 48 | * @see Paranoia\EventManager\EventManagerAbstract::addListener() 49 | */ 50 | public function addListener($eventName, ListenerAbstract $listener) 51 | { 52 | return $this->adapter->addListener($eventName, $listener); 53 | } 54 | 55 | /** 56 | * @see Paranoia\EventManager\EventManagerAbstract::getLastSentRequest() 57 | */ 58 | public function getLastSentRequest() 59 | { 60 | return $this->adapter->getLastSentRequest(); 61 | } 62 | 63 | /** 64 | * @see Paranoia\EventManager\EventManagerAbstract::getLastReceivedResponse() 65 | */ 66 | public function getLastReceivedResponse() 67 | { 68 | return $this->adapter->getLastReceivedResponse(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Paranoia/EventManager/EventParameter.php: -------------------------------------------------------------------------------- 1 | source = $source; 29 | $this->eventName = $eventName; 30 | $this->data = $data; 31 | } 32 | 33 | /** 34 | * returns event source 35 | * 36 | * @return \Paranoia\EventManager\EventManagerAbstract 37 | */ 38 | public function getSource() 39 | { 40 | return $this->source; 41 | } 42 | 43 | /** 44 | * sets event source 45 | * 46 | * @param \Paranoia\EventManager\EventManagerAbstract $source 47 | * 48 | * @return \Paranoia\EventManager\EventParameter 49 | */ 50 | public function setSource(EventManagerAbstract $source) 51 | { 52 | $this->source = $source; 53 | return $this; 54 | } 55 | 56 | /** 57 | * returns event name 58 | * 59 | * @return string 60 | */ 61 | public function getEventName() 62 | { 63 | return $this->eventName; 64 | } 65 | 66 | /** 67 | * sets event name 68 | * 69 | * @param string $eventName 70 | * 71 | * @return \Paranoia\EventManager\EventParameter 72 | */ 73 | public function setEventName($eventName) 74 | { 75 | $this->eventName = $eventName; 76 | return $this; 77 | } 78 | 79 | /** 80 | * returns data. 81 | * 82 | * @param string $key 83 | * 84 | * @return array 85 | */ 86 | public function getData($key = null) 87 | { 88 | if ($key==null) { 89 | return $this->data; 90 | } else { 91 | return (array_key_exists($key, $this->data)) ? 92 | $this->data[$key] : false; 93 | } 94 | } 95 | 96 | /** 97 | * sets data. 98 | * 99 | * @param array $data 100 | * 101 | * @return \Paranoia\EventManager\EventParameter 102 | */ 103 | public function setData($data) 104 | { 105 | $this->data = $data; 106 | return $this; 107 | } 108 | 109 | /** 110 | * returns event time. 111 | * 112 | * @return double 113 | */ 114 | public function getTime() 115 | { 116 | return $this->time; 117 | } 118 | 119 | /** 120 | * sets event time. 121 | * 122 | * @param double $time 123 | * 124 | * @return \Paranoia\EventManager\EventParameter 125 | */ 126 | public function setTime($time) 127 | { 128 | $this->time = $time; 129 | return $this; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /tests/Paranoia/Test/Payment/Adapter/EstTest.php: -------------------------------------------------------------------------------- 1 | config = json_decode($config); 26 | $this->bank = 'estbank'; 27 | } 28 | 29 | private function createNewOrder( $orderId = null, $amount = 10 ) 30 | { 31 | $testData = $this->config->{$this->bank}->testcard; 32 | $request = new Request(); 33 | if($orderId == null) { 34 | $request->setOrderId(sprintf('PRNY%s%s', time(), rand(1,9999))); 35 | } else { 36 | $request->setOrderId($orderId); 37 | } 38 | $request->setAmount($amount); 39 | $request->setCurrency('TRY'); 40 | $request->setCardNumber($testData->number); 41 | $request->setSecurityCode($testData->cvv); 42 | $request->setExpireMonth($testData->expire_month); 43 | $request->setExpireYear($testData->expire_year); 44 | return $request; 45 | } 46 | 47 | private function initializeAdapter() 48 | { 49 | $instance = Factory::createInstance($this->config, $this->bank); 50 | return $instance; 51 | } 52 | 53 | public function testSale() 54 | { 55 | $instance = $this->initializeAdapter(); 56 | $orderRequest = $this->createNewOrder(); 57 | $response = $instance->sale($orderRequest); 58 | $this->assertTrue($response->isSuccess()); 59 | return $orderRequest; 60 | } 61 | 62 | /** 63 | * @depends testSale 64 | */ 65 | public function testCancel( Request $saleRequest ) 66 | { 67 | $instance = $this->initializeAdapter(); 68 | $request = $this->createNewOrder($saleRequest->getOrderId()); 69 | $response = $instance->cancel($request); 70 | $this->assertTrue($response->isSuccess()); 71 | } 72 | 73 | public function testRefund() 74 | { 75 | $instance = $this->initializeAdapter(); 76 | $orderRequest = $this->createNewOrder(); 77 | $response = $instance->sale($orderRequest); 78 | $this->assertTrue($response->isSuccess()); 79 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId()); 80 | $response = $instance->refund($refundRequest); 81 | $this->assertTrue($response->isSuccess()); 82 | } 83 | 84 | public function testPartialRefund() 85 | { 86 | $amount = 10; 87 | $partialAmount = 5; 88 | $instance = $this->initializeAdapter(); 89 | $orderRequest = $this->createNewOrder(null, $amount); 90 | $response = $instance->sale($orderRequest); 91 | $this->assertTrue($response->isSuccess()); 92 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 93 | $response = $instance->refund($refundRequest); 94 | $this->assertTrue($response->isSuccess()); 95 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 96 | $response = $instance->refund($refundRequest); 97 | $this->assertTrue($response->isSuccess()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/Paranoia/Test/Payment/Adapter/GvpTest.php: -------------------------------------------------------------------------------- 1 | config = json_decode($config); 26 | $this->bank = 'garantibank'; 27 | } 28 | 29 | private function createNewOrder( $orderId = null, $amount = 10 ) 30 | { 31 | $testData = $this->config->{$this->bank}->testcard; 32 | $request = new Request(); 33 | if($orderId == null) { 34 | $request->setOrderId(sprintf('PRNY%s%s', time(), rand(1,9999))); 35 | } else { 36 | $request->setOrderId($orderId); 37 | } 38 | $request->setAmount($amount); 39 | $request->setCurrency('TRY'); 40 | $request->setCardNumber($testData->number); 41 | $request->setSecurityCode($testData->cvv); 42 | $request->setExpireMonth($testData->expire_month); 43 | $request->setExpireYear($testData->expire_year); 44 | return $request; 45 | } 46 | 47 | private function initializeAdapter() 48 | { 49 | $instance = Factory::createInstance($this->config, $this->bank); 50 | return $instance; 51 | } 52 | 53 | public function testSale() 54 | { 55 | $instance = $this->initializeAdapter(); 56 | $orderRequest = $this->createNewOrder(); 57 | $response = $instance->sale($orderRequest); 58 | $this->assertTrue($response->isSuccess()); 59 | return $orderRequest; 60 | } 61 | 62 | /** 63 | * @depends testSale 64 | */ 65 | public function testCancel( Request $saleRequest ) 66 | { 67 | $instance = $this->initializeAdapter(); 68 | $request = $this->createNewOrder($saleRequest->getOrderId()); 69 | $response = $instance->cancel($request); 70 | $this->assertTrue($response->isSuccess()); 71 | } 72 | 73 | public function testRefund() 74 | { 75 | $instance = $this->initializeAdapter(); 76 | $orderRequest = $this->createNewOrder(); 77 | $response = $instance->sale($orderRequest); 78 | $this->assertTrue($response->isSuccess()); 79 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId()); 80 | $response = $instance->refund($refundRequest); 81 | $this->assertTrue($response->isSuccess()); 82 | } 83 | 84 | public function testPartialRefund() 85 | { 86 | $amount = 10; 87 | $partialAmount = 5; 88 | $instance = $this->initializeAdapter(); 89 | $orderRequest = $this->createNewOrder(null, $amount); 90 | $response = $instance->sale($orderRequest); 91 | $this->assertTrue($response->isSuccess()); 92 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 93 | $response = $instance->refund($refundRequest); 94 | $this->assertTrue($response->isSuccess()); 95 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 96 | $response = $instance->refund($refundRequest); 97 | $this->assertTrue($response->isSuccess()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/Paranoia/Test/Payment/Adapter/PosnetTest.php: -------------------------------------------------------------------------------- 1 | config = json_decode($config); 28 | $this->bank = 'posnetbank'; 29 | } 30 | 31 | private function createNewOrder( $orderId = null, $amount = 10 ) 32 | { 33 | $testData = $this->config->{$this->bank}->testcard; 34 | $request = new Request(); 35 | if ($orderId == null) { 36 | $request->setOrderId(time()); 37 | } else { 38 | $request->setOrderId($orderId); 39 | } 40 | $request->setAmount($amount); 41 | $request->setCurrency('TRY'); 42 | $request->setCardNumber($testData->number); 43 | $request->setSecurityCode($testData->cvv); 44 | $request->setExpireMonth($testData->expire_month); 45 | $request->setExpireYear($testData->expire_year); 46 | return $request; 47 | } 48 | 49 | private function initializeAdapter() 50 | { 51 | $instance = Factory::createInstance($this->config, $this->bank); 52 | // remove comment character from the following lines to 53 | // displaying transaction logs. 54 | // $listener = new CommunicationListener(); 55 | // $instance->getConnector()->addListener('BeforeRequest', $listener); 56 | // $instance->getConnector()->addListener('AfterRequest', $listener); 57 | return $instance; 58 | } 59 | 60 | public function testSale() 61 | { 62 | $instance = $this->initializeAdapter(); 63 | $orderRequest = $this->createNewOrder(); 64 | $response = $instance->sale($orderRequest); 65 | //$this->assertTrue($response->isSuccess()); 66 | return $orderRequest; 67 | } 68 | 69 | /** 70 | * @depends testSale 71 | */ 72 | public function testCancel( Request $saleRequest ) 73 | { 74 | $instance = $this->initializeAdapter(); 75 | $request = $this->createNewOrder($saleRequest->getOrderId()); 76 | $response = $instance->cancel($request); 77 | //$this->assertTrue($response->isSuccess()); 78 | } 79 | 80 | public function testRefund() 81 | { 82 | $instance = $this->initializeAdapter(); 83 | $orderRequest = $this->createNewOrder(); 84 | $response = $instance->sale($orderRequest); 85 | //$this->assertTrue($response->isSuccess()); 86 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId()); 87 | $response = $instance->refund($refundRequest); 88 | //$this->assertTrue($response->isSuccess()); 89 | } 90 | 91 | public function testPartialRefund() 92 | { 93 | $amount = 10; 94 | $partialAmount = 5; 95 | $instance = $this->initializeAdapter(); 96 | $orderRequest = $this->createNewOrder(null, $amount); 97 | $response = $instance->sale($orderRequest); 98 | //$this->assertTrue($response->isSuccess()); 99 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 100 | $response = $instance->refund($refundRequest); 101 | //$this->assertTrue($response->isSuccess()); 102 | $refundRequest = $this->createNewOrder($orderRequest->getOrderId(), $partialAmount); 103 | $response = $instance->refund($refundRequest); 104 | //$this->assertTrue($response->isSuccess()); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Paranoia 2 | 3 | [![Build Status](https://travis-ci.org/ParanoiaProject/paranoia.svg?branch=master)](https://travis-ci.org/ibrahimgunduz34/paranoia) 4 | 5 | ## Nedir ? 6 | Paranoia, Türkiye dahilinde kullanılan popüler ödeme sistemlerinin tek bir API arayüzü üzerinden basitce kullanımına olanak veren açık kaynak kodlu bir kütüphanedir. 7 | 8 | ## Nasıl çalışır ? 9 | Paranoia kullanarak desteklenen senkron ve asenkron ödeme servisleri üzerinden kolayca satış, iptal ve iade işlemlerinizi gerçekleştirebilirsiniz. 10 | 11 | ## Kullanım: 12 | 13 | Repoyu kopyaladıktan sonra composer ile paranoia kurulumunu gerceklestirebilirsiniz. 14 | ```shell 15 | $ composer install 16 | ``` 17 | 18 | ### Örnek Satış İşlemi: 19 | 20 | ```php 21 | getConnector()->addListener('BeforeRequest', $listener); 40 | // $adapter->getConnector()->addListener('AfterRequest', $listener); 41 | 42 | $request = new Request(); 43 | $request->setCardNumber('5406675406675403') 44 | ->setSecurityCode('000') 45 | ->setExpireMonth(12) 46 | ->setExpireYear(2015) 47 | ->setOrderId('ORDER000000' . time()) 48 | ->setAmount(100.35) 49 | ->setCurrency('TRY'); 50 | 51 | try { 52 | $response = $adapter->sale($request); 53 | if($response->isSuccess()) { 54 | print "Odeme basariyla gerceklestirildi." . PHP_EOL; 55 | } else { 56 | print "Odeme basarisiz." . PHP_EOL; 57 | } 58 | } catch(CommunicationFailed $e) { 59 | print "Baglanti saglanamadi." . PHP_EOL; 60 | } catch(UnexpectedResponse $e) { 61 | print "Banka beklenmedik bir cevap dondu." . PHP_EOL; 62 | } catch(Exception $e) { 63 | print "Beklenmeyen bir hata olustu." . PHP_EOL; 64 | } 65 | ``` 66 | 67 | ## Desteklenen Ödeme Sistemleri: 68 | 69 | * ***Est*** 70 | * İşbankası, Akbank, Finansbank, Denizbank, Kuveytturk, Halkbank, Anadolubank, ING Bank, Citibank, Cardplus 71 | * ***Gvp*** 72 | * Denizbank, TEB, ING, Şekerbank, TFKB, Garanti 73 | * ***Posnet*** 74 | * Yapı Kredi, Vakıfbank, Anadolubank - ***Yakında*** 75 | * ***BKM Express*** 76 | * ***Yakında*** 77 | * ***Turkcell Cüzdan*** 78 | * ***Yakında*** 79 | * ***PayPal*** 80 | * ***Yakında*** 81 | * ***Ininal*** 82 | * ***Yakında*** 83 | 84 | ## Desteklenen Para Birimleri: 85 | 86 | * ***TRL:*** Türk Lirası 87 | * ***EUR:*** Avro 88 | * ***USD:*** Amerikan Doları 89 | 90 | ## Katkıda Bulunun: 91 | Siz de yapacağınız geliştirmelerle açık kaynaklı Paranoia kütüphanesine katkıda bulunabilirsiniz. 92 | 93 | Katkıda bulunmak için aşağıdaki işlem adımlarını gerçekleştirin: 94 | 95 | ### Hazırlık: 96 | 97 | * ***git@github.com:paranoiaproject/paranoia.git*** deposunu kendi github hesabınıza fork edin. 98 | * Kendi hesabınızdaki fork edilmiş repoyu yerel geliştirme ortamınıza kopyalayın. 99 | 100 | ```sh 101 | 102 | $ git clone git@github.com:youruser/paranoia.github 103 | 104 | ``` 105 | * ***git@github.com:paranoiaproject/paranoia.git*** reposunu yerel geliştirme ortamınıza upstream olarak tanımlayın. 106 | 107 | ```sh 108 | 109 | $ git remote add upstream https://github.com/paranoiaproject/paranoia 110 | 111 | ``` 112 | 113 | ### Değişikliklerin/Geliştirmelerin İletilmesi: 114 | 115 | * Projenin issues bölümünden dilediğiniz bir konuyu seçin veya yeni bir konu yaratın. 116 | * Geliştirmeye başlamadan önce upstreamdeki değişiklikleri yerel deponuza alın. 117 | 118 | ```sh 119 | 120 | $ git checkout master 121 | $ git fetch upstream 122 | $ git merge upstream/master 123 | 124 | ``` 125 | 126 | * Yeni bir dal oluşturun ve giriş yapın. 127 | 128 | ```sh 129 | 130 | $ git checkout -b 131 | 132 | ``` 133 | 134 | * Değişikliklerinizi tamamlayın ve yerel deponuza gönderin. 135 | 136 | ```sh 137 | 138 | $ git add . 139 | $ git commit -m "# Geliştirme hakkında kısa bir commit mesajı." 140 | 141 | ``` 142 | 143 | * Yerel depodaki değişimi fork ettiğiniz depoya iletin. 144 | 145 | ```sh 146 | 147 | $ git push origin 148 | 149 | ``` 150 | * Son olarak değişiklikleri bildirmek için bize bir ***pull request*** gönderin. 151 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Response/ResponseAbstract.php: -------------------------------------------------------------------------------- 1 | isSuccess; 58 | } 59 | 60 | /** 61 | * @see \Payment\Response\ResponseInterface::setIsSuccess() 62 | */ 63 | public function setIsSuccess($isSuccess) 64 | { 65 | $this->isSuccess = $isSuccess; 66 | return $this; 67 | } 68 | 69 | /** 70 | * @see \Payment\Response\ResponseInterface::getTransactionType() 71 | */ 72 | public function getTransactionType() 73 | { 74 | return $this->transactionType; 75 | } 76 | 77 | /** 78 | * @see \Payment\Response\ResponseInterface::setTransactionType() 79 | */ 80 | public function setTransactionType($transactionType) 81 | { 82 | $this->transactionType = $transactionType; 83 | return $this; 84 | } 85 | 86 | /** 87 | * @see \Payment\Response\ResponseInterface::getOrderId() 88 | */ 89 | public function getOrderId() 90 | { 91 | return $this->orderId; 92 | } 93 | 94 | /** 95 | * @see \Payment\Response\ResponseInterface::setOrderId() 96 | */ 97 | public function setOrderId($orderId) 98 | { 99 | $this->orderId = $orderId; 100 | return $this; 101 | } 102 | 103 | /** 104 | * @see \Payment\Response\ResponseInterface::getTransactionId() 105 | */ 106 | public function getTransactionId() 107 | { 108 | return $this->transactionId; 109 | } 110 | 111 | /** 112 | * @see \Payment\Response\ResponseInterface::setTransactionId() 113 | */ 114 | public function setTransactionId($transactionId) 115 | { 116 | $this->transactionId = $transactionId; 117 | return $this; 118 | } 119 | 120 | /** 121 | * returns auth code. 122 | * 123 | * @return string 124 | */ 125 | public function getAuthCode() 126 | { 127 | return $this->authCode; 128 | } 129 | 130 | /** 131 | * sets auth code to request object. 132 | * 133 | * @param string $authCode 134 | * 135 | * @return self 136 | */ 137 | public function setAuthCode($authCode) 138 | { 139 | $this->authCode = $authCode; 140 | return $this; 141 | } 142 | 143 | /** 144 | * @see \Payment\Response\ResponseInterface::getResponseCode() 145 | */ 146 | public function getResponseCode() 147 | { 148 | return $this->responseCode; 149 | } 150 | 151 | /** 152 | * @see \Payment\Response\ResponseInterface::setResponseCode() 153 | */ 154 | public function setResponseCode($responseCode) 155 | { 156 | $this->responseCode = $responseCode; 157 | return $this; 158 | } 159 | 160 | /** 161 | * @see \Payment\Response\ResponseInterface::getResponseCode() 162 | */ 163 | public function getResponseMessage() 164 | { 165 | return $this->responseMessage; 166 | } 167 | 168 | /** 169 | * @see \Payment\Response\ResponseInterface::setResponseMessage() 170 | */ 171 | public function setResponseMessage($responseMessage) 172 | { 173 | $this->responseMessage = $responseMessage; 174 | return $this; 175 | } 176 | 177 | /** 178 | * returns request as raw data. 179 | * 180 | * @return string 181 | */ 182 | public function getRawData() 183 | { 184 | return $this->rawData; 185 | } 186 | 187 | /** 188 | * sets response data as raw. 189 | * 190 | * @param string $rawData 191 | * 192 | * @return self 193 | */ 194 | public function setRawData($rawData) 195 | { 196 | $this->rawData = $rawData; 197 | return $this; 198 | } 199 | 200 | /** 201 | * @see \Payment\TransferInterface::getTime() 202 | */ 203 | public function getTime() 204 | { 205 | return $this->time; 206 | } 207 | 208 | /** 209 | * @see \Payment\TransferInterface::setTime() 210 | */ 211 | public function setTime($time) 212 | { 213 | $this->time = $time; 214 | return $this; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/Paranoia/Communication/Adapter/Http.php: -------------------------------------------------------------------------------- 1 | handler = curl_init(); 35 | } 36 | 37 | /** 38 | * validates http method. 39 | * 40 | * @param array $options 41 | * 42 | * @return bool 43 | * @throws \Paranoia\Communication\Exception\UndefinedHttpMethod 44 | */ 45 | private function validateMethod($options) 46 | { 47 | $requestMethods = array( 48 | self::METHOD_GET, 49 | self::METHOD_POST, 50 | self::METHOD_PUT, 51 | self::METHOD_DELETE 52 | ); 53 | if (!in_array($options[CURLOPT_CUSTOMREQUEST], $requestMethods)) { 54 | throw new UndefinedHttpMethod( 55 | 'Undefined http method: ' . $options[CURLOPT_CUSTOMREQUEST] 56 | ); 57 | } 58 | return true; 59 | } 60 | 61 | /** 62 | * attach data to options. 63 | * 64 | * @param string $data 65 | * @param array $curlOptions 66 | * 67 | * @return array 68 | */ 69 | private function attachData($data, &$curlOptions) 70 | { 71 | $method = $curlOptions[CURLOPT_CUSTOMREQUEST]; 72 | if ($method == self::METHOD_POST || $method == self::METHOD_PUT) { 73 | $curlOptions[CURLOPT_POSTFIELDS] = $data; 74 | } else { 75 | $url = $curlOptions[CURLOPT_URL]; 76 | $questionmarkPos = strpos($url, '?'); 77 | if ($questionmarkPos !== false) { 78 | $data .= '&' . substr($url, $questionmarkPos + 1); 79 | $url = substr($url, 0, $questionmarkPos); 80 | } 81 | $url .= '?' . $data; 82 | $curlOptions[CURLOPT_URL] = $url; 83 | } 84 | $this->lastSentRequest = $data; 85 | return $curlOptions; 86 | } 87 | 88 | /** 89 | * sets curl options to handler. 90 | * 91 | * @param string $url 92 | * @param string $data 93 | * @param array $options 94 | * 95 | * @return array 96 | */ 97 | private function setOptions($url, $data, $options) 98 | { 99 | if (!isset($options['method'])) { 100 | $options['method'] = self::METHOD_POST; 101 | } 102 | $curlOptions = array(CURLOPT_URL => $url, 103 | CURLOPT_RETURNTRANSFER => true, 104 | CURLOPT_SSL_VERIFYPEER => false, 105 | CURLOPT_HEADER => false, 106 | CURLOPT_CUSTOMREQUEST => $options['method']); 107 | $this->attachData($data, $curlOptions); 108 | curl_setopt_array($this->handler, $curlOptions); 109 | return $curlOptions; 110 | } 111 | 112 | /** 113 | * @see \Paranoia\Communication\Adapter\AdapterInterface::sendRequest() 114 | * 115 | * @throws \Paranoia\Communication\Exception\CommunicationFailed 116 | */ 117 | public function sendRequest($url, $data, $options = null) 118 | { 119 | $curlOptions = $this->setOptions($url, $data, $options); 120 | $this->validateMethod($curlOptions); 121 | $this->triggerEvent( 122 | self::EVENT_BEFORE_REQUEST, 123 | array('url' => $url, 'data' => $data) 124 | ); 125 | $response = curl_exec($this->handler); 126 | $this->triggerEvent( 127 | self::EVENT_AFTER_REQUEST, 128 | array('url' => $url, 'data' => $response) 129 | ); 130 | $this->lastReceivedResponse = $response; 131 | $error = curl_error($this->handler); 132 | if ($error) { 133 | $exception = new CommunicationFailed( 134 | 'Communication error occurred. Detail: '. $error 135 | ); 136 | 137 | $this->triggerEvent( 138 | self::EVENT_ON_EXCEPTION, 139 | array('url' => $url, 140 | 'last_request' => $data, 141 | 'last_response' => $response, 142 | 'exception' => $exception) 143 | ); 144 | throw $exception; 145 | } 146 | return $response; 147 | } 148 | 149 | /** 150 | * returns last sent request. 151 | * 152 | * @return string 153 | */ 154 | public function getLastSentRequest() 155 | { 156 | return $this->lastSentRequest; 157 | } 158 | 159 | /** 160 | * returns last received response from provider. 161 | * 162 | * @return string 163 | */ 164 | public function getLastReceivedResponse() 165 | { 166 | return $this->lastReceivedResponse; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Request.php: -------------------------------------------------------------------------------- 1 | orderId; 80 | } 81 | 82 | /** 83 | * sets order identity to request object. 84 | * 85 | * @param $orderId 86 | * 87 | * @return self 88 | */ 89 | public function setOrderId($orderId) 90 | { 91 | $this->orderId = $orderId; 92 | return $this; 93 | } 94 | 95 | /** 96 | * returns order amount. 97 | * 98 | * @return float 99 | */ 100 | public function getAmount() 101 | { 102 | return $this->amount; 103 | } 104 | 105 | /** 106 | * sets order amount to request object. 107 | * 108 | * @param float $amount 109 | * 110 | * @return self 111 | */ 112 | public function setAmount($amount) 113 | { 114 | $this->amount = $amount; 115 | return $this; 116 | } 117 | 118 | /** 119 | * returns currency code string which is three digit. 120 | * 121 | * @return string 122 | */ 123 | public function getCurrency() 124 | { 125 | return $this->currency; 126 | } 127 | 128 | /** 129 | * sets currency code to request object. 130 | * 131 | * @param string $currency 132 | * 133 | * @return self 134 | */ 135 | public function setCurrency($currency) 136 | { 137 | $this->currency = $currency; 138 | return $this; 139 | } 140 | 141 | /** 142 | * returns installment amount. 143 | * 144 | * @return integer 145 | */ 146 | public function getInstallment() 147 | { 148 | return $this->installment; 149 | } 150 | 151 | /** 152 | * set installment amount to object. 153 | * 154 | * @param integer $installment 155 | * 156 | * @return self 157 | */ 158 | public function setInstallment($installment) 159 | { 160 | $this->installment = $installment; 161 | return $this; 162 | } 163 | 164 | /** 165 | * returns card number. 166 | * 167 | * @return string 168 | */ 169 | public function getCardNumber() 170 | { 171 | return $this->cardNumber; 172 | } 173 | 174 | /** 175 | * sets card number to request object. 176 | * 177 | * @param string $cardNumber Numeric value 178 | * 179 | * @return self 180 | */ 181 | public function setCardNumber($cardNumber) 182 | { 183 | $this->cardNumber = $cardNumber; 184 | return $this; 185 | } 186 | 187 | /** 188 | * returns card security code. 189 | * 190 | * @return string 191 | */ 192 | public function getSecurityCode() 193 | { 194 | return $this->securityCode; 195 | } 196 | 197 | /** 198 | * sets card security code to request object. 199 | * 200 | * @param string $securityCode 201 | * 202 | * @return self 203 | */ 204 | public function setSecurityCode($securityCode) 205 | { 206 | $this->securityCode = $securityCode; 207 | return $this; 208 | } 209 | 210 | /** 211 | * returns expire month of card. 212 | * 213 | * @return integer 214 | */ 215 | public function getExpireMonth() 216 | { 217 | return $this->expireMonth; 218 | } 219 | 220 | /** 221 | * sets card expire month to request object. 222 | * 223 | * @param integer $expireMonth 224 | * 225 | * @return self 226 | */ 227 | public function setExpireMonth($expireMonth) 228 | { 229 | $this->expireMonth = $expireMonth; 230 | return $this; 231 | } 232 | 233 | /** 234 | * returns expire year of card. 235 | * 236 | * @return integer 237 | */ 238 | public function getExpireYear() 239 | { 240 | return $this->expireYear; 241 | } 242 | 243 | /** 244 | * sets card expire year to request object. 245 | * 246 | * @param integer $expireYear 247 | * 248 | * @return self 249 | */ 250 | public function setExpireYear($expireYear) 251 | { 252 | $this->expireYear = $expireYear; 253 | return $this; 254 | } 255 | 256 | /** 257 | * returns transaction id. 258 | * 259 | * @return string 260 | */ 261 | public function getTransactionId() 262 | { 263 | return $this->transactionId; 264 | } 265 | 266 | /** 267 | * sets transaction id to request object. 268 | * 269 | * @param string $transactionId 270 | * 271 | * @return self 272 | */ 273 | public function setTransactionId($transactionId) 274 | { 275 | $this->transactionId = $transactionId; 276 | return $this; 277 | } 278 | 279 | /** 280 | * returns auth code. 281 | * 282 | * @return string 283 | */ 284 | public function getAuthCode() 285 | { 286 | return $this->authCode; 287 | } 288 | 289 | /** 290 | * sets auth code to request object. 291 | * 292 | * @param string $authCode 293 | * 294 | * @return self 295 | */ 296 | public function setAuthCode($authCode) 297 | { 298 | $this->authCode = $authCode; 299 | return $this; 300 | } 301 | 302 | /** 303 | * returns request as raw data. 304 | * 305 | * @return string 306 | */ 307 | public function getRawData() 308 | { 309 | return $this->rawData; 310 | } 311 | 312 | /** 313 | * sets response data as raw. 314 | * 315 | * @param string $rawData 316 | * 317 | * @return self 318 | */ 319 | public function setRawData($rawData) 320 | { 321 | $this->rawData = $rawData; 322 | return $this; 323 | } 324 | 325 | /** 326 | * @see \Paranoia\Payment\TransferInterface::getTransactionType() 327 | */ 328 | public function getTransactionType() 329 | { 330 | return $this->transactionType; 331 | } 332 | 333 | /** 334 | * @see \Paranoia\Payment\TransferInterface::setTransactionType() 335 | */ 336 | public function setTransactionType($transactionType) 337 | { 338 | $this->transactionType = $transactionType; 339 | return $this; 340 | } 341 | 342 | /** 343 | * @see \Payment\TransferInterface::getTime() 344 | */ 345 | public function getTime() 346 | { 347 | return $this->time; 348 | } 349 | 350 | /** 351 | * @see \Payment\TransferInterface::setTime() 352 | */ 353 | public function setTime($time) 354 | { 355 | $this->time = $time; 356 | return $this; 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /src/Paranoia/Common/Serializer/Adapter/Xml.php: -------------------------------------------------------------------------------- 1 | saveXML(); 33 | */ 34 | namespace Paranoia\Common\Serializer\Adapter; 35 | 36 | use Paranoia\Common\Serializer\Exception\OptionError; 37 | use \DomDocument; 38 | use \Exception; 39 | 40 | class Xml implements SerializerInterface 41 | { 42 | 43 | /** 44 | * @var DomDocument 45 | */ 46 | private $xml = null; 47 | 48 | /** 49 | * @var string 50 | */ 51 | private $encoding = 'UTF-8'; 52 | 53 | public function serialize($data, $options = array()) 54 | { 55 | $options = $this->setDefaults((array) $options); 56 | return $this->createXML($options['root_name'], $data)->saveXml(); 57 | } 58 | 59 | private function setDefaults(array $options) 60 | { 61 | if (!isset($options['root_name'])) { 62 | throw new OptionError('root_name is required.'); 63 | } 64 | $defaults = array( 65 | 'version' => '1.0', 66 | 'encoding' => 'UTF-8', 67 | 'format_output' => true 68 | ); 69 | if (array_diff(array_keys($defaults), array_keys($options))) { 70 | foreach ($defaults as $key => $value) { 71 | $options[$key] = $value; 72 | } 73 | } 74 | return $options; 75 | } 76 | 77 | /** 78 | * Initialize the root XML node [optional] 79 | * 80 | * @param $version 81 | * @param $encoding 82 | * @param $format_output 83 | */ 84 | private function init($version = '1.0', $encoding = 'UTF-8', $format_output = true) 85 | { 86 | $this->xml = new DomDocument($version, $encoding); 87 | $this->xml->formatOutput = $format_output; 88 | $this->encoding = $encoding; 89 | } 90 | 91 | /** 92 | * Convert an Array to XML 93 | * 94 | * @param string $node_name - name of the root node to be converted 95 | * @param array $arr - aray to be converterd 96 | * 97 | * @return DomDocument 98 | */ 99 | 100 | private function &createXML($node_name, $arr = array()) 101 | { 102 | $xml = $this->getXMLRoot(); 103 | $xml->appendChild($this->convert($node_name, $arr)); 104 | $this->xml = null; // clear the xml node in the class for 2nd time use. 105 | return $xml; 106 | } 107 | 108 | /** 109 | * Convert an Array to XML 110 | * 111 | * @param string $node_name - name of the root node to be converted 112 | * @param array $arr - aray to be converterd 113 | * 114 | * @throws \Exception 115 | * @return \DOMNode 116 | */ 117 | private function &convert($node_name, $arr = array()) 118 | { 119 | 120 | //print_arr($node_name); 121 | $xml = $this->getXMLRoot(); 122 | $node = $xml->createElement($node_name); 123 | 124 | if (is_array($arr)) { 125 | // get the attributes first.; 126 | if (isset($arr['@attributes'])) { 127 | foreach ($arr['@attributes'] as $key => $value) { 128 | if (!$this->isValidTagName($key)) { 129 | throw new Exception( 130 | '[Array2XML] Illegal character in attribute name. attribute: '. 131 | $key.' in node: '.$node_name 132 | ); 133 | } 134 | $node->setAttribute($key, $this->bool2str($value)); 135 | } 136 | unset( $arr['@attributes'] ); //remove the key from the array once done. 137 | } 138 | // check if it has a value stored in @value, if yes store the value and return 139 | // else check if its directly stored as string 140 | if (isset($arr['@value'])) { 141 | $node->appendChild($xml->createTextNode($this->bool2str($arr['@value']))); 142 | unset($arr['@value']); //remove the key from the array once done. 143 | //return from recursion, as a note with value cannot have child nodes. 144 | return $node; 145 | } elseif (isset($arr['@cdata'])) { 146 | $node->appendChild($xml->createCDATASection($this->bool2str($arr['@cdata']))); 147 | unset($arr['@cdata']); //remove the key from the array once done. 148 | //return from recursion, as a note with cdata cannot have child nodes. 149 | return $node; 150 | } 151 | } 152 | //create subnodes using recursion 153 | if (is_array($arr)) { 154 | // recurse to get the node for that key 155 | foreach ($arr as $key => $value) { 156 | if (!$this->isValidTagName($key)) { 157 | throw new Exception( 158 | '[Array2XML] Illegal character in tag name. tag: '. 159 | $key.' in node: '.$node_name 160 | ); 161 | } 162 | if (is_array($value) && is_numeric(key($value))) { 163 | // MORE THAN ONE NODE OF ITS KIND; 164 | // if the new array is numeric index, means it is array of nodes of the same kind 165 | // it should follow the parent key name 166 | foreach ($value as $k => $v) { 167 | $node->appendChild($this->convert($key, $v)); 168 | } 169 | } else { 170 | // ONLY ONE NODE OF ITS KIND 171 | $node->appendChild($this->convert($key, $value)); 172 | } 173 | unset( $arr[$key] ); //remove the key from the array once done. 174 | } 175 | } 176 | // after we are done with all the keys in the array (if it is one) 177 | // we check if it has any text value, if yes, append it. 178 | if (!is_array($arr)) { 179 | $node->appendChild($xml->createTextNode($this->bool2str($arr))); 180 | } 181 | return $node; 182 | } 183 | 184 | /* 185 | * Get the root XML node, if there isn't one, create it. 186 | */ 187 | private function getXMLRoot() 188 | { 189 | if (empty($this->xml)) { 190 | $this->init(); 191 | } 192 | return $this->xml; 193 | } 194 | 195 | /* 196 | * Get string representation of boolean value 197 | */ 198 | private function bool2str($v) 199 | { 200 | //convert boolean to text value. 201 | $v = $v === true ? 'true' : $v; 202 | $v = $v === false ? 'false' : $v; 203 | return $v; 204 | } 205 | 206 | /* 207 | * Check if the tag name or attribute name contains illegal characters 208 | * Ref: http://www.w3.org/TR/xml/#sec-common-syn 209 | */ 210 | private function isValidTagName($tag) 211 | { 212 | $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i'; 213 | return preg_match($pattern, $tag, $matches) && $matches[0] == $tag; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Adapter/Est.php: -------------------------------------------------------------------------------- 1 | 'PreAuth', 20 | self::TRANSACTION_TYPE_POSTAUTHORIZATION => 'PostAuth', 21 | self::TRANSACTION_TYPE_SALE => 'Auth', 22 | self::TRANSACTION_TYPE_CANCEL => 'Void', 23 | self::TRANSACTION_TYPE_REFUND => 'Credit', 24 | self::TRANSACTION_TYPE_POINT_QUERY => '', 25 | self::TRANSACTION_TYPE_POINT_USAGE => '', 26 | ); 27 | 28 | /** 29 | * builds request base with common arguments. 30 | * 31 | * @return array 32 | */ 33 | private function buildBaseRequest() 34 | { 35 | $config = $this->config; 36 | return array( 37 | 'Name' => $config->username, 38 | 'Password' => $config->password, 39 | 'ClientId' => $config->client_id, 40 | 'Mode' => $config->mode 41 | ); 42 | } 43 | 44 | /** 45 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRequest() 46 | */ 47 | protected function buildRequest(Request $request, $requestBuilder) 48 | { 49 | $rawRequest = call_user_func(array( $this, $requestBuilder ), $request); 50 | $serializer = new Serializer(Serializer::XML); 51 | $xml = $serializer->serialize( 52 | array_merge($rawRequest, $this->buildBaseRequest()), 53 | array( 'root_name' => 'CC5Request' ) 54 | ); 55 | $data = array( 'DATA' => $xml ); 56 | $request->setRawData($xml); 57 | return http_build_query($data); 58 | } 59 | 60 | /** 61 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPreauthorizationRequest() 62 | */ 63 | protected function buildPreAuthorizationRequest(Request $request) 64 | { 65 | $amount = $this->formatAmount($request->getAmount()); 66 | $installment = $this->formatInstallment($request->getInstallment()); 67 | $currency = $this->formatCurrency($request->getCurrency()); 68 | $expireMonth = $this->formatExpireDate($request->getExpireMonth(), $request->getExpireYear()); 69 | $type = $this->getProviderTransactionType($request->getTransactionType()); 70 | $requestData = array( 71 | 'Type' => $type, 72 | 'Total' => $amount, 73 | 'Currency' => $currency, 74 | 'Taksit' => $installment, 75 | 'Number' => $request->getCardNumber(), 76 | 'Cvv2Val' => $request->getSecurityCode(), 77 | 'Expires' => $expireMonth, 78 | 'OrderId' => $request->getOrderId(), 79 | ); 80 | return $requestData; 81 | } 82 | 83 | /** 84 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPostAuthorizationRequest() 85 | */ 86 | protected function buildPostAuthorizationRequest(Request $request) 87 | { 88 | $type = $this->getProviderTransactionType($request->getTransactionType()); 89 | $requestData = array( 90 | 'Type' => $type, 91 | 'OrderId' => $request->getOrderId(), 92 | ); 93 | return $requestData; 94 | } 95 | 96 | /** 97 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildSaleRequest() 98 | */ 99 | protected function buildSaleRequest(Request $request) 100 | { 101 | $amount = $this->formatAmount($request->getAmount()); 102 | $installment = $this->formatInstallment($request->getInstallment()); 103 | $currency = $this->formatCurrency($request->getCurrency()); 104 | $expireMonth = $this->formatExpireDate($request->getExpireMonth(), $request->getExpireYear()); 105 | $type = $this->getProviderTransactionType($request->getTransactionType()); 106 | $requestData = array( 107 | 'Type' => $type, 108 | 'Total' => $amount, 109 | 'Currency' => $currency, 110 | 'Taksit' => $installment, 111 | 'Number' => $request->getCardNumber(), 112 | 'Cvv2Val' => $request->getSecurityCode(), 113 | 'Expires' => $expireMonth, 114 | 'OrderId' => $request->getOrderId(), 115 | ); 116 | return $requestData; 117 | } 118 | 119 | /** 120 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRefundRequest() 121 | */ 122 | protected function buildRefundRequest(Request $request) 123 | { 124 | $amount = $this->formatAmount($request->getAmount()); 125 | $currency = $this->formatCurrency($request->getCurrency()); 126 | $type = $this->getProviderTransactionType($request->getTransactionType()); 127 | $requestData = array( 128 | 'Type' => $type, 129 | 'Total' => $amount, 130 | 'Currency' => $currency, 131 | 'OrderId' => $request->getOrderId(), 132 | ); 133 | return $requestData; 134 | } 135 | 136 | /** 137 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildCancelRequest() 138 | */ 139 | protected function buildCancelRequest(Request $request) 140 | { 141 | $type = $this->getProviderTransactionType($request->getTransactionType()); 142 | $requestData = array( 143 | 'Type' => $type, 144 | 'OrderId' => $request->getOrderId(), 145 | ); 146 | if ($request->getTransactionId()) { 147 | $requestData['TransId'] = $request->getTransactionId(); 148 | } 149 | return $requestData; 150 | } 151 | 152 | /** 153 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 154 | */ 155 | protected function buildPointQueryRequest(Request $request) 156 | { 157 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 158 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 159 | throw $exception; 160 | } 161 | 162 | /** 163 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPointUsageRequest() 164 | */ 165 | protected function buildPointUsageRequest(Request $request) 166 | { 167 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 168 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 169 | throw $exception; 170 | } 171 | 172 | /** 173 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 174 | */ 175 | protected function parseResponse($rawResponse) 176 | { 177 | $response = new PaymentResponse(); 178 | try { 179 | /** 180 | * @var object $xml 181 | */ 182 | $xml = new \SimpleXmlElement($rawResponse); 183 | } catch ( \Exception $e ) { 184 | $exception = new UnexpectedResponse('Provider returned unexpected response: ' . $rawResponse); 185 | $this->triggerEvent( 186 | self::EVENT_ON_EXCEPTION, 187 | array_merge( 188 | $this->collectTransactionInformation(), 189 | array( 'exception' => $exception ) 190 | ) 191 | ); 192 | throw $exception; 193 | } 194 | $response->setIsSuccess((string)$xml->Response == 'Approved'); 195 | $response->setResponseCode((string)$xml->ProcReturnCode); 196 | if (!$response->isSuccess()) { 197 | $errorMessages = array(); 198 | if (property_exists($xml, 'Error')) { 199 | $errorMessages[] = sprintf('Error: %s', (string)$xml->Error); 200 | } 201 | if (property_exists($xml, 'ErrMsg')) { 202 | $errorMessages[] = sprintf( 203 | 'Error Message: %s ', 204 | (string)$xml->ErrMsg 205 | ); 206 | } 207 | if (property_exists($xml, 'Extra') && property_exists($xml->Extra, 'HOSTMSG')) { 208 | $errorMessages[] = sprintf( 209 | 'Host Message: %s', 210 | (string)$xml->Extra->HOSTMSG 211 | ); 212 | } 213 | $errorMessage = implode(' ', $errorMessages); 214 | $response->setResponseMessage($errorMessage); 215 | } else { 216 | $response->setResponseMessage('Success'); 217 | $response->setOrderId((string)$xml->OrderId); 218 | $response->setTransactionId((string)$xml->TransId); 219 | } 220 | $response->setRawData($rawResponse); 221 | $eventData = $this->collectTransactionInformation(); 222 | $eventName = $response->isSuccess() ? self::EVENT_ON_TRANSACTION_SUCCESSFUL : self::EVENT_ON_TRANSACTION_FAILED; 223 | $this->triggerEvent($eventName, $eventData); 224 | return $response; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Adapter/Posnet.php: -------------------------------------------------------------------------------- 1 | 'auth', 20 | self::TRANSACTION_TYPE_POSTAUTHORIZATION => 'capt', 21 | self::TRANSACTION_TYPE_SALE => 'sale', 22 | self::TRANSACTION_TYPE_CANCEL => 'reverse', 23 | self::TRANSACTION_TYPE_REFUND => 'return', 24 | self::TRANSACTION_TYPE_POINT_QUERY => 'pointinquiry', 25 | self::TRANSACTION_TYPE_POINT_USAGE => 'pointusage', 26 | ); 27 | 28 | /** 29 | * builds request base with common arguments. 30 | * 31 | * @return array 32 | */ 33 | private function buildBaseRequest() 34 | { 35 | $config = $this->config; 36 | return array( 37 | 'username' => $config->username, 38 | 'password' => $config->password, 39 | 'mid' => $config->client_id, 40 | 'tid' => $config->terminal_id 41 | ); 42 | } 43 | 44 | /** 45 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRequest() 46 | */ 47 | protected function buildRequest(Request $request, $requestBuilder) 48 | { 49 | $rawRequest = call_user_func(array( $this, $requestBuilder ), $request); 50 | $serializer = new Serializer(Serializer::XML); 51 | $xml = $serializer->serialize( 52 | array_merge($rawRequest, $this->buildBaseRequest()), 53 | array( 'root_name' => 'posnetRequest' ) 54 | ); 55 | $data = array( 'xmldata' => $xml ); 56 | $request->setRawData($xml); 57 | return http_build_query($data); 58 | } 59 | 60 | /** 61 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPreauthorizationRequest() 62 | */ 63 | protected function buildPreauthorizationRequest(Request $request) 64 | { 65 | $amount = $this->formatAmount($request->getAmount()); 66 | $installment = $this->formatInstallment($request->getInstallment()); 67 | $currency = $this->formatCurrency($request->getCurrency()); 68 | $expireMonth = $this->formatExpireDate($request->getExpireMonth(), $request->getExpireYear()); 69 | $type = $this->getProviderTransactionType($request->getTransactionType()); 70 | $requestData = array( 71 | $type => array( 72 | 'ccno' => $request->getCardNumber(), 73 | 'expDate' => $expireMonth, 74 | 'cvc' => $request->getSecurityCode(), 75 | 'amount' => $amount, 76 | 'currencyCode' => $currency, 77 | 'orderID' => $request->getOrderId(), 78 | 'installment' => $installment, 79 | 'extraPoint' => "000000", 80 | 'multiplePoint' => "000000" 81 | ) 82 | ); 83 | return $requestData; 84 | } 85 | 86 | /** 87 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPostAuthorizationRequest() 88 | */ 89 | protected function buildPostAuthorizationRequest(Request $request) 90 | { 91 | $amount = $this->formatAmount($request->getAmount()); 92 | $installment = $this->formatInstallment($request->getInstallment()); 93 | $currency = $this->formatCurrency($request->getCurrency()); 94 | $type = $this->getProviderTransactionType($request->getTransactionType()); 95 | $requestData = array( 96 | $type => array( 97 | 'hostLogKey' => $request->getTransactionId(), 98 | 'authCode' => $request->getAuthCode(), 99 | 'amount' => $amount, 100 | 'currencyCode' => $currency, 101 | 'installment' => $installment, 102 | 'extraPoint' => "000000", 103 | 'multiplePoint' => "000000" 104 | ) 105 | ); 106 | return $requestData; 107 | } 108 | 109 | /** 110 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildSaleRequest() 111 | */ 112 | protected function buildSaleRequest(Request $request) 113 | { 114 | $amount = $this->formatAmount($request->getAmount()); 115 | $installment = $this->formatInstallment($request->getInstallment()); 116 | $currency = $this->formatCurrency($request->getCurrency()); 117 | $expireMonth = $this->formatExpireDate($request->getExpireMonth(), $request->getExpireYear()); 118 | $type = $this->getProviderTransactionType($request->getTransactionType()); 119 | $requestData = array( 120 | $type => array( 121 | 'ccno' => $request->getCardNumber(), 122 | 'expDate' => $expireMonth, 123 | 'cvc' => $request->getSecurityCode(), 124 | 'amount' => $amount, 125 | 'currencyCode' => $currency, 126 | 'orderID' => $request->getOrderId(), 127 | 'installment' => $installment, 128 | 'extraPoint' => "000000", 129 | 'multiplePoint' => "000000" 130 | ) 131 | ); 132 | return $requestData; 133 | } 134 | 135 | /** 136 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRefundRequest() 137 | */ 138 | protected function buildRefundRequest(Request $request) 139 | { 140 | $amount = $this->formatAmount($request->getAmount()); 141 | $currency = $this->formatCurrency($request->getCurrency()); 142 | $type = $this->getProviderTransactionType($request->getTransactionType()); 143 | $requestData = array( 144 | $type => array( 145 | 'hostLogKey' => $request->getTransactionId(), 146 | 'amount' => $amount, 147 | 'currencyCode' => $currency 148 | ) 149 | ); 150 | return $requestData; 151 | } 152 | 153 | /** 154 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildCancelRequest() 155 | */ 156 | protected function buildCancelRequest(Request $request) 157 | { 158 | $type = $this->getProviderTransactionType($request->getTransactionType()); 159 | $requestData = array( 160 | $type => array( 161 | 'transaction' => "sale", 162 | 'hostLogKey' => $request->getTransactionId(), 163 | 'authCode' => $request->getAuthCode() 164 | ) 165 | ); 166 | return $requestData; 167 | } 168 | 169 | /** 170 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 171 | */ 172 | protected function buildPointQueryRequest(Request $request) 173 | { 174 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 175 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 176 | throw $exception; 177 | } 178 | 179 | /** 180 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPointUsageRequest() 181 | */ 182 | protected function buildPointUsageRequest(Request $request) 183 | { 184 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 185 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 186 | throw $exception; 187 | } 188 | 189 | /** 190 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 191 | */ 192 | protected function parseResponse($rawResponse) 193 | { 194 | $response = new PaymentResponse(); 195 | try { 196 | /** 197 | * @var object $xml 198 | */ 199 | $xml = new \SimpleXmlElement($rawResponse); 200 | } catch ( \Exception $e ) { 201 | $exception = new UnexpectedResponse('Provider returned unexpected response: ' . $rawResponse); 202 | $this->triggerEvent( 203 | self::EVENT_ON_EXCEPTION, 204 | array_merge( 205 | $this->collectTransactionInformation(), 206 | array( 'exception' => $exception ) 207 | ) 208 | ); 209 | throw $exception; 210 | } 211 | $response->setIsSuccess((int)$xml->approved > 0); 212 | if (!$response->isSuccess()) { 213 | $response->setResponseCode((string)$xml->respCode); 214 | $errorMessages = array(); 215 | if (property_exists($xml, 'respCode')) { 216 | $errorMessages[] = sprintf('Error: %s', (string)$xml->respCode); 217 | } 218 | if (property_exists($xml, 'respText')) { 219 | $errorMessages[] = sprintf('Error Message: %s ', (string)$xml->respText); 220 | } 221 | $errorMessage = implode(' ', $errorMessages); 222 | $response->setResponseMessage($errorMessage); 223 | } else { 224 | $response->setResponseCode("0000"); 225 | $response->setResponseMessage('Success'); 226 | if (property_exists($xml, 'orderId')) { 227 | $response->setOrderId((string)$xml->orderId); 228 | } 229 | $response->setTransactionId((string)$xml->hostlogkey); 230 | if (property_exists($xml, 'authCode')) { 231 | $response->setOrderId((string)$xml->authCode); 232 | } 233 | } 234 | $response->setRawData($rawResponse); 235 | $eventData = $this->collectTransactionInformation(); 236 | $eventName = $response->isSuccess() ? self::EVENT_ON_TRANSACTION_SUCCESSFUL : self::EVENT_ON_TRANSACTION_FAILED; 237 | $this->triggerEvent($eventName, $eventData); 238 | return $response; 239 | } 240 | 241 | /** 242 | * Posnet tutar değerinde nokta istemiyor. Örnek:15.00TL için 1500 gönderilmesi gerekiyor. 243 | * 244 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatAmount() 245 | */ 246 | protected function formatAmount($amount, $reverse = false) 247 | { 248 | if (!$reverse) { 249 | return ceil($amount * 100); 250 | } else { 251 | return (float)sprintf('%s.%s', substr($amount, 0, -2), substr($amount, -2)); 252 | } 253 | } 254 | 255 | /** 256 | * Posnet Son Kullanma Tarihini YYMM formatında istiyor. Örnek:03/2014 için 1403 257 | * 258 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatExpireDate() 259 | */ 260 | protected function formatExpireDate($month, $year) 261 | { 262 | return sprintf('%02s%02s', substr($year, -2), $month); 263 | } 264 | 265 | /** 266 | * Postnet Taksit sayısında daima 2 rakam gönderilmesini istiyor. 267 | * 268 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatInstallment() 269 | */ 270 | protected function formatInstallment($installment) 271 | { 272 | if (!is_numeric($installment) || intval($installment) <= 1) { 273 | return '00'; 274 | } 275 | return sprintf('%02s', $installment); 276 | } 277 | 278 | /** 279 | * Posnet currency kodları yerine ilk iki harfi istiyor. 280 | * 281 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatCurrency() 282 | */ 283 | protected function formatCurrency($currency) 284 | { 285 | switch ($currency) { 286 | case self::CURRENCY_TRY: 287 | return 'YT'; 288 | case self::CURRENCY_USD: 289 | return 'US'; 290 | case self::CURRENCY_EUR: 291 | return 'EU'; 292 | default: 293 | return 'YT'; 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Adapter/AdapterAbstract.php: -------------------------------------------------------------------------------- 1 | config = $config; 47 | $this->connector = new Connector(static::CONNECTOR_TYPE); 48 | } 49 | 50 | /** 51 | * build request data for preauthorization transaction. 52 | * 53 | * @param \Paranoia\Payment\Request $request 54 | * @return mixed 55 | */ 56 | abstract protected function buildPreAuthorizationRequest(Request $request); 57 | 58 | /** 59 | * build request data for postauthorization transaction. 60 | * 61 | * @param \Paranoia\Payment\Request $request 62 | * @return mixed 63 | */ 64 | abstract protected function buildPostAuthorizationRequest(Request $request); 65 | 66 | /** 67 | * build request data for sale transaction. 68 | * 69 | * @param \Paranoia\Payment\Request $request 70 | * @return mixed 71 | */ 72 | abstract protected function buildSaleRequest(Request $request); 73 | 74 | /** 75 | * build request data for refund transaction. 76 | * 77 | * @param \Paranoia\Payment\Request $request 78 | * @return mixed 79 | */ 80 | abstract protected function buildRefundRequest(Request $request); 81 | 82 | /** 83 | * build request data for cancel transaction. 84 | * 85 | * @param \Paranoia\Payment\Request $request 86 | * @return mixed 87 | */ 88 | abstract protected function buildCancelRequest(Request $request); 89 | 90 | /** 91 | * build complete raw data for the specified request. 92 | * 93 | * @param \Paranoia\Payment\Request $request 94 | * @param string $requestBuilder 95 | * @return mixed 96 | */ 97 | abstract protected function buildRequest(Request $request, $requestBuilder); 98 | 99 | /** 100 | * parses response from returned provider. 101 | * 102 | * @param string $rawResponse 103 | * @return \Paranoia\Payment\Response\PaymentResponse 104 | */ 105 | abstract protected function parseResponse($rawResponse); 106 | 107 | /** 108 | * returns connector object. 109 | * 110 | * @return \Paranoia\Communication\Adapter\AdapterInterface 111 | */ 112 | public function getConnector() 113 | { 114 | return $this->connector; 115 | } 116 | 117 | /** 118 | * sends request to remote host. 119 | * 120 | * @param string $url 121 | * @param mixed $data 122 | * @param array $options 123 | * @throws \ErrorException|\Exception 124 | * @return mixed 125 | */ 126 | protected function sendRequest($url, $data, $options = null) 127 | { 128 | try { 129 | return $this->getConnector()->sendRequest($url, $data, $options); 130 | } catch ( \ErrorException $e ) { 131 | $this->triggerEvent( 132 | self::EVENT_ON_EXCEPTION, 133 | array( 134 | 'exception' => $e, 135 | 'request' => $this->maskRequest($this->getConnector()->getLastSentRequest()), 136 | 'response' => $this->getConnector()->getLastReceivedResponse() 137 | ) 138 | ); 139 | throw $e; 140 | } 141 | } 142 | 143 | /** 144 | * formats the specified string currency code by iso currency codes. 145 | * 146 | * @param string $currency 147 | * @throws \Paranoia\Payment\Exception\ConfigurationError 148 | * @throws \Paranoia\Payment\Exception\UnknownCurrencyCode 149 | * @return integer 150 | */ 151 | protected function formatCurrency($currency) 152 | { 153 | if (!property_exists($this->config, 'currencyCodes')) { 154 | throw new ConfigurationError('Currency codes are not defined in configuration.'); 155 | } 156 | if (!property_exists($this->config->currencyCodes, $currency)) { 157 | throw new UnknownCurrencyCode(sprintf('%s is unknown currency.', $currency)); 158 | } 159 | return $this->config->currencyCodes->{$currency}; 160 | } 161 | 162 | /** 163 | * returns formatted amount with doth or without doth. 164 | * formatted number returns amount default without doth. 165 | * 166 | * @param string|float $amount 167 | * @param boolean $reverse 168 | * @return string 169 | */ 170 | protected function formatAmount($amount, $reverse = false) 171 | { 172 | if (!$reverse) { 173 | return number_format($amount, 2, '.', ''); 174 | } else { 175 | return (float)sprintf('%s.%s', substr($amount, 0, -2), substr($amount, -2)); 176 | } 177 | } 178 | 179 | /** 180 | * formats expire date as month/year 181 | * 182 | * @param int $month 183 | * @param int $year 184 | * @return string 185 | */ 186 | protected function formatExpireDate($month, $year) 187 | { 188 | return sprintf('%02s/%04s', $month, $year); 189 | } 190 | 191 | /** 192 | * returns formatted installment amount 193 | * 194 | * @param int $installment 195 | * @return string 196 | */ 197 | protected function formatInstallment($installment) 198 | { 199 | return (!is_numeric($installment) || intval($installment) <= 1) ? '' : $installment; 200 | } 201 | 202 | /** 203 | * stamps transfer objects with time and transaction type. 204 | * 205 | * @param \Paranoia\Payment\TransferInterface $transfer 206 | * @param string $transactionType 207 | */ 208 | private function stamp(TransferInterface $transfer, $transactionType) 209 | { 210 | $transfer->setTime(microtime(true)); 211 | $transfer->setTransactionType($transactionType); 212 | } 213 | 214 | /** 215 | * returns transaction code by expected provider. 216 | * 217 | * @param string $transactionType 218 | * @throws \Paranoia\Payment\Exception\UnknownTransactionType 219 | * @return string 220 | */ 221 | protected function getProviderTransactionType($transactionType) 222 | { 223 | if (!array_key_exists($transactionType, $this->transactionMap)) { 224 | throw new UnknownTransactionType('Transaction type is unknown: ' . $transactionType); 225 | } 226 | return $this->transactionMap[$transactionType]; 227 | } 228 | 229 | /** 230 | * @see \Paranoia\Payment\Adapter\AdapterInterface::preAuthorization() 231 | * @param \Paranoia\Payment\Request $request 232 | * @return object 233 | */ 234 | public function preAuthorization(Request $request) 235 | { 236 | $this->stamp($request, __FUNCTION__); 237 | $rawRequest = $this->buildRequest($request, 'buildPreAuthorizationRequest'); 238 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 239 | $response = $this->parseResponse($rawResponse); 240 | $this->stamp($response, __FUNCTION__); 241 | return $response; 242 | } 243 | 244 | /** 245 | * @see \Paranoia\Payment\Adapter\AdapterInterface::postAuthorization() 246 | * @param \Paranoia\Payment\Request $request 247 | * @return object 248 | */ 249 | public function postAuthorization(Request $request) 250 | { 251 | $this->stamp($request, __FUNCTION__); 252 | $rawRequest = $this->buildRequest($request, 'buildPostAuthorizationRequest'); 253 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 254 | $response = $this->parseResponse($rawResponse); 255 | $this->stamp($response, __FUNCTION__); 256 | return $response; 257 | } 258 | 259 | /** 260 | * @see \Paranoia\Payment\Adapter\AdapterInterface::sale() 261 | * @param \Paranoia\Payment\Request $request 262 | * @return object 263 | */ 264 | public function sale(Request $request) 265 | { 266 | $this->stamp($request, __FUNCTION__); 267 | $rawRequest = $this->buildRequest($request, 'buildSaleRequest'); 268 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 269 | $response = $this->parseResponse($rawResponse); 270 | $this->stamp($response, __FUNCTION__); 271 | return $response; 272 | } 273 | 274 | /** 275 | * @see \Paranoia\Payment\Adapter\AdapterInterface::refund() 276 | * @param \Paranoia\Payment\Request $request 277 | * @return object 278 | */ 279 | public function refund(Request $request) 280 | { 281 | $this->stamp($request, __FUNCTION__); 282 | $rawRequest = $this->buildRequest($request, 'buildRefundRequest'); 283 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 284 | $response = $this->parseResponse($rawResponse); 285 | $this->stamp($response, __FUNCTION__); 286 | return $response; 287 | } 288 | 289 | /** 290 | * @see \Paranoia\Payment\Adapter\AdapterInterface::cancel() 291 | * @param \Paranoia\Payment\Request $request 292 | * @return object 293 | */ 294 | public function cancel(Request $request) 295 | { 296 | $this->stamp($request, __FUNCTION__); 297 | $rawRequest = $this->buildRequest($request, 'buildCancelRequest'); 298 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 299 | $response = $this->parseResponse($rawResponse); 300 | $this->stamp($response, __FUNCTION__); 301 | return $response; 302 | } 303 | 304 | /** 305 | * @see \Paranoia\Payment\Adapter\AdapterInterface::pointQuery() 306 | * @param \Paranoia\Payment\Request $request 307 | * @return object 308 | */ 309 | public function pointQuery(Request $request) 310 | { 311 | $this->stamp($request, __FUNCTION__); 312 | $rawRequest = $this->buildRequest($request, 'buildPointQueryRequest'); 313 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 314 | $response = $this->parseResponse($rawResponse); 315 | $this->stamp($response, __FUNCTION__); 316 | return $response; 317 | } 318 | 319 | /** 320 | * @see \Paranoia\Payment\Adapter\AdapterInterface::pointUsage() 321 | * @param \Paranoia\Payment\Request $request 322 | * @return object 323 | */ 324 | public function pointUsage(Request $request) 325 | { 326 | $this->stamp($request, __FUNCTION__); 327 | $rawRequest = $this->buildRequest($request, 'buildPointUsageRequest'); 328 | $rawResponse = $this->sendRequest($this->config->api_url, $rawRequest); 329 | $response = $this->parseResponse($rawResponse); 330 | $this->stamp($response, __FUNCTION__); 331 | return $response; 332 | } 333 | 334 | /** 335 | * mask some critical information in transaction request. 336 | * 337 | * @param string $rawRequest 338 | * @return string 339 | */ 340 | protected function maskRequest($rawRequest) 341 | { 342 | return $rawRequest; 343 | } 344 | 345 | /** 346 | * collects transaction information. 347 | * 348 | * @return array 349 | */ 350 | protected function collectTransactionInformation() 351 | { 352 | $backtrace = debug_backtrace(); 353 | $data = array( 354 | 'transaction' => $backtrace[2]['function'], 355 | 'request' => $this->maskRequest($this->getConnector()->getLastSentRequest()), 356 | 'response' => $this->getConnector()->getLastReceivedResponse(), 357 | ); 358 | return $data; 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /src/Paranoia/Payment/Adapter/Gvp.php: -------------------------------------------------------------------------------- 1 | 'preauth', 20 | self::TRANSACTION_TYPE_POSTAUTHORIZATION => 'postauth', 21 | self::TRANSACTION_TYPE_SALE => 'sales', 22 | self::TRANSACTION_TYPE_CANCEL => 'void', 23 | self::TRANSACTION_TYPE_REFUND => 'refund', 24 | self::TRANSACTION_TYPE_POINT_QUERY => 'pointinquiry', 25 | self::TRANSACTION_TYPE_POINT_USAGE => 'pointusage', 26 | ); 27 | 28 | /** 29 | * builds request base with common arguments. 30 | * 31 | * @param Request $request 32 | * @return array 33 | */ 34 | private function buildBaseRequest(Request $request) 35 | { 36 | $terminal = $this->buildTerminal($request); 37 | $customer = $this->buildCustomer(); 38 | $order = $this->buildOrder($request); 39 | $transaction = $this->buildTransaction($request); 40 | return array( 41 | 'Version' => '0.01', 42 | 'Mode' => $this->config->mode, 43 | 'Terminal' => $terminal, 44 | 'Order' => $order, 45 | 'Customer' => $customer, 46 | 'Transaction' => $transaction 47 | ); 48 | } 49 | 50 | /** 51 | * builds terminal section of request. 52 | * 53 | * @param Request $request 54 | * @return array 55 | */ 56 | private function buildTerminal(Request $request) 57 | { 58 | $config = $this->config; 59 | list($username, $password) = $this->getApiCredentialsByRequest( 60 | $request->getTransactionType() 61 | ); 62 | $hash = $this->getTransactionHash($request, $password); 63 | return array( 64 | 'ProvUserID' => $username, 65 | 'HashData' => $hash, 66 | 'UserID' => $username, 67 | 'ID' => $config->terminal_id, 68 | 'MerchantID' => $config->merchant_id 69 | ); 70 | } 71 | 72 | /** 73 | * builds customer section of request. 74 | * 75 | * @return array 76 | */ 77 | private function buildCustomer() 78 | { 79 | /** 80 | * we don't want to share customer information 81 | * to bank. 82 | */ 83 | return array( 84 | 'IPAddress' => '127.0.0.1', 85 | 'EmailAddress' => 'dummy@dummy.net' 86 | ); 87 | } 88 | 89 | /** 90 | * builds card section of request. 91 | * 92 | * @param Request $request 93 | * @return array 94 | */ 95 | private function buildCard(Request $request) 96 | { 97 | $expireMonth = $this->formatExpireDate( 98 | $request->getExpireMonth(), 99 | $request->getExpireYear() 100 | ); 101 | return array( 102 | 'Number' => $request->getCardNumber(), 103 | 'ExpireDate' => $expireMonth, 104 | 'CVV2' => $request->getSecurityCode() 105 | ); 106 | } 107 | 108 | /** 109 | * builds order section of request. 110 | * 111 | * @param Request $request 112 | * @return array 113 | */ 114 | private function buildOrder(Request $request) 115 | { 116 | return array( 117 | 'OrderID' => $request->getOrderId(), 118 | 'GroupID' => null, 119 | 'Description' => null 120 | ); 121 | } 122 | 123 | /** 124 | * builds terminal section of request. 125 | * 126 | * @param Request $request 127 | * @param integer $cardHolderPresentCode 128 | * @param string $originalRetrefNum 129 | * @return array 130 | */ 131 | private function buildTransaction( 132 | Request $request, 133 | $cardHolderPresentCode = 0, 134 | $originalRetrefNum = null 135 | ) { 136 | $transactionType = $request->getTransactionType(); 137 | $installment = ($request->getInstallment()) ? $this->formatInstallment($request->getInstallment()) : null; 138 | $amount = $this->isAmountRequired($request) ? $this->formatAmount($request->getAmount()) : '1'; 139 | $currency = ($request->getCurrency()) ? $this->formatCurrency($request->getCurrency()) : null; 140 | $type = $this->getProviderTransactionType($transactionType); 141 | return array( 142 | 'Type' => $type, 143 | 'InstallmentCnt' => $installment, 144 | 'Amount' => $amount, 145 | 'CurrencyCode' => $currency, 146 | 'CardholderPresentCode' => $cardHolderPresentCode, 147 | 'MotoInd' => 'N', 148 | 'OriginalRetrefNum' => $originalRetrefNum 149 | ); 150 | } 151 | 152 | /** 153 | * returns boolean true, when amount field is required 154 | * for request transaction type. 155 | * 156 | * @param Request $request 157 | * @return boolean 158 | */ 159 | private function isAmountRequired(Request $request) 160 | { 161 | return in_array( 162 | $request->getTransactionType(), 163 | array( 164 | self::TRANSACTION_TYPE_SALE, 165 | self::TRANSACTION_TYPE_PREAUTHORIZATION, 166 | self::TRANSACTION_TYPE_POSTAUTHORIZATION, 167 | ) 168 | ); 169 | } 170 | 171 | /** 172 | * returns boolean true, when card number field is required 173 | * for request transaction type. 174 | * 175 | * @param Request $request 176 | * @return boolean 177 | */ 178 | private function isCardNumberRequired(Request $request) 179 | { 180 | return in_array( 181 | $request->getTransactionType(), 182 | array( 183 | self::TRANSACTION_TYPE_SALE, 184 | self::TRANSACTION_TYPE_PREAUTHORIZATION, 185 | ) 186 | ); 187 | } 188 | 189 | /** 190 | * returns api credentials by transaction type of request. 191 | * 192 | * @param string $transactionType 193 | * @return array 194 | */ 195 | private function getApiCredentialsByRequest($transactionType) 196 | { 197 | $isAuth = in_array( 198 | $transactionType, 199 | array( 200 | self::TRANSACTION_TYPE_SALE, 201 | self::TRANSACTION_TYPE_PREAUTHORIZATION, 202 | self::TRANSACTION_TYPE_POSTAUTHORIZATION, 203 | ) 204 | ); 205 | $config = $this->config; 206 | if ($isAuth) { 207 | return array( $config->auth_username, $config->auth_password ); 208 | } else { 209 | return array( $config->refund_username, $config->refund_password ); 210 | } 211 | } 212 | 213 | /** 214 | * returns security hash for using in transaction hash. 215 | * 216 | * @param string $password 217 | * @return string 218 | */ 219 | private function getSecurityHash($password) 220 | { 221 | $config = $this->config; 222 | $tidPrefix = str_repeat('0', 9 - strlen($config->terminal_id)); 223 | $terminalId = sprintf('%s%s', $tidPrefix, $config->terminal_id); 224 | return strtoupper(SHA1(sprintf('%s%s', $password, $terminalId))); 225 | } 226 | 227 | /** 228 | * returns transaction hash for using in transaction request. 229 | * 230 | * @param Request $request 231 | * @param string $password 232 | * @return string 233 | */ 234 | private function getTransactionHash(Request $request, $password) 235 | { 236 | $config = $this->config; 237 | $orderId = $request->getOrderId(); 238 | $terminalId = $config->terminal_id; 239 | $cardNumber = $this->isCardNumberRequired($request) ? $request->getCardNumber() : ''; 240 | $amount = $this->isAmountRequired($request) ? $this->formatAmount($request->getAmount()) : '1'; 241 | $securityData = $this->getSecurityHash($password); 242 | return strtoupper( 243 | sha1( 244 | sprintf( 245 | '%s%s%s%s%s', 246 | $orderId, 247 | $terminalId, 248 | $cardNumber, 249 | $amount, 250 | $securityData 251 | ) 252 | ) 253 | ); 254 | } 255 | 256 | /** 257 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRequest() 258 | */ 259 | protected function buildRequest(Request $request, $requestBuilder) 260 | { 261 | $rawRequest = call_user_func(array( $this, $requestBuilder ), $request); 262 | $serializer = new Serializer(Serializer::XML); 263 | $xml = $serializer->serialize( 264 | $rawRequest, 265 | array( 'root_name' => 'GVPSRequest' ) 266 | ); 267 | $data = array( 'data' => $xml ); 268 | $request->setRawData($xml); 269 | return http_build_query($data); 270 | } 271 | 272 | /** 273 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPreauthorizationRequest() 274 | */ 275 | protected function buildPreAuthorizationRequest(Request $request) 276 | { 277 | $requestData = array( 'Card' => $this->buildCard($request) ); 278 | return array_merge($requestData, $this->buildBaseRequest($request)); 279 | } 280 | 281 | /** 282 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPostAuthorizationRequest() 283 | */ 284 | protected function buildPostAuthorizationRequest(Request $request) 285 | { 286 | $requestData = $this->buildBaseRequest($request); 287 | return $requestData; 288 | } 289 | 290 | /** 291 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildSaleRequest() 292 | */ 293 | protected function buildSaleRequest(Request $request) 294 | { 295 | $requestData = array( 'Card' => $this->buildCard($request) ); 296 | return array_merge($requestData, $this->buildBaseRequest($request)); 297 | } 298 | 299 | /** 300 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildRefundRequest() 301 | */ 302 | protected function buildRefundRequest(Request $request) 303 | { 304 | return $this->buildBaseRequest($request); 305 | } 306 | 307 | /** 308 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildCancelRequest() 309 | */ 310 | protected function buildCancelRequest(Request $request) 311 | { 312 | $requestData = $this->buildBaseRequest($request); 313 | $transactionId = ($request->getTransactionId()) ? $request->getTransactionId() : null; 314 | $transaction = $this->buildTransaction($request, 0, $transactionId); 315 | $requestData['Transaction'] = $transaction; 316 | return $requestData; 317 | } 318 | 319 | /** 320 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 321 | */ 322 | protected function buildPointQueryRequest(Request $request) 323 | { 324 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 325 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 326 | throw $exception; 327 | } 328 | 329 | /** 330 | * @see Paranoia\Payment\Adapter\AdapterAbstract::buildPointUsageRequest() 331 | */ 332 | protected function buildPointUsageRequest(Request $request) 333 | { 334 | $exception = new UnimplementedMethod('Provider method not implemented: ' . $request->getTransactionType()); 335 | $this->triggerEvent(self::EVENT_ON_EXCEPTION, array( 'exception' => $exception )); 336 | throw $exception; 337 | } 338 | 339 | /** 340 | * @see Paranoia\Payment\Adapter\AdapterAbstract::parseResponse() 341 | */ 342 | protected function parseResponse($rawResponse) 343 | { 344 | $response = new PaymentResponse(); 345 | try { 346 | /** 347 | * @var object $xml 348 | */ 349 | $xml = new \SimpleXmlElement($rawResponse); 350 | } catch ( \Exception $e ) { 351 | throw new UnexpectedResponse('Provider returned unexpected response: ' . $rawResponse); 352 | } 353 | $response->setIsSuccess((string)$xml->Transaction->Response->Code == '00'); 354 | $response->setResponseCode((string)$xml->Transaction->ReasonCode); 355 | if (!$response->isSuccess()) { 356 | $errorMessages = array(); 357 | if (property_exists($xml->Transaction->Response, 'ErrorMsg')) { 358 | $errorMessages[] = sprintf( 359 | 'Error Message: %s', 360 | (string)$xml->Transaction->Response->ErrorMsg 361 | ); 362 | } 363 | if (property_exists($xml->Transaction->Response, 'SysErrMsg')) { 364 | $errorMessages[] = sprintf( 365 | 'System Error Message: %s', 366 | (string)$xml->Transaction->Response->SysErrMsg 367 | ); 368 | } 369 | $errorMessage = implode(' ', $errorMessages); 370 | $response->setResponseMessage($errorMessage); 371 | } else { 372 | $response->setResponseMessage('Success'); 373 | $response->setOrderId((string)$xml->Order->OrderID); 374 | $response->setTransactionId((string)$xml->Transaction->RetrefNum); 375 | } 376 | $response->setRawData($rawResponse); 377 | return $response; 378 | } 379 | 380 | /** 381 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatAmount() 382 | */ 383 | protected function formatAmount($amount, $reverse = false) 384 | { 385 | if (!$reverse) { 386 | return number_format($amount, 2, '', ''); 387 | } else { 388 | return (float)sprintf('%s.%s', substr($amount, 0, -2), substr($amount, -2)); 389 | } 390 | } 391 | 392 | /** 393 | * @see Paranoia\Payment\Adapter\AdapterAbstract::formatExpireDate() 394 | */ 395 | protected function formatExpireDate($month, $year) 396 | { 397 | return sprintf('%02s%s', $month, substr($year, -2)); 398 | } 399 | } 400 | --------------------------------------------------------------------------------