work on payments

This commit is contained in:
2025-10-30 22:33:28 +05:00
parent 68d544b9c3
commit 11f99caf42
5 changed files with 362 additions and 18 deletions

View File

@@ -0,0 +1,7 @@
<?php
return [
'username' => 'hello',
'password' => '',
'returnUrl' => '',
];

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Modules\HalkbankOnlinePayment;
use App\Modules\Makeable;
use App\Modules\ModuleContract;
class HalkbankOnlinePaymentModule implements ModuleContract
{
use Makeable;
/**
* Module is enabled
*/
protected bool $enabled = true;
/**
* Check if is module enabled
*/
public function isEnabled(): bool
{
return $this->enabled;
}
/**
* Disable module
*/
public function disable(): void
{
$this->enabled = false;
}
/**
* Enable module
*/
public function enable(): void
{
$this->enabled = true;
}
/**
* Check if module has a filament resource
*/
public function hasFilamentResource(): bool
{
return false;
}
/**
* Get module composer requirements
*/
public function getComposerRequirements(): array
{
return [];
}
/**
* Get module composer suggestions
*/
public function getComposerSuggestions(): array
{
return [];
}
}

View File

@@ -0,0 +1,224 @@
<?php
namespace App\Modules\HalkbankOnlinePayment\Repositories;
use App\Modules\Makeable;
use Closure;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class HalkbankOnlinePaymentRepository
{
use Makeable;
public function __construct(
protected string $username = '',
protected string $password = '',
protected string $amount = '',
protected int|string $orderNumber = '',
protected string $returnUrl = '',
protected string $description = '',
protected ?Closure $onRequestError = null,
protected ?Closure $onResponseFail = null,
protected ?Closure $onResponseSuccess = null,
) {
$this->username = config()->string('module.halkbank-online-payment.username');
$this->password = config()->string('module.halkbank-online-payment.password');
$this->returnUrl = config()->string('module.halkbank-online-payment.returnUrl');
$this->orderNumber = $this->generateOrderNumber();
}
/**
* Send request to gatewat
*/
public function sendRequest()
{
try {
$paymentResponse = Http::get('https://mpi.gov.tm/payment/rest/register.do', [
'orderNumber' => $this->orderNumber,
'amount' => $this->formatAmount($this->amount),
'currency' => 934,
'language' => 'ru',
'userName' => $this->username,
'password' => $this->password,
'returnUrl' => $this->returnUrl,
'pageView' => 'DESKTOP',
'description' => $this->description,
]);
} catch (Exception $e) {
Config::set('logging.channels.halkbank_payment_error', [
'driver' => 'single',
'path' => storage_path('logs/halkbank_payment_error.log'),
'level' => 'debug',
]);
Log::channel('halkbank_payment_error')
->error('Payment error', [
'response' => [
'error' => $e->getMessage(),
'file_line' => $e->getFile().':'.$e->getLine(),
],
]);
return emptyClass([]);
}
return $paymentResponse;
}
/**
* Format amount to match requirements
*/
public function formatAmount(int|float|string $amount): string
{
return number_format(floatval($amount), 2, '', '');
}
/**
* Get username
*/
public function username(): string
{
return $this->username;
}
/**
* Get password
*/
public function password(): string
{
return $this->password;
}
/**
* Get amount
*/
public function amount(): string
{
return $this->amount;
}
/**
* Get order number
*/
public function orderNumber(): int|string
{
return $this->orderNumber;
}
/**
* Set return url
*/
public function returnUrl(): string
{
return $this->returnUrl;
}
/**
* Set description
*/
public function description(): string
{
return $this->description;
}
/**
* Set username
*/
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
/**
* Set password
*/
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* Set amoutn
*/
public function setAmount(string $amount): self
{
$this->amount = $amount;
return $this;
}
/**
* Set order number
*/
public function setOrderNumber(int|string $orderNumber): self
{
$this->orderNumber = $orderNumber;
return $this;
}
/**
* Set return url
*/
public function setReturnUrl(string $returnUrl): self
{
$this->returnUrl = $returnUrl;
return $this;
}
/**
* Set description
*/
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
/**
* Set callback on request error
*/
public function setOnRequestError(Closure $onRequestError): self
{
$this->onRequestError = $onRequestError;
return $this;
}
/**
* Set callback on Response Fail
*/
public function setOnResponseFail(Closure $onResponseFail): self
{
$this->onResponseFail = $onResponseFail;
return $this;
}
/**
* Set callback on Response Success
*/
public function setOnResponseSuccess(Closure $onResponseSuccess): self
{
$this->onResponseSuccess = $onResponseSuccess;
return $this;
}
/**
* Generate order number for payment
*/
public function generateOrderNumber(): string
{
return date('dmyHis');
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Modules\OnlinePayment\Repositories; namespace App\Modules\OnlinePayment\Repositories;
use App\Modules\CardOrder\Models\CardOrder; use App\Modules\CardOrder\Models\CardOrder;
use App\Modules\HalkbankOnlinePayment\Repositories\HalkbankOnlinePaymentRepository;
use App\Modules\OnlinePayment\Models\OnlinePayment; use App\Modules\OnlinePayment\Models\OnlinePayment;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -24,7 +25,7 @@ class OnlinePaymentRepository
*/ */
public const PAID = 'paid'; public const PAID = 'paid';
/** /**
* Status Values * Status Values
* *
* @return array<null|string, string> * @return array<null|string, string>
@@ -39,14 +40,6 @@ class OnlinePaymentRepository
]; ];
} }
/**
* Set price
*/
public function getPrice(int|float|string $price): string
{
return number_format(floatval($price), 2, '', '');
}
/** /**
* Pay card order * Pay card order
* *
@@ -57,6 +50,18 @@ class OnlinePaymentRepository
{ {
$orderNumber = $this->generateOrderNumber(); $orderNumber = $this->generateOrderNumber();
$response = HalkbankOnlinePaymentRepository::make()
->setUsername()
->setPassword()
->setAmount()
->setOrderNumber()
->returnUrl()
->description()
->onError()
->onResponseFail()
->onResponseSuccess()
->sendRequest();
// $paymentResponse = Http::get('https://mpi.gov.tm/payment/rest/register.do', [ // $paymentResponse = Http::get('https://mpi.gov.tm/payment/rest/register.do', [
// 'orderNumber' => $orderNumber, // 'orderNumber' => $orderNumber,
// 'amount' => $this->getPrice($resource->priceAmount()), // 'amount' => $this->getPrice($resource->priceAmount()),

View File

@@ -55,33 +55,55 @@ function module_exists(string $moduleName): bool
} }
/** /**
* Create an anonymous class that acts as a dynamic object. * Create an anonymous dynamic object with both properties and callable methods.
* *
* @param mixed ...$arguments Key-value pairs passed as an associative array. * You can define any mix of:
* @return object Anonymous class instance with dynamic properties. * - scalar or object properties
* - closures (which become methods bound to $this)
*
* Example:
* ```php
* $user = emptyClass(
* name: 'Ali',
* greet: fn(): string => "Hello, {$this->name}",
* setName: fn(string $n): void => $this->name = $n,
* );
*
* echo $user->greet(); // Hello, Ali
* $user->setName('Ahmet');
* echo $user->greet(); // Hello, Ahmet
* ```
*
* @template T of object
*
* @param mixed ...$arguments Key-value pairs (property name => value or Closure)
* @return T Anonymous class instance exposing dynamic properties/methods.
*/ */
function emptyClass(...$arguments): object function emptyClass(mixed ...$arguments): object
{ {
/** /** @var T */
* @var array<string, mixed> $arguments
*/
return new class($arguments) return new class($arguments)
{ {
/** /**
* Internal data storage. * Internal data store.
* *
* @var array<string, mixed> * @var array<string, mixed>
*/ */
private array $data = []; private array $data = [];
/** /**
* Constructor that sets properties. * Constructor that sets up dynamic properties and binds closures.
* *
* @param array<string, mixed> $props * @param array<string, mixed> $props
*/ */
public function __construct(array $props) public function __construct(array $props)
{ {
foreach ($props as $key => $value) { foreach ($props as $key => $value) {
if ($value instanceof Closure) {
/** @var Closure $value */
$value = $value->bindTo($this, self::class);
}
$this->data[$key] = $value; $this->data[$key] = $value;
} }
} }
@@ -111,5 +133,27 @@ function emptyClass(...$arguments): object
{ {
return isset($this->data[$key]); return isset($this->data[$key]);
} }
/**
* Magic method caller invokes stored closures as methods.
*
* @param array<int, mixed> $args
*
* @throws BadMethodCallException if the method does not exist or is not callable.
*/
public function __call(string $method, array $args): mixed
{
$callable = $this->data[$method] ?? null;
if ($callable instanceof Closure) {
return $callable(...$args);
}
throw new BadMethodCallException(sprintf(
'Method %s() does not exist on %s.',
$method,
self::class
));
}
}; };
} }