123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- <?php
- /**
- * Liqpay Payment Module
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- *
- * @category LiqPay
- * @package liqpay/liqpay
- * @version 3.0
- * @author Liqpay
- * @copyright Copyright (c) 2014 Liqpay
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- *
- * EXTENSION INFORMATION
- *
- * LIQPAY API https://www.liqpay.ua/documentation/en
- *
- */
- /**
- * Payment method liqpay process
- *
- * @author Liqpay <support@liqpay.ua>
- */
- // tests/Unit/LiqPayTest.php
- class LiqPay
- {
- private $_api_url = 'https://www.liqpay.ua/api/';
- private $_checkout_url = 'https://www.liqpay.ua/api/3/checkout';
- protected $_supportedCurrencies = array(
- 'EUR', 'USD', 'UAH');
- protected $_supportedLangs = ['uk', 'ru', 'en'];
- private $_public_key;
- private $_private_key;
- private $_server_response_code = null;
- protected $_button_translations = array(
- 'ru' => 'Оплатить',
- 'uk' => 'Сплатити',
- 'en' => 'Pay'
- );
- protected $_actions = array(
- "pay", "hold", "subscribe", "paydonate"
- );
- public CurlRequester $curlRequester;
- /**
- * Constructor.
- *
- * @param string $public_key
- * @param string $private_key
- * @param string $api_url (optional)
- *
- * @throws InvalidArgumentException
- */
- public function __construct($public_key, $private_key, $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->curlRequester = new CurlRequester();
- $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 array|null
- */
- public function api($path, $params = array(), $timeout = 5)
- {
- 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
- ));
- $server_output = $this->curlRequester->make_curl_request($url, $postfields);
- return json_decode($server_output);
- }
- /**
- * Return last api response http code
- *
- * @return string|null
- */
- public function get_response_code()
- {
- return $this->_server_response_code;
- }
- /**
- * cnb_form
- *
- * @param array $params
- *
- * @return string
- *
- * @throws InvalidArgumentException
- */
- public function cnb_form($params)
- {
- $language = 'uk';
- if (isset($params['language']) && in_array($params['language'], $this->_supportedLangs)) {
- $language = $params['language'];
- }
- $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
- <script type="text/javascript" src="https://static.liqpay.ua/libjs/sdk_button.js"></script>
- <sdk-button label="%s" background="#77CC5D" onClick="submit()"></sdk-button>
- </form>
- ',
- $this->_checkout_url,
- sprintf('<input type="hidden" name="%s" value="%s" />', 'data', $data),
- sprintf('<input type="hidden" name="%s" value="%s" />', 'signature', $signature),
- $this->_button_translations[$language]
- );
- }
- /**
- * cnb_form raw data for custom form
- *
- * @param $params
- * @return array
- */
- public function cnb_form_raw($params)
- {
- $params = $this->cnb_params($params);
- return array(
- 'url' => $this->_checkout_url,
- 'data' => $this->encode_params($params),
- 'signature' => $this->cnb_signature($params)
- );
- }
- /**
- * cnb_signature
- *
- * @param array $params
- *
- * @return string
- */
- public function cnb_signature($params)
- {
- $params = $this->cnb_params($params);
- $private_key = $this->_private_key;
- $json = $this->encode_params($params);
- $signature = $this->str_to_sign($private_key . $json . $private_key);
- return $signature;
- }
- /**
- * cnb_params
- *
- * @param array $params
- *
- * @return array $params
- */
- protected function cnb_params($params)
- {
- $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 (!isset($params['action'])) {
- throw new InvalidArgumentException('action is null');
- }
- if (!in_array($params['action'], $this->_actions)) {
- throw new InvalidArgumentException('action is not supported');
- }
- if (!isset($params['order_id'])) {
- throw new InvalidArgumentException('order_id is null');
- }
- if (!isset($params['description'])) {
- throw new InvalidArgumentException('description is null');
- }
- return $params;
- }
- /**
- * encode_params
- *
- * @param array $params
- * @return string
- */
- protected function encode_params($params)
- {
- return base64_encode(json_encode($params));
- }
- /**
- * decode_params
- *
- * @param string $params
- * @return array
- */
- public function decode_params($params)
- {
- return json_decode(base64_decode($params), true);
- }
- /**
- * str_to_sign
- *
- * @param string $str
- *
- * @return string
- */
- public function str_to_sign($str)
- {
- $signature = base64_encode(sha1($str, 1));
- return $signature;
- }
- }
- class CurlRequester
- {
- /**
- * make_curl_request
- * @param $url string
- * @param $postfields string
- * @param int $timeout
- * @return bool|string
- */
- public function make_curl_request($url, $postfields, $timeout = 5) {
- $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 $server_output;
- }
- }
|