Initial import
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace app\services\payment;
|
||||
|
||||
use app\models\Order;
|
||||
use app\models\OrderPayment;
|
||||
use app\services\payment\providers\epay\EPay;
|
||||
|
||||
|
||||
class Payment
|
||||
{
|
||||
public static function getCheckOut(Order $order, $payment_method)
|
||||
{
|
||||
|
||||
$payment = new OrderPayment();
|
||||
$payment->order_id = $order->id;
|
||||
$payment->payment_method = $payment_method;
|
||||
$payment->amount = $order->total_price;
|
||||
if ($order->user)
|
||||
$payment->client_email = $order->user->email;
|
||||
$payment->save();
|
||||
|
||||
switch ($payment->payment_method) {
|
||||
case 'epay':
|
||||
case 'card':
|
||||
$directCard = $payment_method == 'card' ? true : false;
|
||||
/** [ 3 February 2023 10:59 ] TodoR: Nasl
|
||||
* [ 3 February 2023 11:00 ] TodoR: Naslk
|
||||
* [ 3 February 2023 11:00 ] TodoR: 123456
|
||||
*/
|
||||
$epay = new EPay();
|
||||
$epay->setData(EPay::API_MODE_LIVE, 'https://demo.epay.bg/', 'https://www.epay.bg/', $payment->client_email,
|
||||
[
|
||||
// DEMO DATA
|
||||
'client_secret' => 'C6OCA0SZ8LYJN5E3UOE6PJD0ELMW9JL9BRNHEO1TI6M54H9K7JI69H4YZELASABA',
|
||||
'client_identifier' => 'D727935809'
|
||||
],
|
||||
[
|
||||
//REAL DATA
|
||||
'client_secret' => 'HPLP2D7MA15NGXR5ZL85Y05P90VGW6S3XB6XBV2Q3UQ3V2HDIZB3Q6EYL0XFHNDD',
|
||||
'client_identifier' => '1921938405'
|
||||
]);
|
||||
$epay->prepareEPayPaymentFormFields($epay->getEpayPaymentDetails($payment), $directCard);
|
||||
$epay->postSubmit();
|
||||
break;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function setPaymentNotification()
|
||||
{
|
||||
if (!empty($_GET['type'])) {
|
||||
switch ($_GET['type']) {
|
||||
case 'epay':
|
||||
$epay = new EPay();
|
||||
$epay->setNotification();
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace app\services\payment\providers\epay;
|
||||
|
||||
use app\models\OrderPayment;
|
||||
use app\models\OrderPaymentNotification;
|
||||
use app\services\JWT;
|
||||
use yii\base\BaseObject;
|
||||
|
||||
class EPay
|
||||
{
|
||||
|
||||
const API_MODE_DEMO = 'demo';
|
||||
const API_MODE_LIVE = 'live';
|
||||
|
||||
|
||||
private $apiMode;
|
||||
private $ePayDemoEnvironmentUrl;
|
||||
private $ePayLiveEnvironmentUrl;
|
||||
private $authenticationDemo;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $authenticationLive;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $postFields = [];
|
||||
|
||||
/**
|
||||
* EPayHelper set method.
|
||||
* @param string $apiMode
|
||||
* @param string $ePayDemoEnvironmentUrl
|
||||
* @param string $ePayLiveEnvironmentUrl
|
||||
* @param string $apiClientEmail
|
||||
* @param array $authenticationDemo
|
||||
* @param array $authenticationLive
|
||||
*/
|
||||
public function setData($apiMode, $ePayDemoEnvironmentUrl, $ePayLiveEnvironmentUrl, $apiClientEmail, array $authenticationDemo, array $authenticationLive)
|
||||
{
|
||||
$this->apiMode = $apiMode;
|
||||
$this->ePayDemoEnvironmentUrl = $ePayDemoEnvironmentUrl;
|
||||
$this->ePayLiveEnvironmentUrl = $ePayLiveEnvironmentUrl;
|
||||
$this->apiClientEmail = $apiClientEmail;
|
||||
$this->authenticationDemo = $authenticationDemo;
|
||||
$this->authenticationLive = $authenticationLive;
|
||||
}
|
||||
|
||||
public function getEPayUrl()
|
||||
{
|
||||
if ($this->apiMode == self::API_MODE_DEMO) {
|
||||
return $this->ePayDemoEnvironmentUrl;
|
||||
} else {
|
||||
return $this->ePayLiveEnvironmentUrl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EPayPayment $ePayPayment
|
||||
* @param bool $directCard
|
||||
* @param array $order
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function prepareEPayPaymentFormFields($ePayPayment, $directCard = false)
|
||||
{
|
||||
$now = new \DateTime("+20 min");
|
||||
|
||||
$dataFields = [];
|
||||
$postFields = [];
|
||||
|
||||
$dataFields['MIN'] = $this->getApiClientId();
|
||||
$dataFields['INVOICE'] = (string)$ePayPayment->getInvoiceNumber();
|
||||
|
||||
$amount = (float)$ePayPayment->getAmount();
|
||||
$paymentAmount = $amount;
|
||||
$dataFields['AMOUNT'] = number_format($paymentAmount, 2);
|
||||
$dataFields['CURRENCY'] = 'BGN';
|
||||
$dataFields['EXP_TIME'] = $now->format('d.m.Y H:i:s');
|
||||
$dataFields['DESCR'] = $ePayPayment->getDescription();
|
||||
$dataFields['ENCODING'] = 'utf-8';
|
||||
$dataFields['ORDERID'] = $ePayPayment->getOrderId();
|
||||
|
||||
$data = $this->getDataFieldsAsString($dataFields);
|
||||
$encodedData = base64_encode($data);
|
||||
//$checksum = $this->getHash($encodedData);
|
||||
$checksum = $this->generateChecksum($encodedData);
|
||||
|
||||
if (!$directCard) {
|
||||
$postFields['PAGE'] = 'paylogin';
|
||||
} else {
|
||||
$postFields['PAGE'] = 'credit_paydirect';
|
||||
}
|
||||
if ($directCard) {
|
||||
$postFields['LANG'] = 'bg';
|
||||
}
|
||||
//echo $data;
|
||||
//exit;
|
||||
$postFields['ENCODED'] = $encodedData;
|
||||
$postFields['CHECKSUM'] = $checksum;
|
||||
$postFields['URL_OK'] = $ePayPayment->getUrlOk();
|
||||
$postFields['URL_CANCEL'] = $ePayPayment->getUrlCancel();
|
||||
|
||||
//echo json_encode($dataFields);
|
||||
//exit;
|
||||
|
||||
$this->postFields = $postFields;
|
||||
}
|
||||
|
||||
public function postSubmit()
|
||||
{
|
||||
//echo json_encode($this->postFields);
|
||||
//exit;
|
||||
if (sizeof($this->postFields) > 0) {
|
||||
$form = '<html><body onload="document.forms[\'ePay\'].submit()">';
|
||||
$form .= '<form action="' . $this->getEPayUrl() . '" name="ePay" method="post">';
|
||||
foreach ($this->postFields as $key => $value) {
|
||||
$form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
|
||||
}
|
||||
$form .= '</form>';
|
||||
$form .= '</body></html>';
|
||||
echo $form;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dataFields
|
||||
* @return string
|
||||
*/
|
||||
private function getEncodedDataFieldsAsString($dataFields)
|
||||
{
|
||||
return JWT::encode($dataFields, JWT::SECRET_KEY);
|
||||
}
|
||||
|
||||
private function getDataFieldsAsString($dataFields)
|
||||
{
|
||||
$data = '';
|
||||
foreach ($dataFields as $key => $value) {
|
||||
$data .= "$key=$value" . PHP_EOL;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
private function generateChecksum($data)
|
||||
{
|
||||
$algorithm = 'sha1';
|
||||
$password = $this->getApiClientSecret();
|
||||
|
||||
$p = ['md5' => 'H32', 'sha1' => 'H40'];
|
||||
if (strlen($password) > 64) {
|
||||
$password = pack($p[$algorithm], $algorithm($password));
|
||||
}
|
||||
if (strlen($password) < 64) {
|
||||
$password = str_pad($password, 64, chr(0));
|
||||
}
|
||||
|
||||
$iPad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64);
|
||||
$oPad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64);
|
||||
|
||||
return ($algorithm($oPad . pack($p[$algorithm], $algorithm($iPad . $data))));
|
||||
}
|
||||
|
||||
private function getHash($data)
|
||||
{
|
||||
$algorithm = 'sha1';
|
||||
$password = $this->getApiClientSecret();
|
||||
return hash_hmac($algorithm, $data, $password);
|
||||
}
|
||||
|
||||
private function getApiClientSecret()
|
||||
{
|
||||
if ($this->apiMode == self::API_MODE_DEMO) {
|
||||
return $this->authenticationDemo['client_secret'];
|
||||
} else {
|
||||
return $this->authenticationLive['client_secret'];
|
||||
}
|
||||
}
|
||||
|
||||
private function getApiClientId()
|
||||
{
|
||||
if ($this->apiMode == self::API_MODE_DEMO) {
|
||||
return $this->authenticationDemo['client_identifier'];
|
||||
} else {
|
||||
return $this->authenticationLive['client_identifier'];
|
||||
}
|
||||
}
|
||||
|
||||
public function getOrder($encoded)
|
||||
{
|
||||
$decodeArray = explode(':', base64_decode($encoded));
|
||||
$responseData = [];
|
||||
foreach ($decodeArray as $keyValueStr) {
|
||||
$keyValueArray = explode('=', $keyValueStr);
|
||||
if (sizeof($keyValueArray) == 2)
|
||||
$responseData[$keyValueArray[0]] = $keyValueArray[1];
|
||||
}
|
||||
if (isset($responseData['INVOICE']) && isset($responseData['STATUS'])) {
|
||||
return $responseData;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getEpayPaymentDetails(OrderPayment $orderPayment)
|
||||
{
|
||||
$epayPayment = new EPayPayment();
|
||||
$epayPayment->setEpayPayment($orderPayment);
|
||||
return $epayPayment;
|
||||
}
|
||||
|
||||
public function setNotification()
|
||||
{
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if (!empty($_POST['encoded'])) {
|
||||
$paymentNotification = new OrderPaymentNotification();
|
||||
$paymentNotification->message = base64_decode($_POST['encoded']);
|
||||
$paymentNotification->date = date('Y-m-d H:i:s');
|
||||
$paymentNotification->save();
|
||||
$responseData = $this->encodedOrder($_POST['encoded']);
|
||||
if($responseData) {
|
||||
$response_message = 'INVOICE=' . $responseData['INVOICE'] . ':STATUS=OK';
|
||||
$order_payment = OrderPayment::find()->where(['order_id' => (int)$responseData['INVOICE']])->one();
|
||||
$order_payment->status = $responseData['STATUS'];
|
||||
$order_payment->response_message = $response_message;
|
||||
$order_payment->response_time = date('Y-m-d H:i:s');
|
||||
$order_payment->save();
|
||||
echo $response_message;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
public function encodedOrder($encoded)
|
||||
{
|
||||
$decodeArray = explode(':', base64_decode($encoded));
|
||||
$responseData = [];
|
||||
foreach ($decodeArray as $keyValueStr) {
|
||||
$keyValueArray = explode('=', $keyValueStr);
|
||||
if (sizeof($keyValueArray) == 2)
|
||||
$responseData[$keyValueArray[0]] = $keyValueArray[1];
|
||||
}
|
||||
if (isset($responseData['INVOICE']) && isset($responseData['STATUS'])) {
|
||||
return $responseData;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace app\services\payment\providers\epay;
|
||||
|
||||
use app\models\OrderPayment;
|
||||
|
||||
class EPayPayment
|
||||
{
|
||||
|
||||
/**
|
||||
* This is int.
|
||||
* Cast it to string when sending data to EPay!
|
||||
* @var int
|
||||
*/
|
||||
private $invoiceNumber;
|
||||
|
||||
|
||||
private $orderId;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $amount;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $encoding = 'utf-8';
|
||||
|
||||
/**
|
||||
* URL where the client should be redirected
|
||||
* when payment is processed successfully.
|
||||
* @var string
|
||||
*/
|
||||
private $urlOk;
|
||||
|
||||
/**
|
||||
* URL where the client should be redirected
|
||||
* in case they rejected payment.
|
||||
* @var string
|
||||
*/
|
||||
private $urlCancel;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getInvoiceNumber()
|
||||
{
|
||||
return $this->invoiceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $invoiceNumber
|
||||
*/
|
||||
public function setInvoiceNumber($invoiceNumber)
|
||||
{
|
||||
$this->invoiceNumber = $invoiceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getAmount()
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $amount
|
||||
*/
|
||||
public function setAmount($amount)
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrency()
|
||||
{
|
||||
return $this->currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $currency
|
||||
*/
|
||||
public function setCurrency($currency)
|
||||
{
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEncoding()
|
||||
{
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encoding
|
||||
*/
|
||||
public function setEncoding($encoding)
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUrlOk()
|
||||
{
|
||||
return $this->urlOk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $urlOk
|
||||
*/
|
||||
public function setUrlOk($urlOk)
|
||||
{
|
||||
$this->urlOk = $urlOk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUrlCancel()
|
||||
{
|
||||
return $this->urlCancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $urlCancel
|
||||
*/
|
||||
public function setUrlCancel($urlCancel)
|
||||
{
|
||||
$this->urlCancel = $urlCancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOrderId()
|
||||
{
|
||||
return $this->orderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $orderId
|
||||
*/
|
||||
public function setOrderId($orderId)
|
||||
{
|
||||
$this->orderId = $orderId;
|
||||
}
|
||||
|
||||
public function setEpayPayment(OrderPayment $orderPayment) {
|
||||
$this->setAmount($orderPayment->amount);
|
||||
$isMobile = !empty($_GET['webview_mode']) ? '?webview_mode=1' : '';
|
||||
$this->setUrlOk(\Yii::$app->params['portal'].'/'.\Yii::$app->language.'/user/finalize-order/'.$isMobile);
|
||||
$this->setUrlCancel(\Yii::$app->params['portal'].'/'.\Yii::$app->language.'/user/finalize-order-cancel/'. $isMobile);
|
||||
$this->setOrderId($orderPayment->order->id);
|
||||
$this->setEncoding('utf-8');
|
||||
$this->setCurrency('BGN');
|
||||
$this->setDescription($orderPayment->order->getDescription());
|
||||
$this->setInvoiceNumber($orderPayment->order_id);
|
||||
$this->setOrderId($orderPayment->order_id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user