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 }