PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/braintree/braintree_php/lib/Braintree/TransactionGateway.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 445 lines | 288 code | 36 blank | 121 comment | 8 complexity | 4282d7497100c26afcd709fd77eae0bd MD5 | raw file
  1. <?php
  2. /**
  3. * Braintree TransactionGateway processor
  4. * Creates and manages transactions
  5. *
  6. *
  7. * <b>== More information ==</b>
  8. *
  9. * For more detailed information on Transactions, see {@link http://www.braintreepayments.com/gateway/transaction-api http://www.braintreepaymentsolutions.com/gateway/transaction-api}
  10. *
  11. * @package Braintree
  12. * @category Resources
  13. * @copyright 2014 Braintree, a division of PayPal, Inc.
  14. */
  15. final class Braintree_TransactionGateway
  16. {
  17. private $_gateway;
  18. private $_config;
  19. private $_http;
  20. public function __construct($gateway)
  21. {
  22. $this->_gateway = $gateway;
  23. $this->_config = $gateway->config;
  24. $this->_config->assertHasAccessTokenOrKeys();
  25. $this->_http = new Braintree_Http($gateway->config);
  26. }
  27. public function cloneTransaction($transactionId, $attribs)
  28. {
  29. Braintree_Util::verifyKeys(self::cloneSignature(), $attribs);
  30. return $this->_doCreate('/transactions/' . $transactionId . '/clone', array('transactionClone' => $attribs));
  31. }
  32. /**
  33. * @ignore
  34. * @access private
  35. * @param array $attribs
  36. * @return object
  37. */
  38. private function create($attribs)
  39. {
  40. Braintree_Util::verifyKeys(self::createSignature(), $attribs);
  41. return $this->_doCreate('/transactions', array('transaction' => $attribs));
  42. }
  43. /**
  44. *
  45. * @ignore
  46. * @access private
  47. * @param array $attribs
  48. * @return object
  49. * @throws Braintree_Exception_ValidationError
  50. */
  51. private function createNoValidate($attribs)
  52. {
  53. $result = $this->create($attribs);
  54. return Braintree_Util::returnObjectOrThrowException(__CLASS__, $result);
  55. }
  56. /**
  57. *
  58. * @access public
  59. * @param array $attribs
  60. * @return object
  61. */
  62. public function createFromTransparentRedirect($queryString)
  63. {
  64. trigger_error("DEPRECATED: Please use Braintree_TransparentRedirectRequest::confirm", E_USER_NOTICE);
  65. $params = Braintree_TransparentRedirect::parseAndValidateQueryString(
  66. $queryString
  67. );
  68. return $this->_doCreate(
  69. '/transactions/all/confirm_transparent_redirect_request',
  70. array('id' => $params['id'])
  71. );
  72. }
  73. /**
  74. *
  75. * @access public
  76. * @param none
  77. * @return string
  78. */
  79. public function createTransactionUrl()
  80. {
  81. trigger_error("DEPRECATED: Please use Braintree_TransparentRedirectRequest::url", E_USER_NOTICE);
  82. return $this->_config->baseUrl() . $this->_config->merchantPath() .
  83. '/transactions/all/create_via_transparent_redirect_request';
  84. }
  85. public static function cloneSignature()
  86. {
  87. return array('amount', 'channel', array('options' => array('submitForSettlement')));
  88. }
  89. /**
  90. * creates a full array signature of a valid gateway request
  91. * @return array gateway request signature format
  92. */
  93. public static function createSignature()
  94. {
  95. return array(
  96. 'amount',
  97. 'billingAddressId',
  98. 'channel',
  99. 'customerId',
  100. 'deviceData',
  101. 'deviceSessionId',
  102. 'fraudMerchantId',
  103. 'merchantAccountId',
  104. 'orderId',
  105. 'paymentMethodNonce',
  106. 'paymentMethodToken',
  107. 'purchaseOrderNumber',
  108. 'recurring',
  109. 'serviceFeeAmount',
  110. 'shippingAddressId',
  111. 'taxAmount',
  112. 'taxExempt',
  113. 'threeDSecureToken',
  114. 'type',
  115. 'venmoSdkPaymentMethodCode',
  116. array('creditCard' =>
  117. array('token', 'cardholderName', 'cvv', 'expirationDate', 'expirationMonth', 'expirationYear', 'number'),
  118. ),
  119. array('customer' =>
  120. array(
  121. 'id', 'company', 'email', 'fax', 'firstName',
  122. 'lastName', 'phone', 'website'),
  123. ),
  124. array('billing' =>
  125. array(
  126. 'firstName', 'lastName', 'company', 'countryName',
  127. 'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',
  128. 'extendedAddress', 'locality', 'postalCode', 'region',
  129. 'streetAddress'),
  130. ),
  131. array('shipping' =>
  132. array(
  133. 'firstName', 'lastName', 'company', 'countryName',
  134. 'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',
  135. 'extendedAddress', 'locality', 'postalCode', 'region',
  136. 'streetAddress'),
  137. ),
  138. array('options' =>
  139. array(
  140. 'holdInEscrow',
  141. 'storeInVault',
  142. 'storeInVaultOnSuccess',
  143. 'submitForSettlement',
  144. 'addBillingAddressToPaymentMethod',
  145. 'venmoSdkSession',
  146. 'storeShippingAddressInVault',
  147. 'payeeEmail',
  148. array('three_d_secure' =>
  149. array('required')
  150. ),
  151. array('paypal' =>
  152. array(
  153. 'payeeEmail',
  154. 'customField'
  155. )
  156. )
  157. ),
  158. ),
  159. array('customFields' => array('_anyKey_')
  160. ),
  161. array('descriptor' => array('name', 'phone', 'url')),
  162. array('paypalAccount' => array('payeeEmail')),
  163. array('industry' =>
  164. array('industryType',
  165. array('data' =>
  166. array(
  167. 'folioNumber',
  168. 'checkInDate',
  169. 'checkOutDate',
  170. 'travelPackage',
  171. 'departureDate',
  172. 'lodgingCheckInDate',
  173. 'lodgingCheckOutDate',
  174. 'lodgingName',
  175. 'roomRate'
  176. )
  177. )
  178. )
  179. )
  180. );
  181. }
  182. /**
  183. *
  184. * @access public
  185. * @param array $attribs
  186. * @return object
  187. */
  188. public function credit($attribs)
  189. {
  190. return $this->create(array_merge($attribs, array('type' => Braintree_Transaction::CREDIT)));
  191. }
  192. /**
  193. *
  194. * @access public
  195. * @param array $attribs
  196. * @return object
  197. * @throws Braintree_Exception_ValidationError
  198. */
  199. public function creditNoValidate($attribs)
  200. {
  201. $result = $this->credit($attribs);
  202. return Braintree_Util::returnObjectOrThrowException(__CLASS__, $result);
  203. }
  204. /**
  205. * @access public
  206. *
  207. */
  208. public function find($id)
  209. {
  210. $this->_validateId($id);
  211. try {
  212. $path = $this->_config->merchantPath() . '/transactions/' . $id;
  213. $response = $this->_http->get($path);
  214. return Braintree_Transaction::factory($response['transaction']);
  215. } catch (Braintree_Exception_NotFound $e) {
  216. throw new Braintree_Exception_NotFound(
  217. 'transaction with id ' . $id . ' not found'
  218. );
  219. }
  220. }
  221. /**
  222. * new sale
  223. * @param array $attribs
  224. * @return array
  225. */
  226. public function sale($attribs)
  227. {
  228. return $this->create(array_merge(array('type' => Braintree_Transaction::SALE), $attribs));
  229. }
  230. /**
  231. * roughly equivalent to the ruby bang method
  232. * @access public
  233. * @param array $attribs
  234. * @return array
  235. * @throws Braintree_Exception_ValidationsFailed
  236. */
  237. public function saleNoValidate($attribs)
  238. {
  239. $result = $this->sale($attribs);
  240. return Braintree_Util::returnObjectOrThrowException(__CLASS__, $result);
  241. }
  242. /**
  243. * Returns a ResourceCollection of transactions matching the search query.
  244. *
  245. * If <b>query</b> is a string, the search will be a basic search.
  246. * If <b>query</b> is a hash, the search will be an advanced search.
  247. * For more detailed information and examples, see {@link http://www.braintreepayments.com/gateway/transaction-api#searching http://www.braintreepaymentsolutions.com/gateway/transaction-api}
  248. *
  249. * @param mixed $query search query
  250. * @param array $options options such as page number
  251. * @return object Braintree_ResourceCollection
  252. * @throws InvalidArgumentException
  253. */
  254. public function search($query)
  255. {
  256. $criteria = array();
  257. foreach ($query as $term) {
  258. $criteria[$term->name] = $term->toparam();
  259. }
  260. $path = $this->_config->merchantPath() . '/transactions/advanced_search_ids';
  261. $response = $this->_http->post($path, array('search' => $criteria));
  262. if (array_key_exists('searchResults', $response)) {
  263. $pager = array(
  264. 'object' => $this,
  265. 'method' => 'fetch',
  266. 'methodArgs' => array($query)
  267. );
  268. return new Braintree_ResourceCollection($response, $pager);
  269. } else {
  270. throw new Braintree_Exception_DownForMaintenance();
  271. }
  272. }
  273. public function fetch($query, $ids)
  274. {
  275. $criteria = array();
  276. foreach ($query as $term) {
  277. $criteria[$term->name] = $term->toparam();
  278. }
  279. $criteria["ids"] = Braintree_TransactionSearch::ids()->in($ids)->toparam();
  280. $path = $this->_config->merchantPath() . '/transactions/advanced_search';
  281. $response = $this->_http->post($path, array('search' => $criteria));
  282. return Braintree_Util::extractattributeasarray(
  283. $response['creditCardTransactions'],
  284. 'transaction'
  285. );
  286. }
  287. /**
  288. * void a transaction by id
  289. *
  290. * @param string $id transaction id
  291. * @return object Braintree_Result_Successful|Braintree_Result_Error
  292. */
  293. public function void($transactionId)
  294. {
  295. $this->_validateId($transactionId);
  296. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/void';
  297. $response = $this->_http->put($path);
  298. return $this->_verifyGatewayResponse($response);
  299. }
  300. /**
  301. *
  302. */
  303. public function voidNoValidate($transactionId)
  304. {
  305. $result = $this->void($transactionId);
  306. return Braintree_Util::returnObjectOrThrowException(__CLASS__, $result);
  307. }
  308. public function submitForSettlement($transactionId, $amount = null)
  309. {
  310. $this->_validateId($transactionId);
  311. $path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/submit_for_settlement';
  312. $response = $this->_http->put($path, array('transaction' => array('amount' => $amount)));
  313. return $this->_verifyGatewayResponse($response);
  314. }
  315. public function submitForSettlementNoValidate($transactionId, $amount = null)
  316. {
  317. $result = $this->submitForSettlement($transactionId, $amount);
  318. return Braintree_Util::returnObjectOrThrowException(__CLASS__, $result);
  319. }
  320. public function holdInEscrow($transactionId)
  321. {
  322. $this->_validateId($transactionId);
  323. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/hold_in_escrow';
  324. $response = $this->_http->put($path, array());
  325. return $this->_verifyGatewayResponse($response);
  326. }
  327. public function releaseFromEscrow($transactionId)
  328. {
  329. $this->_validateId($transactionId);
  330. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/release_from_escrow';
  331. $response = $this->_http->put($path, array());
  332. return $this->_verifyGatewayResponse($response);
  333. }
  334. public function cancelRelease($transactionId)
  335. {
  336. $this->_validateId($transactionId);
  337. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/cancel_release';
  338. $response = $this->_http->put($path, array());
  339. return $this->_verifyGatewayResponse($response);
  340. }
  341. public function refund($transactionId, $amount = null)
  342. {
  343. self::_validateId($transactionId);
  344. $params = array('transaction' => array('amount' => $amount));
  345. $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/refund';
  346. $response = $this->_http->post($path, $params);
  347. return $this->_verifyGatewayResponse($response);
  348. }
  349. /**
  350. * sends the create request to the gateway
  351. *
  352. * @ignore
  353. * @param var $subPath
  354. * @param array $params
  355. * @return mixed
  356. */
  357. public function _doCreate($subPath, $params)
  358. {
  359. $fullPath = $this->_config->merchantPath() . $subPath;
  360. $response = $this->_http->post($fullPath, $params);
  361. return $this->_verifyGatewayResponse($response);
  362. }
  363. /**
  364. * verifies that a valid transaction id is being used
  365. * @ignore
  366. * @param string transaction id
  367. * @throws InvalidArgumentException
  368. */
  369. private function _validateId($id = null) {
  370. if (empty($id)) {
  371. throw new InvalidArgumentException(
  372. 'expected transaction id to be set'
  373. );
  374. }
  375. if (!preg_match('/^[0-9a-z]+$/', $id)) {
  376. throw new InvalidArgumentException(
  377. $id . ' is an invalid transaction id.'
  378. );
  379. }
  380. }
  381. /**
  382. * generic method for validating incoming gateway responses
  383. *
  384. * creates a new Braintree_Transaction object and encapsulates
  385. * it inside a Braintree_Result_Successful object, or
  386. * encapsulates a Braintree_Errors object inside a Result_Error
  387. * alternatively, throws an Unexpected exception if the response is invalid.
  388. *
  389. * @ignore
  390. * @param array $response gateway response values
  391. * @return object Result_Successful or Result_Error
  392. * @throws Braintree_Exception_Unexpected
  393. */
  394. private function _verifyGatewayResponse($response)
  395. {
  396. if (isset($response['transaction'])) {
  397. // return a populated instance of Braintree_Transaction
  398. return new Braintree_Result_Successful(
  399. Braintree_Transaction::factory($response['transaction'])
  400. );
  401. } else if (isset($response['apiErrorResponse'])) {
  402. return new Braintree_Result_Error($response['apiErrorResponse']);
  403. } else {
  404. throw new Braintree_Exception_Unexpected(
  405. "Expected transaction or apiErrorResponse"
  406. );
  407. }
  408. }
  409. }