tpayCardAPI

CardAPI class.

Defined (1)

The class is defined in the following location(s).

/includes/lib/src/_class_tpay/cardApi.php  
  1. class CardAPI 
  2. const PRESALE = 'presale'; 
  3. const EMPTYCODE = 'Client auth code is empty.'; 
  4. const INVALIDCODE = 'Client auth code is invalid.'; 
  5.  
  6. /** 
  7. * PaymentCardAPI class constructor 
  8. * @param string $cardApiKey api key 
  9. * @param string $cardApiPassword api password 
  10. * @param string $verificationCode verification code 
  11. * @param string $hashAlg hash algorithm 
  12. * @throws TException 
  13. */ 
  14.  
  15. const METHOD = 'method'; 
  16. const NAME = 'name'; 
  17. const EMAIL = 'email'; 
  18. const DESC = 'desc'; 
  19. const AMOUNT = 'amount'; 
  20. const CURRENCY = 'currency'; 
  21. const SIGN = 'sign'; 
  22. const APIPASS = 'api_password'; 
  23. const LANGUAGE = 'language'; 
  24. const SALE = 'sale'; 
  25. const SALEAUTH = 'sale_auth'; 
  26. const CLIAUTH = 'cli_auth'; 
  27. /** 
  28. * tpay payment url 
  29. * @var string 
  30. */ 
  31. private $apiURL = 'https://secure.transferuj.pl/api/cards/'; 
  32. /** 
  33. * Card api key 
  34. * @var string 
  35. */ 
  36. private $apiKey; 
  37. /** 
  38. * Card api pass 
  39. * @var string 
  40. */ 
  41. private $apiPass; 
  42. /** 
  43. * Api verification code 
  44. * @var string 
  45. */ 
  46. private $verificationCode; 
  47. /** 
  48. * The same as chosen in merchant panel (https://secure.transferuj.pl/panel) 
  49. * In card api tab preferences 
  50. * @var string 
  51. */ 
  52. private $hashAlg; 
  53.  
  54. public function __construct($cardApiKey, $cardApiPassword, $verificationCode = '', $hashAlg = 'sha1') 
  55. Validate::validateCardApiKey($cardApiKey); 
  56. Validate::validateCardApiPassword($cardApiPassword); 
  57. Validate::validateCardHashAlg($hashAlg); 
  58. if ($verificationCode !== '') { 
  59. Validate::validateCardCode($verificationCode); 
  60.  
  61. $this->apiKey = $cardApiKey; 
  62. $this->apiPass = $cardApiPassword; 
  63. $this->hashAlg = $hashAlg; 
  64. $this->verificationCode = $verificationCode; 
  65.  
  66. Util::loadClass('curl'); 
  67.  
  68. /** 
  69. * Method used to sale initialization in tpay system. 
  70. * Successful request returns sale_auth used to redirect client to transaction panel 
  71. * @param string $clientName client name 
  72. * @param string $clientEmail client email 
  73. * @param string $saleDescription sale description 
  74. * @param float $amount amount 
  75. * @param string $currency currency 
  76. * @param string|null $orderID order id 
  77. * @param bool $onetimer 
  78. * @param string $lang 
  79. * @return bool|mixed 
  80. */ 
  81. public function registerSale( 
  82. $clientName,  
  83. $clientEmail,  
  84. $saleDescription,  
  85. $amount,  
  86. $currency = '985',  
  87. $orderID = null,  
  88. $onetimer = true,  
  89. $lang = 'pl',  
  90. $powUrl = true 
  91. return $this->registerSaleBase( 
  92. $clientName,  
  93. $clientEmail,  
  94. $saleDescription,  
  95. $amount,  
  96. $currency,  
  97. $orderID,  
  98. $onetimer,  
  99. false,  
  100. null,  
  101. $lang,  
  102. $powUrl 
  103. ); 
  104.  
  105. /** 
  106. * Prepare for register sale @see $this->registerSale 
  107. * @param string $clientName client name 
  108. * @param string $clientEmail client email 
  109. * @param string $saleDescription sale description 
  110. * @param float $amount amount 
  111. * @param string $currency currency 
  112. * @param string|null $orderID order id 
  113. * @param bool $onetimer 
  114. * @param bool $direct 
  115. * @param string|null $saledata encrypted credit card data 
  116. * @param string $lang 
  117. * @return bool|mixed 
  118. * @throws TException 
  119. */ 
  120. private function registerSaleBase( 
  121. $clientName, $clientEmail, $saleDescription, $amount, $currency = '985', $orderID = null,  
  122. $onetimer = true, $direct = false, $saledata = null, $lang = 'pl', $enablePowUrl = false, $powUrl = '',  
  123. $powUrlBlad = '' 
  124. $amount = number_format(str_replace(array(', ', ' '), array('.', ''), $amount), 2, '.', ''); 
  125.  
  126. $params = $this->recogniseMethod($direct, $saledata); 
  127.  
  128. $params = array_merge($params, array( 
  129. static::NAME => $clientName,  
  130. static::EMAIL => $clientEmail,  
  131. static::DESC => $saleDescription,  
  132. static::AMOUNT => $amount,  
  133. )); 
  134. $params = array_merge($params, $this->prepareSecondaryParams($currency, $orderID, $onetimer, $lang,  
  135. $enablePowUrl)); 
  136.  
  137. $params[static::SIGN] = hash($this->hashAlg, implode('', $params) . $this->verificationCode); 
  138. $params[static::APIPASS] = $this->apiPass; 
  139.  
  140. $params = array_merge($params, $this->checkReturnUrls($powUrl, $powUrlBlad)); 
  141.  
  142. Util::log('Card request', print_r($params, true)); 
  143. return $this->postRequest($this->apiURL . $this->apiKey, $params); 
  144.  
  145. /** 
  146. * Prepare for register sale @see $this->registerSale 
  147. * @param string $saledata 
  148. * @param bool $direct 
  149. * @return array 
  150. */ 
  151. private function recogniseMethod($direct = false, $saledata = null) 
  152.  
  153. if ($direct && !empty($saledata)) { 
  154. $params = array( 
  155. static::METHOD => 'directsale',  
  156. 'card' => $saledata,  
  157. ); 
  158. } elseif (!$direct && !empty($saledata)) { 
  159. $params = array( 
  160. static::METHOD => 'securesale',  
  161. 'card' => $saledata,  
  162. ); 
  163. } else { 
  164. $params = array( 
  165. static::METHOD => 'register_sale',  
  166. ); 
  167. return $params; 
  168.  
  169. /** 
  170. * Prepare for register sale @see $this->registerSale 
  171. * @param string $currency currency 
  172. * @param string|null $orderID order id 
  173. * @param bool $onetimer 
  174. * @param string $lang 
  175. * @param bool $enablePowUrl 
  176. * @return array 
  177. */ 
  178. private function prepareSecondaryParams($currency = '985', $orderID = '',  
  179. $onetimer = true, $lang = 'pl', $enablePowUrl = false) 
  180. $params = array(); 
  181. if ($currency) { 
  182. $params[static::CURRENCY] = $currency; 
  183. if ($orderID) { 
  184. $params['order_id'] = $orderID; 
  185. if ($onetimer) { 
  186. $params['onetimer'] = '1'; 
  187. if ($lang) { 
  188. $params[static::LANGUAGE] = Validate::validateCardLanguage($lang); 
  189. if ($enablePowUrl) { 
  190. $params['enable_pow_url'] = '1'; 
  191.  
  192. return $params; 
  193.  
  194. /** 
  195. * Execute post request to card API 
  196. * @param string $url url 
  197. * @param array $params 
  198. * @return bool|mixed 
  199. */ 
  200. private function postRequest($url, $params = array()) 
  201. $curlRes = Curl::doCurlRequest($url, $params); 
  202. return json_decode($curlRes, true); 
  203.  
  204. /** 
  205. * This method allows Merchant to host payment form on his website and perform sale without any client redirection 
  206. * to tpay.com system. This approach requires special security considerations. 
  207. * The client will be redirected if his card has 3d secure. 
  208. * We support secure communication by encrypting card data (card number, validity date and cvv/cvs number) 
  209. * on client side (javascript) with Merchant's public RSA key and send it as one parameter (card) to our API gate. 
  210. * A valid SSL certificate on domain is required 
  211. * @param string $clientName client name 
  212. * @param string $clientEmail client email 
  213. * @param string $saleDescription sale description 
  214. * @param float $amount amount 
  215. * @param string $carddata encrypted credit card data 
  216. * @param string $curr currency 
  217. * @param string|null $orderID order id 
  218. * @param bool $onetimer 
  219. * @param string $lang 
  220. * @return bool|mixed 
  221. * @throws TException 
  222. */ 
  223. public function secureSale( 
  224. $clientName,  
  225. $clientEmail,  
  226. $saleDescription,  
  227. $amount,  
  228. $carddata,  
  229. $curr = '985',  
  230. $orderID = null,  
  231. $onetimer = true,  
  232. $lang = 'pl',  
  233. $enablePowUrl = true,  
  234. $powUrl = '',  
  235. $powUrlBlad = '' 
  236. if (!is_string($carddata) || strlen($carddata) === 0) { 
  237. throw new TException('Card data are not set'); 
  238.  
  239. return $this->registerSaleBase( 
  240. $clientName,  
  241. $clientEmail,  
  242. $saleDescription,  
  243. $amount,  
  244. $curr,  
  245. $orderID,  
  246. $onetimer,  
  247. false,  
  248. $carddata,  
  249. $lang,  
  250. $enablePowUrl,  
  251. $powUrl,  
  252. $powUrlBlad 
  253. ); 
  254.  
  255. /** 
  256. * This method allows Merchant to host payment form on his website and perform sale without any client redirection 
  257. * to tpay.com system. This approach requires special security considerations. 
  258. * We support secure communication by encrypting card data (card number, validity date and cvv/cvs number) 
  259. * on client side (javascript) with Merchant's public RSA key and send it as one parameter (card) to our API gate. 
  260. * A valid SSL certificate on domain is required 
  261. * @param string $clientName client name 
  262. * @param string $clientEmail client email 
  263. * @param string $saleDescription sale description 
  264. * @param float $amount amount 
  265. * @param string $carddata encrypted credit card data 
  266. * @param string $curr currency 
  267. * @param string|null $orderID order id 
  268. * @param bool $onetimer 
  269. * @return bool|mixed 
  270. * @throws TException 
  271. */ 
  272. public function directSale( 
  273. $clientName,  
  274. $clientEmail,  
  275. $saleDescription,  
  276. $amount,  
  277. $carddata,  
  278. $curr = '985',  
  279. $orderID = null,  
  280. $onetimer = true 
  281.  
  282.  
  283. if (!is_string($carddata) || strlen($carddata) === 0) { 
  284. throw new TException('Card data are not set'); 
  285.  
  286. return $this->registerSaleBase( 
  287. $clientName,  
  288. $clientEmail,  
  289. $saleDescription,  
  290. $amount,  
  291. $curr,  
  292. $orderID,  
  293. $onetimer,  
  294. true,  
  295. $carddata 
  296.  
  297. ); 
  298.  
  299. /** 
  300. * Method used to create new sale for payment on demand. 
  301. * It can be called after receiving notification with cli_auth (see communication schema in register_sale method). 
  302. * It cannot be used if onetimer option was sent in register_sale or client has unregistered 
  303. * (by link in email or by API). 
  304. * @param string $clientAuthCode client auth code 
  305. * @param string $saleDescription sale description 
  306. * @param float $amount amount 
  307. * @param string $currency currency 
  308. * @param null $orderID order id 
  309. * @param string $lang language 
  310. * @return bool|mixed 
  311. * @throws TException 
  312. */ 
  313. public function presale($clientAuthCode, $saleDescription, $amount, $currency = '985',  
  314. $orderID = null, $lang = 'pl') 
  315.  
  316. $params = $this->saleValidateAndPrepareParams($clientAuthCode, $saleDescription, $amount,  
  317. $currency, $orderID, $lang, static::PRESALE); 
  318.  
  319. Util::log('Presale params', print_r($params, true) . ' hash alg ' . $this->hashAlg); 
  320.  
  321. $amount = number_format($amount, 2, '.', ''); 
  322.  
  323. $params[static::SIGN] = hash($this->hashAlg, static::PRESALE . $clientAuthCode . $saleDescription . 
  324. $amount . $currency . $orderID . $lang . $this->verificationCode); 
  325. $params[static::APIPASS] = $this->apiPass; 
  326.  
  327. Util::log('Pre sale params with hash ', print_r($params, true) . 'req url ' . $this->apiURL . $this->apiKey); 
  328.  
  329. return $this->postRequest($this->apiURL . $this->apiKey, $params); 
  330.  
  331. /** 
  332. * Validate all transaction parameters and throw TException if any error occurs 
  333. * Add required fields sign and api password to config 
  334. * @param string $clientAuthCode client auth code 
  335. * @param string $saleDescription sale description 
  336. * @param float $amount amount 
  337. * @param string $currency currency 
  338. * @param string|null $orderID order id 
  339. * @param string $lang language 
  340. * @param string $method sale method 
  341. * @param array $errors validation errors 
  342. * @return array parameters for sale request 
  343. * @throws TException 
  344. */ 
  345. private function saleValidateAndPrepareParams($clientAuthCode, $saleDescription,  
  346. $amount, $currency, $orderID, $lang, $method, $errors = array()) 
  347.  
  348. if (!is_string($clientAuthCode) || strlen($clientAuthCode) === 0) { 
  349. $errors[] = static::EMPTYCODE; 
  350. } else { 
  351. if (strlen($clientAuthCode) !== 40) { 
  352. $errors[] = static::INVALIDCODE; 
  353.  
  354. if (!is_string($saleDescription) || strlen($saleDescription) === 0) { 
  355. $errors[] = 'Sale description is empty.'; 
  356. } else { 
  357. if (strlen($saleDescription) > 128) { 
  358. $errors[] = 'Sale description is too long. Max 128 characters.'; 
  359.  
  360. if (!is_double($amount) && !is_float($amount) && !is_int($amount) && $amount <= 0) { 
  361. $errors[] = 'Amount is invalid.'; 
  362.  
  363. if (!is_int($currency) && strlen($currency) != 3) { 
  364. $errors[] = 'XCurrency is invalid.'; 
  365.  
  366. if (count($errors) > 0) { 
  367. throw new TException(sprintf('%s', implode(' ', $errors))); 
  368.  
  369. $amount = number_format(str_replace(array(', ', ' '), array('.', ''), $amount), 2, '.', ''); 
  370.  
  371. $params = array( 
  372. static::METHOD => $method,  
  373. static::CLIAUTH => $clientAuthCode,  
  374. static::DESC => $saleDescription,  
  375. static::AMOUNT => $amount,  
  376. ); 
  377.  
  378. if ($currency) { 
  379. $params[static::CURRENCY] = $currency; 
  380. if ($orderID) { 
  381. $params['order_id'] = $orderID; 
  382. if ($lang) { 
  383. $params[static::LANGUAGE] = $lang; 
  384.  
  385. $params[static::SIGN] = hash($this->hashAlg, implode('', $params) . $this->verificationCode); 
  386. $params[static::APIPASS] = $this->apiPass; 
  387.  
  388. return $params; 
  389.  
  390. /** 
  391. * Make sale by client auth code 
  392. * @param string $clientAuthCode client auth code 
  393. * @param string $saleDescription sale description 
  394. * @param float $amount amount 
  395. * @param string $currency currency 
  396. * @param string|null $orderID order id 
  397. * @param string $lang language 
  398. * @return bool|mixed 
  399. * @throws TException 
  400. */ 
  401. public function completeSale( 
  402. $clientAuthCode,  
  403. $saleDescription,  
  404. $amount,  
  405. $currency = '985',  
  406. $orderID = null,  
  407. $lang = 'pl' 
  408.  
  409. $params = $this->saleValidateAndPrepareParams($clientAuthCode, $saleDescription,  
  410. $amount, $currency, $orderID, $lang, static::PRESALE); 
  411. $response = $this->postRequest($this->apiURL . $this->apiKey, $params); 
  412.  
  413. if ($response['result']) { 
  414. $saleAuthCode = $response[static::SALEAUTH]; 
  415. return $this->sale($clientAuthCode, $saleAuthCode); 
  416.  
  417.  
  418. return $response; 
  419.  
  420. /** 
  421. * Method used to execute created sale with presale method. Sale defined with sale_auth can be executed only once. 
  422. * If the method is called second time with the same parameters, system returns sale actual status - in parameter 
  423. * status - done for correct payment and declined for rejected payment. 
  424. * In that case, client card is not charged the second time. 
  425. * @param string $clientAuthCode client auth code 
  426. * @param string $saleAuthCode sale auth code 
  427. * @return bool|mixed 
  428. */ 
  429. public function sale($clientAuthCode, $saleAuthCode) 
  430. if (strlen($clientAuthCode) != 40) { 
  431. return false; 
  432. if (strlen($saleAuthCode) != 40) { 
  433. return false; 
  434.  
  435. $params = array( 
  436. static::METHOD => static::SALE,  
  437. static::CLIAUTH => $clientAuthCode,  
  438. static::SALEAUTH => $saleAuthCode,  
  439. ); 
  440. $params[static::SIGN] = hash($this->hashAlg, static::SALE . 
  441. $clientAuthCode . $saleAuthCode . $this->verificationCode); 
  442. $params[static::APIPASS] = $this->apiPass; 
  443.  
  444. return $this->postRequest($this->apiURL . $this->apiKey, $params); 
  445.  
  446. /** 
  447. * Method used to transfer money back to the client. 
  448. * The refund can reference to chosen sale (sale_auth) or directly to client (cli_auth). 
  449. * In both cases amount is adjustable in parameter amount. 
  450. * If only cli_auth is sent amount parameter is required,  
  451. * if sale_auth is passed amount and currency is not necessary - 
  452. * system will take default values from the specified sale. With sale_auth refund can be made only once 
  453. * @param string $clientAuthCode client auth code 
  454. * @param string|bool $saleAuthCode sale auth code 
  455. * @param string $refundDesc refund description 
  456. * @param float|null $amount amount 
  457. * @param string $currency currency 
  458. * @param string $lang 
  459. * @return bool|mixed 
  460. * @throws TException 
  461. */ 
  462. public function refund($clientAuthCode, $saleAuthCode, $refundDesc, $amount = null, $currency = '985', $lang = 'pl') 
  463. $errors = array(); 
  464. /** 
  465. * required clientAuthCode or sale_auth, refund_desc and amount if only clientAuthCode passed 
  466. */ 
  467. if (!is_string($clientAuthCode) || strlen($clientAuthCode) === 0) { 
  468. $errors[] = static::EMPTYCODE; 
  469. } else { 
  470. if (strlen($clientAuthCode) !== 40) { 
  471. $errors[] = static::INVALIDCODE; 
  472.  
  473. if (!is_string($saleAuthCode) || strlen($saleAuthCode) === 0) { 
  474. $errors[] = 'Sale auth code is empty.'; 
  475. } else { 
  476. if (strlen($saleAuthCode) !== 40) { 
  477. $errors[] = 'Sale auth code is invalid.'; 
  478.  
  479. if (!is_string($refundDesc) || strlen($refundDesc) === 0) { 
  480. $errors[] = 'Refund desc is empty.'; 
  481. } else { 
  482. if (strlen($refundDesc) > 128) { 
  483. $errors[] = 'Refund desc is too long. Max 128 characters.'; 
  484.  
  485. if ($amount != null) { 
  486. $amount = number_format(str_replace(array(', ', ' '), array('.', ''), $amount), 2, '.', ''); 
  487.  
  488. } else { 
  489. if ($clientAuthCode && !$saleAuthCode) { 
  490. $errors[] = 'Sale auth is false.'; 
  491.  
  492. if (!isset($clientAuthCode) && !isset($saleAuthCode)) { 
  493. $errors[] = 'Cli auth is not set and sale auth is not set.'; 
  494.  
  495. if (!is_int($currency) && strlen($currency) != 3) { 
  496. $errors[] = 'Currency is invalid.'; 
  497.  
  498. if (count($errors) > 0) { 
  499. throw new TException(sprintf('%s', implode(' ', $errors))); 
  500.  
  501. $params[static::METHOD] = 'refund'; 
  502. $params[static::DESC] = $refundDesc; 
  503.  
  504. if ($clientAuthCode) { 
  505. $params[static::CLIAUTH] = $clientAuthCode; 
  506. if ($saleAuthCode) { 
  507. $params[static::SALEAUTH] = $saleAuthCode; 
  508. if ($amount) { 
  509. $params[static::AMOUNT] = $amount; 
  510. if ($currency) { 
  511. $params[static::CURRENCY] = $currency; 
  512. if ($lang) { 
  513. $params[static::LANGUAGE] = $lang; 
  514.  
  515.  
  516. $params[static::SIGN] = hash($this->hashAlg, implode('', $params) . $this->verificationCode); 
  517. $params[static::APIPASS] = $this->apiPass; 
  518.  
  519. return $this->postRequest($this->apiURL . $this->apiKey, $params); 
  520.  
  521. /** 
  522. * Method used to deregister client card data from system. 
  523. * Client can also do it himself from link in email after payment - if onetimer was not set - in that case system 
  524. * will sent notification. After successful deregistration Merchant can no more charge client's card 
  525. * @param string $clientAuthCode client auth code 
  526. * @return bool|mixed 
  527. * @throws TException 
  528. */ 
  529. public function deregisterClient($clientAuthCode) 
  530. $errors = array(); 
  531.  
  532. if (!is_string($clientAuthCode) || strlen($clientAuthCode) === 0) { 
  533. $errors[] = static::EMPTYCODE; 
  534. } else { 
  535. if (strlen($clientAuthCode) !== 40) { 
  536. $errors[] = static::INVALIDCODE; 
  537.  
  538. if (count($errors) > 0) { 
  539. throw new TException(sprintf('%s', implode(' ', $errors))); 
  540.  
  541. $params[static::METHOD] = 'deregister'; 
  542. $params[static::CLIAUTH] = $clientAuthCode; 
  543.  
  544. $params[static::SIGN] = hash($this->hashAlg, implode('', $params) . $this->verificationCode); 
  545. $params[static::APIPASS] = $this->apiPass; 
  546.  
  547. return $this->postRequest($this->apiURL . $this->apiKey, $params); 
  548.  
  549. private function checkReturnUrls($powUrl = '', $powUrlBlad = '') 
  550. $params = array(); 
  551. if (filter_var($powUrl, FILTER_VALIDATE_URL)) { 
  552. $params['pow_url'] = $powUrl; 
  553. if (filter_var($powUrlBlad, FILTER_VALIDATE_URL)) { 
  554. $params['pow_url_blad'] = $powUrlBlad; 
  555. return $params;