*/ class LiqPay { 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 $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->_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($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 )); $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() { return $this->_server_response_code; } /** * cnb_form * * @param array $params * * @return string * * @throws InvalidArgumentException */ public function cnb_form($params) { $language = 'en'; 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('
', $this->_checkout_url, sprintf('', 'data', $data), sprintf('', 'signature', $signature), $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 */ private 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 ($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($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 LiqPayController extends Controller { public function payment(Request $request) { try{ $tran = Str::random(6) . '-' . rand(1, 1000); $order = Order::with(['details'])->where(['id' => $request->order_id, 'user_id'=>$request->customer_id])->first(); $config = Helpers::get_business_settings('liqpay'); $public_key = $config['public_key']; $private_key = $config['private_key']; $liqpay = new LiqPay($public_key, $private_key); $html = $liqpay->cnb_form(array( 'action' => 'pay', 'amount' => round($order->order_amount, 2), 'currency' => Helpers::currency_code(), //USD 'description' => 'Transaction ID: ' . $tran, 'order_id' => $order->id, 'result_url' => route('liqpay-callback',['order_id'=>$order->id]), 'server_url' => route('liqpay-callback',['order_id'=>$order->id]), 'version' => '3' )); return $html; }catch(\Exception $ex){ Toastr::error(translate('messages.config_your_account',['method'=>translate('messages.liqpay')])); return back(); } } public function callback(Request $request,$order_id) { $order = Order::with(['details'])->where(['id' => $order_id])->first(); $request['order_id'] = $order_id; if ($request['status'] == 'success') { // $order->transaction_reference = $request->trxID; $order->payment_method = 'LiqPay'; $order->payment_status = 'paid'; $order->order_status = 'confirmed'; $order->confirmed = now(); $order->save(); Helpers::send_order_notification($order); if ($order->callback != null) { return redirect($order->callback . '&status=success'); }else{ return \redirect()->route('payment-success'); } } $order->order_status = 'failed'; $order->failed = now(); $order->save(); if ($order->callback != null) { return redirect($order->callback . '&status=fail'); }else{ return \redirect()->route('payment-fail'); } } }