You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
9.7 KiB

2 years ago
<?php
namespace App\Http\Controllers;
use App\CentralLogics\Helpers;
use App\Models\Order;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use stdClass;
use Symfony\Component\Process\Exception\InvalidArgumentException;
/**
* 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>
*/
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('
<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" />
</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_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');
}
}
}