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 paymentProvider(PaymentProviderContract $provider): self { $this->provider = $provider; return $this; } /** * 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(); } return $this; } /** * Check payment */ public function checkPayment(string $orderId): array { /** @var \App\Modules\OnlinePayment\Models\OnlinePayment Find payment order from history */ $paymentHistory = OnlinePayment::where('orderId', $orderId)->first(); /** @var \Illuminate\Database\Eloquent\Model Find related resource */ $relatedResource = (new $paymentHistory->online_paymantable_type)->find(id: $paymentHistory->online_paymantable_id); // Check if resource could not be found or does not exist if (! $relatedResource) { return $this->paymentFailed('(RESOURCE NOT FOUND)'); } $relatedResource->load('branch'); /** @var \App\Modules\Branch\Models\Branch */ $bankBranch = $relatedResource->branch; if (! $bankBranch) { 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['ErrorCode'] == '0' ? $this->paymentSuccessful($relatedResource, $paymentHistory, $bankBranch) : $this->paymentFailed(__('Payment has failed'), $paymentHistory, $bankBranch); } /** * 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; } OnlinePayment::create($data); } public function paymentSuccessful($relatedResource, $paymentHistory, $bankBranch): array { $relatedResource->update([ 'paid' => true, ]); $paymentHistory->update([ 'paymentStatus' => OnlinePaymentRepository::PAID, ]); return $this->paymentCheckResponseTemplate( success: true, pnr: $paymentHistory->online_paymantable_id, branch_name: $bankBranch->name, price_amount: $paymentHistory->amount.' TMT' ); } /** * Failed payment */ public function paymentFailed(string $title = '', $paymentHistory = null, $bankBranch = null): array { if ($paymentHistory) { $paymentHistory->update([ 'paymentStatus' => OnlinePaymentRepository::FAILED, ]); return $this->paymentCheckResponseTemplate( success: false, pnr: $paymentHistory->online_paymantable_id, branch_name: $bankBranch->name, price_amount: $paymentHistory->amount.' TMT' ); } return $this->paymentCheckResponseTemplate(false, $title); } /** * Check payment response * * @return array{success: bool, title: string, pnr: string, branch_name: string, price_amount: string, return_url: string} */ public function paymentCheckResponseTemplate( bool $success, string $title = '', string $pnr = '', string $branch_name = '', 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{success: bool, title: string, pnr: string, branch_name: string, price_amount: string, return_url: string} $data */ public function paymentStatusView(array $data): View { return view('module.online-payment::payment-status', $data); } }