File indexing completed on 2025-02-23 05:32:03
0001 <?php 0002 /** 0003 * ocs-webserver 0004 * 0005 * Copyright 2016 by pling GmbH. 0006 * 0007 * This file is part of ocs-webserver. 0008 * 0009 * This program is free software: you can redistribute it and/or modify 0010 * it under the terms of the GNU Affero General Public License as 0011 * published by the Free Software Foundation, either version 3 of the 0012 * License, or (at your option) any later version. 0013 * 0014 * This program is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 * GNU Affero General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Affero General Public License 0020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 **/ 0022 0023 class Local_Payment_Dwolla_Gateway implements Local_Payment_GatewayInterface 0024 { 0025 /** @var Local_Payment_Dwolla_UserData */ 0026 protected $_paymentUserData; 0027 /** @var string */ 0028 protected $_checkoutEndpoint; 0029 /** @var string Transaction mode. Can be 'live' or 'test' */ 0030 protected $_mode; 0031 /** @var boolean */ 0032 protected $_allowGuestCheckout; 0033 /** @var boolean */ 0034 protected $_allowFundingSources; 0035 /** @var string comma delimited value possible values: 'credit', 'banks', 'fisync', 'realtime', 'true', 'false' */ 0036 protected $_additionalFundingSources; 0037 0038 /** @var string callback url for transaction response */ 0039 protected $_ipnNotificationUrl; 0040 /** @var string redirect URL after thes authorize or cancel the purchase */ 0041 protected $_returnUrl; 0042 /** @var Local_Payment_ResponseInterface */ 0043 protected $_lastResponse; 0044 /** @var string */ 0045 protected $_message; 0046 /** @var null|Zend_Log|Zend_Log_Writer_Abstract */ 0047 protected $_logger; 0048 /** @var array|Zend_Config */ 0049 protected $_config; 0050 0051 0052 /** 0053 * @param array|Zend_config $config 0054 * @param Zend_Log_Writer_Abstract $logger 0055 * @throws Local_Payment_Exception 0056 */ 0057 function __construct($config, $logger = null) 0058 { 0059 if (is_array($config)) { 0060 $this->_config = new Zend_Config($config); 0061 } else { 0062 if ($config instanceof Zend_Config) { 0063 $this->_config = $config; 0064 } 0065 } 0066 if (is_null($logger)) { 0067 $this->_logger = Zend_Registry::get('logger'); 0068 } else { 0069 if ($logger instanceof Zend_Log) { 0070 $this->_logger = $logger; 0071 } else { 0072 throw new Local_Payment_Exception('Logger must be an instance of Zend_Log'); 0073 } 0074 } 0075 0076 $this->_paymentUserData = new Local_Payment_Dwolla_UserData(); 0077 $this->_allowFundingSources = true; 0078 $this->_allowGuestCheckout = true; 0079 $this->_additionalFundingSources = 'true'; 0080 } 0081 0082 /** 0083 * @return string 0084 */ 0085 public function getCheckoutEndpoint() 0086 { 0087 return ($this->_config->api->endpoint . '/payment/checkout/' . $this->_lastResponse->getPaymentId()); 0088 } 0089 0090 /** 0091 * @param Local_Payment_UserDataInterface $userData 0092 * @throws Exception 0093 */ 0094 public function setUserDataStore($userData) 0095 { 0096 if (false === ($userData instanceof Local_Payment_UserDataInterface)) { 0097 throw new Exception('Wrong data type for user data'); 0098 } 0099 $this->_paymentUserData = $userData; 0100 } 0101 0102 /** 0103 * @return Local_Payment_PayPal_UserData 0104 */ 0105 public function getUserDataStore() 0106 { 0107 return $this->_paymentUserData; 0108 } 0109 0110 /** 0111 * @param float $amount 0112 * @param string $requestMsg 0113 * @throws Local_Payment_Exception 0114 * @return Local_Payment_ResponseInterface 0115 */ 0116 public function requestPayment($amount, $requestMsg = null) 0117 { 0118 Zend_Registry::get('logger')->debug(__METHOD__ . ' - ' . print_r(func_get_args(), true)); 0119 0120 if (empty($this->_returnUrl)) { 0121 throw new Local_Payment_Exception('return url was not set.'); 0122 } 0123 0124 if (empty($this->_ipnNotificationUrl)) { 0125 throw new Local_Payment_Exception('ipn notification url was not set.'); 0126 } 0127 0128 // Create request body 0129 $requestBody = array( 0130 'Key' => $this->_config->consumer->access_key, 0131 'Secret' => $this->_config->consumer->access_secret, 0132 'Test' => ($this->_mode == 'test') ? 'true' : 'false', 0133 'AdditionalFundingSources' => $this->_additionalFundingSources, 0134 'AllowGuestCheckout' => $this->_allowGuestCheckout ? 'true' : 'false', 0135 'AllowFundingSources' => $this->_allowFundingSources ? 'true' : 'false', 0136 'PurchaseOrder' => array( 0137 'DestinationId' => $this->_paymentUserData->getPaymentUserId(), 0138 'Total' => $amount, 0139 'FacilitatorAmount' => 0, 0140 'Notes' => $requestMsg 0141 ), 0142 'Redirect' => $this->_returnUrl, 0143 'Callback' => $this->_ipnNotificationUrl 0144 ); 0145 0146 $response = $this->_makeRequest($requestBody, 'payment/request', false); 0147 if (APPLICATION_ENV != 'production') { 0148 $this->_logger->debug(__METHOD__ . '- response - ' . print_r($response, true) . PHP_EOL); 0149 } 0150 0151 $this->_lastResponse = new Local_Payment_Dwolla_ResponsePayRequest($response); 0152 if (APPLICATION_ENV != 'production') { 0153 $this->_logger->debug(__METHOD__ . ' - lastResponse - ' . print_r($this->_lastResponse, true) . PHP_EOL); 0154 } 0155 0156 if (false === $this->_lastResponse->isSuccessful()) { 0157 throw new Local_Payment_Exception('Dwolla payment request failed. Request response:' . print_r($this->_lastResponse->getRawMessage(), 0158 true)); 0159 } 0160 0161 return $this->_lastResponse; 0162 0163 } 0164 0165 /** 0166 * @param array $request 0167 * @param string $apiNameOperation 0168 * @param bool $withAuthHeader 0169 * @throws Local_Payment_Exception 0170 * @return array 0171 */ 0172 protected function _makeRequest($request, $apiNameOperation, $withAuthHeader = true) 0173 { 0174 $url = $this->_config->api->endpoint . '/' . $apiNameOperation; 0175 $http = new Zend_Http_Client($url); 0176 if (true === $withAuthHeader) { 0177 $http->setHeaders($this->_buildHeader($this->_config)); 0178 } 0179 $http->setHeaders('Content-Type', 'application/json'); 0180 $http->setMethod(Zend_Http_Client::POST); 0181 $http->setRawData(json_encode($request)); 0182 0183 try { 0184 $response = $http->request(); 0185 } catch (Zend_Http_Client_Exception $e) { 0186 throw new Local_Payment_Exception('Error while request Dwolla website.', 0, $e); 0187 } 0188 0189 if (false === $response) { 0190 $logMsg = __METHOD__ . "::Error while request Dwolla Website.\n Server replay was: " . $http->getLastResponse()->getStatus() . PHP_EOL . $http->getLastResponse()->getMessage() . PHP_EOL; 0191 $logMsg .= __METHOD__ . '::' . print_r($http->getLastRequest(), true) . PHP_EOL; 0192 $logMsg .= __METHOD__ . '::' . print_r($response->getHeaders(), true) . PHP_EOL; 0193 $logMsg .= __METHOD__ . '::' . print_r($response->getBody(), true) . PHP_EOL; 0194 $this->_logger->err($logMsg); 0195 throw new Local_Payment_Exception('Error while request Dwolla website.'); 0196 } else { 0197 $logMsg = __METHOD__ . '::' . print_r($http->getLastRequest(), true) . PHP_EOL; 0198 $logMsg .= __METHOD__ . '::' . print_r($response->getHeaders(), true) . PHP_EOL; 0199 $logMsg .= __METHOD__ . '::' . print_r($response->getBody(), true) . PHP_EOL; 0200 $this->_logger->debug($logMsg); 0201 } 0202 0203 return json_decode($response->getBody(), true); 0204 } 0205 0206 /** 0207 * Build all HTTP headers required for the API call. 0208 * 0209 * @access protected 0210 * @param array|Zend_Config $config 0211 * @return array $headers 0212 */ 0213 protected function _buildHeader($config = null) 0214 { 0215 if (is_array($config)) { 0216 $config = new Zend_Config($config); 0217 } 0218 $header = array( 0219 'Content-Type: application/json' 0220 ); 0221 0222 return $header; 0223 } 0224 0225 /** 0226 * @return mixed 0227 */ 0228 public function getMode() 0229 { 0230 return $this->_mode; 0231 } 0232 0233 /** 0234 * @param mixed $mode 0235 */ 0236 public function setMode($mode = 'live') 0237 { 0238 $this->_mode = $mode; 0239 } 0240 0241 /** 0242 * @return string 0243 */ 0244 public function getIpnNotificationUrl() 0245 { 0246 return $this->_ipnNotificationUrl; 0247 } 0248 0249 /** 0250 * @param string $ipnNotificationUrl 0251 */ 0252 public function setIpnNotificationUrl($ipnNotificationUrl) 0253 { 0254 $this->_ipnNotificationUrl = $ipnNotificationUrl; 0255 } 0256 0257 /** 0258 * @return string 0259 */ 0260 public function getReturnUrl() 0261 { 0262 return $this->_returnUrl; 0263 } 0264 0265 /** 0266 * @param string $returnUrl 0267 */ 0268 public function setReturnUrl($returnUrl) 0269 { 0270 $this->_returnUrl = $returnUrl; 0271 } 0272 0273 }