Files
ExtraNetwork e5c4b6aa13 first commit
2026-05-12 17:04:54 +03:00

645 lines
17 KiB
PHP

<?php
namespace App\Core\Payment\Pos;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use App\Core\Payment\Pos\Exceptions\UnsupportedPaymentModelException;
use App\Core\Payment\Pos\Exceptions\UnsupportedTransactionTypeException;
use App\Core\Payment\Pos\PosHelpersTrait;
use Symfony\Component\HttpFoundation\Request;
/**
* Class EstPos
* @package Mews\Pos
*/
class QPos implements PosInterface
{
use PosHelpersTrait;
/**
* @const string
*/
public const NAME = 'VPos';
/**
* API URL
*
* @var string
*/
public $url;
/**
* 3D Pay Gateway URL
*
* @var string
*/
public $gateway;
/**
* Response Codes
*
* @var array
*/
public $codes = [
'00' => 'approved',
'01' => 'bank_call',
'02' => 'bank_call',
'05' => 'reject',
'09' => 'try_again',
'12' => 'invalid_transaction',
'28' => 'reject',
'51' => 'insufficient_balance',
'54' => 'expired_card',
'57' => 'does_not_allow_card_holder',
'62' => 'restricted_card',
'77' => 'request_rejected',
'99' => 'general_error',
];
/**
* Transaction Types
*
* @var array
*/
public $types = [
'pay' => 'Auth',
'pre' => 'PreAuth',
'post' => 'PostAuth',
];
/**
* Currencies
*
* @var array
*/
public $currencies = [];
/**
* Transaction Type
*
* @var string
*/
public $type;
/**
* API Account
*
* @var array
*/
protected $account = [];
/**
* Order Details
*
* @var array
*/
protected $order = [];
/**
* Credit Card
*
* @var object
*/
protected $card;
/**
* Request
*
* @var Request
*/
protected $request;
/**
* Response Raw Data
*
* @var object
*/
protected $data;
/**
* Processed Response Data
*
* @var mixed
*/
public $response;
/**
* Configuration
*
* @var array
*/
protected $config = [];
/**
* Response Raw Data
*
* @var object
*/
protected $mbrId = 5;
/**
* EstPos constructor.
*
* @param array $config
* @param mixed $account
* @param array $currencies
*/
public function __construct($config, $account, array $currencies)
{
$this->config = $config;
$this->account = $account;
$this->currencies = $currencies;
$this->url = isset($this->config['urls'][$this->account->env]) ?
$this->config['urls'][$this->account->env] :
$this->config['urls']['production'];
$this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ?
$this->config['urls']['gateway'][$this->account->env] :
$this->config['urls']['gateway']['production'];
return $this;
}
/**
* Create Regular Payment XML
*
* @return string
*/
protected function createRegularPaymentXML()
{
$nodes = [
'CC5Request' => [
'Name' => $this->account->username,
'Password' => $this->account->password,
'ClientId' => $this->account->client_id,
'Type' => $this->type,
'IPAddress' => $this->order->ip,
'Email' => $this->order->email,
'OrderId' => $this->order->id,
'UserId' => isset($this->order->user_id) ? $this->order->user_id : null,
'Total' => $this->order->amount,
'Currency' => $this->order->currency,
'Taksit' => $this->order->installment,
'CardType' => isset($this->card->type) ? $this->card->type : null,
'Number' => $this->card->number,
'Expires' => $this->card->month . '/' . $this->card->year,
'Cvv2Val' => $this->card->cvv,
'Mode' => 'P',
'GroupId' => '',
'TransId' => '',
'BillTo' => [
'Name' => $this->order->name ? $this->order->name : null,
]
]
];
return $this->createXML($nodes, 'ISO-8859-9');
}
/**
* Create Regular Payment Post XML
*
* @return string
*/
protected function createRegularPostXML()
{
$nodes = [
'CC5Request' => [
'Name' => $this->account->username,
'Password' => $this->account->password,
'ClientId' => $this->account->client_id,
'Type' => $this->types[$this->order->transaction],
'OrderId' => $this->order->id,
]
];
return $this->createXML($nodes, 'ISO-8859-9');
}
/**
* Create 3D Payment XML
* @return string
*/
protected function create3DPaymentXML()
{
$nodes = [
'CC5Request' => [
'Name' => $this->account->username,
'Password' => $this->account->password,
'ClientId' => $this->account->client_id,
'Type' => $this->type,
'IPAddress' => $this->order->ip,
'Email' => $this->order->email,
'OrderId' => $this->order->id,
'UserId' => isset($this->order->user_id) ? $this->order->user_id : null,
'Total' => $this->order->amount,
'Currency' => $this->order->currency,
'Taksit' => $this->order->installment,
'Number' => $this->request->get('md'),
'Expires' => '',
'Cvv2Val' => '',
'PayerTxnId' => $this->request->get('xid'),
'PayerSecurityLevel' => $this->request->get('eci'),
'PayerAuthenticationCode' => $this->request->get('cavv'),
'CardholderPresentCode' => '13',
'Mode' => 'P',
'GroupId' => '',
'TransId' => '',
]
];
if ($this->order->name) {
$nodes['BillTo'] = [
'Name' => $this->order->name,
];
}
return $this->createXML($nodes, 'ISO-8859-9');
}
/**
* Get ProcReturnCode
*
* @return string|null
*/
protected function getProcReturnCode()
{
return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null;
}
/**
* Get Status Detail Text
*
* @return string|null
*/
protected function getStatusDetail()
{
$proc_return_code = $this->getProcReturnCode();
return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null;
}
/**
* Create 3D Hash
*
* @return string
*/
public function create3DHash()
{
$hash_str = '';
$hash_str = $this->mbrId . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->merchant_pass;
return base64_encode(pack('H*', sha1($hash_str)));
}
/**
* Check 3D Hash
*
* @param array $data
* @return bool
*/
public function check3DHash($data)
{
$return = false;
$responseHash = $data['ResponseHash'];
//MerchantID + MerchantPass + OrderId + AuthCode + ProcReturnCode + 3DStatus + ResponseRnd + UserCode
$generatedHash = $this->account->merchant_id . $this->account->merchant_pass . $data['OrderId'] . $data['AuthCode'] . $data['ProcReturnCode'] . $data['3DStatus'] . $data['ResponseRnd'] . $this->account->user_code;
$generatedHash = base64_encode(pack('H*', sha1($generatedHash)));
if ($generatedHash == $responseHash) {
$return = true;
}
return $return;
}
/**
* Regular Payment
*
* @return $this
* @throws GuzzleException
*/
public function makeRegularPayment()
{
return false;
}
/**
* Make 3D Payment
*
* @return $this
* @throws GuzzleException
*/
public function make3DPayment()
{
return false;
}
/**
* Make 3D Pay Payment
*
* @return $this
*/
public function make3DPayPayment()
{
$this->request = Request::createFromGlobals();
$status = 'declined';
if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') {
if (in_array($this->request->get('3DStatus'), [1])) {
$status = 'approved';
}
}
$transaction_security = 'MPI fallback';
if ($status == 'approved') {
if ($this->request->get('3DStatus') == '1') {
$transaction_security = 'Full 3D Secure';
} elseif (in_array($this->request->get('3DStatus'), [2, 3, 4])) {
$transaction_security = 'Half 3D Secure';
}
}
$this->response = (object)[
'id' => (string)$this->request->get('RequestGuid'),
'trans_id' => (string)$this->request->get('HostRefNum'),
'auth_code' => (string)$this->request->get('AuthCode'),
'host_ref_num' => (string)$this->request->get('HostRefNum'),
//'response' => (string)$this->request->get('Response'),
'order_id' => (string)$this->request->get('OrderId'),
'transaction_type' => $this->type,
'transaction' => $this->order->transaction,
'transaction_security' => $transaction_security,
'code' => (string)$this->request->get('ProcReturnCode'),
'md_status' => $this->request->get('3DStatus'),
'status' => $status,
'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null,
'hash' => (string)$this->request->get('ResponseHash'),
'rand' => (string)$this->request->get('Rnd'),
//'hash_params' => (string)$this->request->get('HASHPARAMS'),
//'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'),
'masked_number' => (string)$this->request->get('CardMask'),
//'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'),
//'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'),
'amount' => (string)$this->request->get('PurchAmount'),
'currency' => (string)$this->request->get('Currency'),
'tx_status' => (string)$this->request->get('TxnStatus'),
'eci' => (string)$this->request->get('Eci'),
'cavv' => (string)$this->request->get('CavvResult'),
//'xid' => (string)$this->request->get('xid'),
//'error_code' => (string)$this->request->get('ErrCode'),
'error_message' => (string)$this->request->get('ErrMsg'),
//'md_error_message' => (string)$this->request->get('mdErrorMsg'),
'name' => (string)$this->request->get('MrcName'),
//'email' => (string)$this->request->get('Email'),
'extra' => $this->request->get('Extra'),
'response_rnd' => $this->request->get('ResponseRnd'),
'all' => $this->request->request->all(),
];
return $this;
}
/**
* Get 3d Form Data
*
* @return array
*/
public function get3DFormData()
{
$data = [];
if ($this->order) {
$this->order->hash = $this->create3DHash();
$inputs = [
'MbrId' => $this->mbrId,
'MerchantID' => $this->account->merchant_id,
'UserCode' => $this->account->user_code,
'UserPass' => $this->account->user_pass,
'SecureType' => $this->account->model == '3d_pay' ? '3DPay' : '3D',
'TxnType' => $this->type,
'InstallmentCount' => $this->order->installment,
'Currency' => $this->order->currency,
'OkUrl' => $this->order->success_url,
'FailUrl' => $this->order->fail_url,
'OrderId' => $this->order->id,
'PurchAmount' => $this->order->amount,
'Lang' => $this->order->lang,
'Rnd' => $this->order->rand,
'Hash' => $this->order->hash,
'Pan' => $this->card->number,
'Cvv2' => $this->card->cvv,
'Expiry' => $this->getCardExpDate(),
];
$data = [
'gateway' => $this->gateway,
'success_url' => $this->order->success_url,
'fail_url' => $this->order->fail_url,
'rand' => $this->order->rand,
'hash' => $this->order->hash,
'inputs' => $inputs,
];
}
return $data;
}
/**
* Send contents to WebService
*
* @param $contents
* @return $this
* @throws GuzzleException
*/
public function send($contents)
{
$client = new Client();
$response = $client->request('POST', $this->url, [
'body' => $contents
]);
$this->data = $this->XMLStringToObject($response->getBody()->getContents());
return $this;
}
/**
* Prepare Order
*
* @param object $order
* @param object null $card
* @return mixed
* @throws UnsupportedTransactionTypeException
*/
public function prepare($order, $card = null)
{
$this->type = $this->types['pay'];
if (isset($order->transaction)) {
if (array_key_exists($order->transaction, $this->types)) {
$this->type = $this->types[$order->transaction];
} else {
throw new UnsupportedTransactionTypeException('Unsupported transaction type!');
}
}
$this->order = $order;
$this->card = $card;
$this->order->installment = $this->order->installment == 0 ? 0 : $this->order->installment;
}
/**
* Make Payment
*
* @param object $card
* @return mixed
* @throws UnsupportedPaymentModelException
* @throws GuzzleException
*/
public function payment($card)
{
$this->card = $card;
$model = 'regular';
if (isset($this->account->model) && $this->account->model) {
$model = $this->account->model;
}
if ($model == 'regular') {
$this->makeRegularPayment();
} elseif ($model == '3d') {
$this->make3DPayment();
} elseif ($model == '3d_pay') {
$this->make3DPayPayment();
} else {
throw new UnsupportedPaymentModelException();
}
return $this;
}
/**
* Refund Order
*
* @param array $meta
* @return $this
* @throws GuzzleException
*/
public function refund(array $meta)
{
return false;
}
/**
* Cancel Order
*
* @param array $meta
* @return $this
* @throws GuzzleException
*/
public function cancel(array $meta)
{
return false;
}
/**
* Order Status
*
* @param array $meta
* @return $this
* @throws GuzzleException
*/
public function status(array $meta)
{
return false;
}
/**
* Order History
*
* @param array $meta
* @return $this
* @throws GuzzleException
*/
public function history(array $meta)
{
return false;
}
/**
* @return array
*/
public function getConfig()
{
return $this->config;
}
/**
* @return mixed
*/
public function getAccount()
{
return $this->account;
}
/**
* @return array
*/
public function getCurrencies()
{
return $this->currencies;
}
/**
* @return mixed
*/
public function getOrder()
{
return $this->order;
}
/**
* @return mixed
*/
public function getCard()
{
return $this->card;
}
/**
* @return string|null
*/
public function getCardCode()
{
$card_type = null;
if (isset($this->card->type)) {
if ($this->card->type == 'visa') {
$card_type = '0';
} elseif ($this->card->type == 'master') {
$card_type = '1';
} elseif ($this->card->type == '1' || $this->card->type == '2') {
$card_type = $this->card->type;
}
}
return $card_type;
}
protected function getCardExpDate()
{
$year = (string)substr($this->card->year, 2, 2);
$month = (string)substr($this->card->month, 0, 2);
return (string)$month . $year;
}
}