관리-도구
편집 파일: LiqPayData.php
<?php namespace App\Library; use InvalidArgumentException; use stdClass; class LiqPayData { const CURRENCY_EUR = 'EUR'; const CURRENCY_USD = 'USD'; const CURRENCY_UAH = 'UAH'; const CURRENCY_RUB = 'RUB'; const CURRENCY_RUR = 'RUR'; private $_api_url = 'https://www.liqpay.ua/api/'; private $_checkout_url = 'https://www.liqpay.ua/api/3/checkout'; protected $_supportedCurrencies = array( self::CURRENCY_EUR, self::CURRENCY_USD, self::CURRENCY_UAH, self::CURRENCY_RUB, self::CURRENCY_RUR, ); private $_public_key; private $_private_key; private $_server_response_code = null; /** * Constructor. * * @param string $public_key * @param string $private_key * @param string|null $api_url (optional) * * @throws InvalidArgumentException */ public function __construct(string $public_key, string $private_key, string $api_url = null) { if (empty($public_key)) { throw new InvalidArgumentException('public_key is empty'); } if (empty($private_key)) { throw new InvalidArgumentException('private_key is empty'); } $this->_public_key = $public_key; $this->_private_key = $private_key; if (null !== $api_url) { $this->_api_url = $api_url; } } /** * Call API * * @param string $path * @param array $params * @param int $timeout * * @return stdClass */ public function api(string $path, array $params = array(), int $timeout = 5): stdClass { if (!isset($params['version'])) { throw new InvalidArgumentException('version is null'); } $url = $this->_api_url . $path; $public_key = $this->_public_key; $private_key = $this->_private_key; $data = $this->encode_params(array_merge(compact('public_key'), $params)); $signature = $this->str_to_sign($private_key.$data.$private_key); $postfields = http_build_query(array( 'data' => $data, 'signature' => $signature )); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // Avoid MITM vulnerability http://phpsecurity.readthedocs.io/en/latest/Input-Validation.html#validation-of-input-sources curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // Check the existence of a common name and also verify that it matches the hostname provided curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,$timeout); // The number of seconds to wait while trying to connect curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // The maximum number of seconds to allow cURL functions to execute curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $server_output = curl_exec($ch); $this->_server_response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return json_decode($server_output); } /** * Return last api response http code * * @return string|null */ public function get_response_code(): ?string { return $this->_server_response_code; } /** * cnb_form raw data for custom form * * @param $params * @return array */ public function cnb_form_raw($params): array { $params = $this->cnb_params($params); return array( 'url' => $this->_checkout_url, 'data' => $this->encode_params($params), 'signature' => $this->cnb_signature($params) ); } /** * cnb_form * * @param array $params * * @return string * * @throws InvalidArgumentException */ public function cnb_form(array $params): string { $language = 'ru'; if (isset($params['language']) && $params['language'] == 'en') { $language = 'en'; } $params = $this->cnb_params($params); $data = $this->encode_params($params); $signature = $this->cnb_signature($params); return sprintf(' <form method="POST" action="%s" accept-charset="utf-8"> %s %s <input type="image" src="//static.liqpay.ua/buttons/p1%s.radius.png" name="btn_text" alt=""/> </form> ', $this->_checkout_url, sprintf('<input type="hidden" name="%s" value="%s" />', 'data', $data), sprintf('<input type="hidden" name="%s" value="%s" />', 'signature', $signature), $language ); } /** * cnb_signature * * @param array $params * * @return string */ public function cnb_signature(array $params): string { $params = $this->cnb_params($params); $private_key = $this->_private_key; $json = $this->encode_params($params); return $this->str_to_sign($private_key . $json . $private_key); } /** * cnb_params * * @param array $params * * @return array $params */ private function cnb_params(array $params): array { $params['public_key'] = $this->_public_key; if (!isset($params['version'])) { throw new InvalidArgumentException('version is null'); } if (!isset($params['amount'])) { throw new InvalidArgumentException('amount is null'); } if (!isset($params['currency'])) { throw new InvalidArgumentException('currency is null'); } if (!in_array($params['currency'], $this->_supportedCurrencies)) { throw new InvalidArgumentException('currency is not supported'); } if ($params['currency'] == self::CURRENCY_RUR) { $params['currency'] = self::CURRENCY_RUB; } if (!isset($params['description'])) { throw new InvalidArgumentException('description is null'); } return $params; } /** * encode_params * * @param array $params * * @return string */ private function encode_params(array $params): string { return base64_encode(json_encode($params)); } /** * decode_params * * @param string $params * * @return array */ public function decode_params(string $params): array { return json_decode(base64_decode($params), true); } /** * str_to_sign * * @param string $str * * @return string */ public function str_to_sign(string $str): string { return base64_encode(sha1($str, 1)); } }