Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 105 additions & 144 deletions src/GatewayResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,168 +2,129 @@

namespace Larabookir\Gateway;

use Illuminate\Support\Facades\DB;
use Larabookir\Gateway\Asanpardakht\Asanpardakht;
use Larabookir\Gateway\Exceptions\InvalidRequestException;
use Larabookir\Gateway\Exceptions\NotFoundTransactionException;
use Larabookir\Gateway\Exceptions\PortNotFoundException;
use Larabookir\Gateway\Exceptions\RetryException;
use Larabookir\Gateway\Irankish\Irankish;
use Larabookir\Gateway\Mellat\Mellat;
use Larabookir\Gateway\Parsian\Parsian;
use Larabookir\Gateway\Pasargad\Pasargad;
use Larabookir\Gateway\Payir\Payir;
use Larabookir\Gateway\Paypal\Paypal;
use Larabookir\Gateway\Sadad\Sadad;
use Larabookir\Gateway\Mellat\Mellat;
use Larabookir\Gateway\Pasargad\Pasargad;
use Larabookir\Gateway\Saman\Saman;
use Larabookir\Gateway\Asanpardakht\Asanpardakht;
use Larabookir\Gateway\Shahr\Shahr;
use Larabookir\Gateway\Zarinpal\Zarinpal;
use Larabookir\Gateway\Payir\Payir;
use Larabookir\Gateway\Exceptions\RetryException;
use Larabookir\Gateway\Exceptions\PortNotFoundException;
use Larabookir\Gateway\Exceptions\InvalidRequestException;
use Larabookir\Gateway\Exceptions\NotFoundTransactionException;
use Illuminate\Support\Facades\DB;

class GatewayResolver
{
protected $request;
protected $config;
protected $port;

private const PORT_MAP = [
Mellat::class => Enum::MELLAT,
Parsian::class => Enum::PARSIAN,
Saman::class => Enum::SAMAN,
Zarinpal::class => Enum::ZARINPAL,
Sadad::class => Enum::SADAD,
Asanpardakht::class => Enum::ASANPARDAKHT,
Paypal::class => Enum::PAYPAL,
Payir::class => Enum::PAYIR,
Pasargad::class => Enum::PASARGAD,
Shahr::class => Enum::SHAHR,
Irankish::class => Enum::IRANKISH,
];

public function __construct($config = null, $port = null)
{
$this->config = app('config');
$this->request = app('request');

if ($this->config->has('gateway.timezone')) {
date_default_timezone_set($this->config->get('gateway.timezone'));
}

protected $request;

/**
* @var Config
*/
public $config;

/**
* Keep current port driver
*
* @var Mellat|Saman|Sadad|Zarinpal|Payir|Parsian
*/
protected $port;

/**
* Gateway constructor.
* @param null $config
* @param null $port
*/
public function __construct($config = null, $port = null)
{
$this->config = app('config');
$this->request = app('request');

if ($this->config->has('gateway.timezone'))
date_default_timezone_set($this->config->get('gateway.timezone'));

if (!is_null($port)) $this->make($port);
}

/**
* Get supported ports
*
* @return array
*/
public function getSupportedPorts()
{
return (array) Enum::getIPGs();
}

/**
* Call methods of current driver
*
* @return mixed
*/
public function __call($name, $arguments)
{

// calling by this way ( Gateway::mellat()->.. , Gateway::parsian()->.. )
if(in_array(strtoupper($name),$this->getSupportedPorts())){
return $this->make($name);
}

return call_user_func_array([$this->port, $name], $arguments);
}

/**
* Gets query builder from you transactions table
* @return mixed
*/
function getTable()
{
return DB::table($this->config->get('gateway.table'));
}

/**
* Callback
*
* @return $this->port
*
* @throws InvalidRequestException
* @throws NotFoundTransactionException
* @throws PortNotFoundException
* @throws RetryException
*/
public function verify()
{
if (!$this->request->has('transaction_id') && !$this->request->has('iN'))
throw new InvalidRequestException;
if ($this->request->has('transaction_id')) {
$id = $this->request->get('transaction_id');
}else {
$id = $this->request->get('iN');
}

$transaction = $this->getTable()->whereId($id)->first();

if (!$transaction)
throw new NotFoundTransactionException;

if (in_array($transaction->status, [Enum::TRANSACTION_SUCCEED, Enum::TRANSACTION_FAILED]))
throw new RetryException;

$this->make($transaction->port);

return $this->port->verify($transaction);
}


/**
* Create new object from port class
*
* @param int $port
* @throws PortNotFoundException
*/
function make($port)
if ($port !== null) {
$this->make($port);
}
}

public function getSupportedPorts(): array
{
if ($port InstanceOf Mellat) {
$name = Enum::MELLAT;
} elseif ($port InstanceOf Parsian) {
$name = Enum::PARSIAN;
} elseif ($port InstanceOf Saman) {
$name = Enum::SAMAN;
} elseif ($port InstanceOf Zarinpal) {
$name = Enum::ZARINPAL;
} elseif ($port InstanceOf Sadad) {
$name = Enum::SADAD;
} elseif ($port InstanceOf Asanpardakht) {
$name = Enum::ASANPARDAKHT;
} elseif ($port InstanceOf Paypal) {
$name = Enum::PAYPAL;
} elseif ($port InstanceOf Payir) {
$name = Enum::PAYIR;
} elseif ($port InstanceOf Pasargad) {
$name = Enum::PASARGAD;
} elseif ($port InstanceOf Shahr) {
$name = Enum::SHAHR;
} elseif ($port InstanceOf Irankish) {
$name = Enum::IRANKISH;
} elseif (in_array(strtoupper($port), $this->getSupportedPorts())) {
$port = ucfirst(strtolower($port));
$name = strtoupper($port);
$class = __NAMESPACE__ . '\\' . $port . '\\' . $port;
return (array) Enum::getIPGs();
}

public function __call($name, $arguments)
{
if (in_array(strtoupper($name), $this->getSupportedPorts(), true)) {
return $this->make($name);
}

return call_user_func_array([$this->port, $name], $arguments);
}

public function getTable()
{
return DB::table($this->config->get('gateway.table'));
}

public function verify()
{
if (!$this->request->has('transaction_id') && !$this->request->has('iN')) {
throw new InvalidRequestException;
}

$id = $this->request->get('transaction_id', $this->request->get('iN'));
$transaction = $this->getTable()->whereId($id)->first();

if (!$transaction) {
throw new NotFoundTransactionException;
}

if (in_array($transaction->status, [Enum::TRANSACTION_SUCCEED, Enum::TRANSACTION_FAILED], true)) {
throw new RetryException;
}

$this->make($transaction->port);

return $this->port->verify($transaction);
}

public function make($port)
{
$name = $this->resolvePortName($port);

if ($name === null && in_array(strtoupper($port), $this->getSupportedPorts(), true)) {
$portName = ucfirst(strtolower($port));
$name = strtoupper($portName);
$class = __NAMESPACE__ . '\\' . $portName . '\\' . $portName;
$port = new $class;
} else
}

if ($name === null) {
throw new PortNotFoundException;
}

$this->port = $port;
$this->port->setConfig($this->config); // injects config
$this->port->setPortName($name); // injects config
$this->port->setConfig($this->config);
$this->port->setPortName($name);
$this->port->boot();

return $this;
}

private function resolvePortName($port): ?string
{
foreach (self::PORT_MAP as $class => $portName) {
if ($port instanceof $class) {
return $portName;
}
}

return null;
}
}