From 11f99caf424b01151e7396d8a47754124b9bd930 Mon Sep 17 00:00:00 2001 From: Nurmuhammet Allanov Date: Thu, 30 Oct 2025 22:33:28 +0500 Subject: [PATCH] work on payments --- .../halkbank-online-payment-config.php | 7 + .../HalkbankOnlinePaymentModule.php | 64 +++++ .../HalkbankOnlinePaymentRepository.php | 224 ++++++++++++++++++ .../Repositories/OnlinePaymentRepository.php | 23 +- app/Modules/module-helpers.php | 62 ++++- 5 files changed, 362 insertions(+), 18 deletions(-) create mode 100644 app/Modules/HalkbankOnlinePayment/Configs/halkbank-online-payment-config.php create mode 100644 app/Modules/HalkbankOnlinePayment/HalkbankOnlinePaymentModule.php create mode 100644 app/Modules/HalkbankOnlinePayment/Repositories/HalkbankOnlinePaymentRepository.php diff --git a/app/Modules/HalkbankOnlinePayment/Configs/halkbank-online-payment-config.php b/app/Modules/HalkbankOnlinePayment/Configs/halkbank-online-payment-config.php new file mode 100644 index 0000000..930cf42 --- /dev/null +++ b/app/Modules/HalkbankOnlinePayment/Configs/halkbank-online-payment-config.php @@ -0,0 +1,7 @@ + 'hello', + 'password' => '', + 'returnUrl' => '', +]; diff --git a/app/Modules/HalkbankOnlinePayment/HalkbankOnlinePaymentModule.php b/app/Modules/HalkbankOnlinePayment/HalkbankOnlinePaymentModule.php new file mode 100644 index 0000000..7aec872 --- /dev/null +++ b/app/Modules/HalkbankOnlinePayment/HalkbankOnlinePaymentModule.php @@ -0,0 +1,64 @@ +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 []; + } +} diff --git a/app/Modules/HalkbankOnlinePayment/Repositories/HalkbankOnlinePaymentRepository.php b/app/Modules/HalkbankOnlinePayment/Repositories/HalkbankOnlinePaymentRepository.php new file mode 100644 index 0000000..a7e1aa6 --- /dev/null +++ b/app/Modules/HalkbankOnlinePayment/Repositories/HalkbankOnlinePaymentRepository.php @@ -0,0 +1,224 @@ +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'); + } +} diff --git a/app/Modules/OnlinePayment/Repositories/OnlinePaymentRepository.php b/app/Modules/OnlinePayment/Repositories/OnlinePaymentRepository.php index d996ebb..520b01b 100644 --- a/app/Modules/OnlinePayment/Repositories/OnlinePaymentRepository.php +++ b/app/Modules/OnlinePayment/Repositories/OnlinePaymentRepository.php @@ -3,6 +3,7 @@ namespace App\Modules\OnlinePayment\Repositories; use App\Modules\CardOrder\Models\CardOrder; +use App\Modules\HalkbankOnlinePayment\Repositories\HalkbankOnlinePaymentRepository; use App\Modules\OnlinePayment\Models\OnlinePayment; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; @@ -24,7 +25,7 @@ class OnlinePaymentRepository */ public const PAID = 'paid'; - /** + /** * Status Values * * @return array @@ -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 * @@ -57,6 +50,18 @@ class OnlinePaymentRepository { $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', [ // 'orderNumber' => $orderNumber, // 'amount' => $this->getPrice($resource->priceAmount()), diff --git a/app/Modules/module-helpers.php b/app/Modules/module-helpers.php index cfca1bc..d69dc83 100644 --- a/app/Modules/module-helpers.php +++ b/app/Modules/module-helpers.php @@ -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. - * @return object Anonymous class instance with dynamic properties. + * You can define any mix of: + * - 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 array $arguments - */ + /** @var T */ return new class($arguments) { /** - * Internal data storage. + * Internal data store. * * @var array */ private array $data = []; /** - * Constructor that sets properties. + * Constructor that sets up dynamic properties and binds closures. * * @param array $props */ public function __construct(array $props) { foreach ($props as $key => $value) { + if ($value instanceof Closure) { + /** @var Closure $value */ + $value = $value->bindTo($this, self::class); + } + $this->data[$key] = $value; } } @@ -111,5 +133,27 @@ function emptyClass(...$arguments): object { return isset($this->data[$key]); } + + /** + * Magic method caller — invokes stored closures as methods. + * + * @param array $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 + )); + } }; }