input->get('psystem', TYPE_NOTAGS); # система оплаты $psystem = $this->paymentProvider($key); if ($psystem) { return $psystem->payProcess(); } $this->log('Не найдена система оплаты: ' . $key); return $this->payError('off'); } /** * Оплата счёта на основе данных от платёжной системы * @param int $billID ID счета (в таблице TABLE_BILLS) * @param int|float $money сумма счета (оплачиваемая) * @param string $paySystemKey ключ системы оплаты * @param mixed $details детали от платежной системы * @param array $extra доп.параметры (если необходимо) * @return bool|\bff\http\Response */ public function processBill($billID, $money = 0, $paySystemKey = '', $details = false, $extra = []) { $paySystemTitle = $paySystemKey . (isset($extra['way']) ? ' / ' . $extra['way'] : ''); # Проверяем ID счета if (! is_numeric($billID) || $billID <= 0) { $this->log($paySystemTitle . ': некорректный номер счета, #' . $billID); return $this->payError('wrong_bill_id'); } $billData = $this->model->billData($billID, [ 'user_id','item_id', 'psystem','status','amount','money', 'service_settings', ]); if (empty($billData)) { $this->log($paySystemTitle . ': Оплачен несуществующий счёт #' . $billID); return $this->payError('pay_error'); } # Проверяем доступность способа оплаты if ($paySystemKey !== $billData['psystem']) { $this->log($paySystemTitle . ': Cчёт #' . $billID . ' выставлен для оплаты другой системой оплаты (' . $billData['psystem'] . ')'); return $this->payError('pay_error'); } # Проверяем статус счета if ( $billData['status'] == static::STATUS_CANCELED || $billData['status'] == static::STATUS_COMPLETED ) { $this->log($paySystemTitle . ': Оплачен уже ранее оплаченный счёт или счёт с другим статусом, #' . $billID); return $this->payError('pay_error'); } # Проверка суммы if ($money < $billData['money']) { $this->log("$paySystemTitle: Сумма оплаты($money) счета #$billID меньше выставленной ранее({$billData['money']})"); return $this->payError('amount_error'); } # Закрываем счет: # - обновляем статус на "завершен" # - помечаем дату оплаты текущей if ( ! $this->completeBill( $billID, true, [ 'user_id' => $billData['user_id'], 'amount' => $billData['amount'], 'add' => true, ], $details ) ) { $this->log('Ошибка закрытия счета #[id]', ['id' => $billID]); return $this->payError('pay_error'); } # - пополняем счет пользователя на сумму $this->updateUserBalance($billData['user_id'], $billData['amount'], true); # отправим почтовое уведомление пользователю if ($billData['user_id']) { $user = Users::model()->userData($billData['user_id'], ['name','email','balance','user_id','user_id_ex','last_login','lang']); $langCurrent = $this->locale->current(); $this->locale->setCurrentLanguage($user['lang'], true); $mailData = [ 'name' => $user['name'], 'email' => $user['email'], 'user_id' => $billData['user_id'], 'amount' => Currency::formatPriceAndCurrency($billData['amount']), 'balance' => Currency::formatPriceAndCurrency($user['balance']), 'auth_link' => $this->url('wallet', ['alogin' => Users::loginAutoHash($user)]), ]; $this->app->sendMailTemplate($mailData, 'users_balance_plus', $user['email'], false, '', '', $user['lang']); $this->locale->setCurrentLanguage($langCurrent, true); } Svc::activateServices($billData['service_settings']); return true; } public function success() { # завершаем процесс подачи объявление (после покупки платного лимита) $limits = Session::pull('listings-item-add-limits-payed-process', []); if (! empty($limits['item_id'])) { $params = [ 'success' => 1, 'id' => $limits['item_id'], ]; if (! empty($limits['ak'])) { $params['ak'] = $limits['ak']; } return $this->redirect(Listings::url('item.add', $params)); } $id = $this->input->getpost('id', TYPE_UINT); $result = $this->app->filter('bills.pay.success', '', ['id' => &$id]); if (! empty($result)) { return $result; } $bill = $this->model->billData($id, ['*'], User::id()); $title = _t('bills', 'Payment successfully completed'); $message = [_t('bills', 'Thank you for your payment.')]; if (empty($bill) || empty($bill['service_settings'])) { $message[] = _t('bills', 'You have successfully Top Upped your balance'); if (! User::guest()) { $message[] = _t('bills', 'In your account: [balance]', [ 'link' => $this->url('wallet'), 'balance' => Currency::formatPriceAndCurrency(User::balance()), ]); } } return $this->showSuccess($title, $message); } public function fail() { $id = $this->input->getpost('id', TYPE_UINT); $result = $this->app->filter('bills.pay.fail', '', ['id' => &$id]); if (! empty($result)) { return $result; } $paySystemKey = $this->input->get('w', TYPE_NOTAGS); $system = $this->paymentProvider($paySystemKey); $paySystemTitle = $system ? $system->providerTitle() : ''; $title = _t('bills', 'Payment of invoice'); $message = _t('bills', 'Error paying bill'); if (! empty($paySystemKey)) { $message .= _t('bills', '"[way]" system', [ 'way' => $paySystemTitle, ]); } return $this->showForbidden($title, $message); } # Вспомогательный результирующий метод для некоторых системы оплат public function result() { $this->app->hook('bills.pay.result'); $id = $this->input->get('id', TYPE_UINT); do { if (! $id) { break; } $billData = $this->model->billData($id, ['status','type','payed']); if (empty($billData)) { break; } if ( $billData['status'] != static::STATUS_COMPLETED || $billData['type'] != static::TYPE_IN_PAY || $billData['payed'] == '0000-00-00 00:00:00' || (time() - strtotime($billData['payed']) > 3600) ) { break; } return $this->success(); } while (false); return $this->fail(); } /** * Content of /ads.txt * @return \bff\http\Response */ public function ads_txt() { $content = $this->config('bills.ads.txt', ''); $file = $this->app->publicPath('ads.txt'); if (file_exists($file)) { $content = file_get_contents($file); } return Response::text($content); } }