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.
335 lines
9.7 KiB
335 lines
9.7 KiB
<?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');
|
|
}
|
|
}
|
|
}
|
|
|