relatedModel = $relatedModel; } /** * Status Values * * @return array */ public static function statusValues(): array { return [ null => '-', self::PENDING => __('Pending'), self::PAID => __('Paid'), self::FAILED => __('Cancelled'), ]; } /** * Generate order number for payment */ public function generateOrderNumber(): string { return date('dmyHis'); } /** * Payment provder */ public function setPaymentProvider(PaymentProviderContract $provider): self { $this->provider = $provider; return $this; } /** * Payment provider */ public function paymentProvider(): PaymentProviderContract { return $this->provider; } /** * Online payment */ public function onlinePayment(): OnlinePayment { return $this->onlinePayment; } /** * If payment has been successfull */ public function successful(): bool { return $this->successful; } /** * If payment has been a failure */ public function failed(): bool { return $this->failed; } /** * Set respond results */ public function setResponseResults(bool $result): void { $this->successful = $result; $this->failed = ! $result; } /** * Send request via provider */ public function sendRequest(): self { $this->response = $this->provider->sendRequest(); $this->failed = $this->response->failed(); $this->successful = $this->response->successful(); if ($this->response['errorCode'] != 0) { $this->setResponseResults(false); } if ($this->successful) { $this->orderId = string($this->response['orderId']); $this->paymentLink = string($this->response['formUrl']); $this->createHistory(); } else { 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' => [ 'title' => 'REGISTER', 'error' => $this->response->body(), 'file_line' => __FILE__.':'.__LINE__, ], ]); } return $this; } /** * Payment link */ public function paymentLink(): string { return $this->paymentLink; } /** * Create online payment history */ public function createHistory(): void { $data = [ 'amount' => $this->provider->amount(), 'orderNumber' => $this->provider->orderNumber(), 'description' => $this->provider->description(), 'orderId' => $this->orderId, 'formUrl' => $this->paymentLink, 'successUrl' => $this->provider->returnUrl(), 'errorUrl' => $this->provider->returnUrl(), 'username' => $this->provider->username(), 'paymentStatus' => self::PENDING, ]; if ($this->relatedModel) { $data['online_paymantable_id'] = $this->relatedModel->id; // @phpstan-ignore-line $data['online_paymantable_type'] = $this->relatedModel::class; } $this->onlinePayment = OnlinePayment::create($data); } /** * Check payment * * @return array */ public function checkPayment(string $orderId): array { // Find payment order from history /** @var \App\Modules\OnlinePayment\Models\OnlinePayment */ $paymentHistory = OnlinePayment::where('orderId', $orderId)->first(); // Resolve related resource model dynamically /** @var \Illuminate\Database\Eloquent\Model Find related resource */ $modelClass = $paymentHistory->online_paymantable_type; $modelId = $paymentHistory->online_paymantable_id; if (! class_exists($modelClass)) { return $this->paymentFailed('(RELATED RESOURCE CLASS NOT FOUND)'); } $relatedResource = (new $modelClass)->find(id: $modelId); // Check if resource could not be found or does not exist if (! $relatedResource) { return $this->paymentFailed('(RESOURCE NOT FOUND)'); } $relatedResource->loadMissing('branch'); /** @var \App\Modules\Branch\Models\Branch */ $bankBranch = $relatedResource->branch; if (! $bankBranch || is_null($bankBranch->billing_username) || is_null($bankBranch->billing_password)) { // @phpstan-ignore-line return $this->paymentFailed('(BRANCH NOT FOUND)'); } $this->provider->setUsername($bankBranch->billing_username); $this->provider->setPassword($bankBranch->billing_password); $response = $this->provider->checkPayment($orderId); if ($response['errorCode'] == '99') { return $this->paymentFailed('(REQUEST FAILURE)'); } return $response['paymentAmountInfo']['depositedAmount'] > 0 // @phpstan-ignore-line ? $this->paymentSuccessful($relatedResource, $paymentHistory, $bankBranch->name) : $this->paymentFailed(__('Payment has failed'), $paymentHistory, $bankBranch->name); } /** * Successful payment * * @return array */ public function paymentSuccessful(Model $relatedResource, OnlinePayment $paymentHistory, string $branchName = ''): array { $relatedResource->update([ 'paid' => true, ]); $paymentHistory->update([ 'paymentStatus' => OnlinePaymentRepository::PAID, ]); return $this->paymentCheckResponseTemplate( success: true, pnr: $paymentHistory->online_paymantable_id, branch_name: $branchName, price_amount: $paymentHistory->amount.' TMT' ); } /** * Failed payment * * @return array */ public function paymentFailed(string $title = '', ?OnlinePayment $paymentHistory = null, string $branchName = ''): array { if ($paymentHistory) { $paymentHistory->update([ 'paymentStatus' => OnlinePaymentRepository::FAILED, ]); return $this->paymentCheckResponseTemplate( success: false, pnr: $paymentHistory->online_paymantable_id, branch_name: $branchName, price_amount: $paymentHistory->amount.' TMT' ); } return $this->paymentCheckResponseTemplate(false, $title); } /** * Check payment response * * @return array */ public function paymentCheckResponseTemplate( bool $success, string $title = '', int|string $pnr = '', string $branch_name = '', int|string $price_amount = '', string $return_url = '' ): array { return [ 'success' => $success, 'title' => $title !== '' ? $title : ($success ? __('Payment is successful') : __('Payment has failed')), 'pnr' => $pnr, 'branch_name' => $branch_name, 'price_amount' => $price_amount, 'return_url' => $return_url !== '' ? $return_url : url('/'), ]; } /** * Show payment status * * @param array $data */ public function paymentStatusView(array $data): View { return view('module.online-payment::payment-status', $data); } }