Пример #1
0
 /**
  * @deprecated Синхронная выплата, сейчас используется очередь
  * 
  * Выплата через сервис
  * 
  * @param type $reserveInstance
  * @param type $type
  * @return substatus
  * @throws Exception
  */
 public function payout($reserveInstance, $type)
 {
     $uid = $reserveInstance->getFrlId();
     $reserve_id = $reserveInstance->getID();
     $sum = $reserveInstance->getPayoutSum();
     //Подготовка данных/реквизитов для последующей работы с API
     try {
         if ($sum <= 0) {
             throw new ReservesPayoutException(ReservesPayoutException::WRONG_SUM);
         }
         $reqv = array();
         $request_list = $this->getPayouts($reserve_id);
         $is_allow_repeated = $this->isAllowRepeatedRequest($request_list);
         if ($is_allow_repeated) {
             //Это повторный запрос на выплату
             //нельзя менять реквизиты!
             //Если нельзя обновлять реквизиты то читаем из слепка
             $data_reqv = $this->getPayoutReqv($reserve_id);
             if ($data_reqv) {
                 $reqv = mb_unserialize($data_reqv['fields']);
                 if ($reqv) {
                     $type = $data_reqv['pay_type'];
                 }
             }
             if (!$reqv) {
                 throw new ReservesPayoutException(ReservesPayoutException::REQV_INVALID);
             }
             $is_update = false;
             //Если нет мобильного у существующих реквизитов
             //то пробует получить из обычного телефона
             if (!isset($reqv['mob_phone']) || empty($reqv['mob_phone'])) {
                 $is_update = true;
                 $reqv['mob_phone'] = @$reqv['phone'];
                 if (empty($reqv['mob_phone'])) {
                     throw new ReservesPayoutException(ReservesPayoutException::PHONE_FAIL);
                 }
             }
             //Если выплата на карту то получаем и сохраняем ее синоним
             if ($type == ReservesPayoutPopup::PAYMENT_TYPE_CARD && !isset($reqv['skr_destinationCardSynonim'])) {
                 $is_update = true;
                 $reqv['skr_destinationCardSynonim'] = $this->getDestinationCardSynonim($reqv['el_ccard'], $sum);
                 if (!$reqv['skr_destinationCardSynonim']) {
                     throw new ReservesPayoutException(ReservesPayoutException::CARD_SYNONIM_FAIL);
                 }
             }
             //Обновляем реквизиты
             if ($is_update) {
                 $this->updateReqv($reserve_id, $reqv);
                 //Фиксируем остояние в истории
                 $this->saveToHistory($reserve_id);
             }
         } else {
             //Иначе сознаем новый запрос на выплату
             $reqv = $this->getUserReqvs($uid, $type, $sum);
             if (!$reqv) {
                 throw new ReservesPayoutException(ReservesPayoutException::REQV_FAIL, $type, $uid);
             }
             //Если выплата на карту то получаем и сохраняем ее синоним
             if ($type == ReservesPayoutPopup::PAYMENT_TYPE_CARD) {
                 $reqv['skr_destinationCardSynonim'] = $this->getDestinationCardSynonim($reqv['el_ccard'], $sum);
                 if (!$reqv['skr_destinationCardSynonim']) {
                     throw new ReservesPayoutException(ReservesPayoutException::CARD_SYNONIM_FAIL);
                 }
             }
             //Создаем запросы на выплату если нужно дробим сумму
             $request_list = $this->calcRequestList($reserve_id, $sum);
             $this->db()->start();
             $ok_1 = $this->insertReqv($reserve_id, $type, $reqv);
             if ($ok_1) {
                 foreach ($request_list as $key => $payout) {
                     $ok_2 = $this->db()->insert($this->TABLE, $payout, 'id');
                     if (!$ok_2) {
                         break;
                     }
                     $request_list[$key]['id'] = $ok_2;
                 }
             }
             //Если при добавлении списка задач или реквизитов возникла ошибка
             //то откатываем назад транзакцию и валимся с ошибкой
             if (!$ok_1 || !$ok_2) {
                 $this->db()->rollback();
                 $request_list = array();
                 throw new ReservesPayoutException(ReservesPayoutException::INS_FAIL);
             }
             if (!$this->db()->commit()) {
                 $request_list = array();
                 throw new ReservesPayoutException(ReservesPayoutException::INS_FAIL);
             }
             //Если все ок - сохраняем в историю
             $this->saveToHistory($reserve_id);
         }
         //На всякий пожарный проверяем наличие списка задач на выплату
         if (empty($request_list)) {
             throw new ReservesPayoutException(ReservesPayoutException::RQST_EMPTY);
         }
     } catch (Exception $e) {
         $this->errorLog($reserve_id, $e->getMessage());
         return ReservesModel::SUBSTATUS_ERR;
     }
     $substatus = ReservesModel::SUBSTATUS_PAYED;
     //Если это не боевой сервер то всегда успешная выплата
     //но! при этом не меняется статус у задач из reserves_payout
     if (!is_release()) {
         return $substatus;
     }
     //Формирование запроса к API сервиса и обработка ответа
     try {
         $depositionRequest = new DepositionRequest();
         $depositionRequest->setAgentId($this->agent_id);
         $depositionRequest->setCurrency($this->currency);
         $depositionRequest->setPofOfferAccepted(1);
         $depositionRequest->setSmsPhoneNumber(trim(str_replace('+', '', $reqv['mob_phone'])));
         foreach ($request_list as $key => $request) {
             if ($request['status'] == static::STATUS_SUCCESS) {
                 continue;
             }
             $depositionRequest->setAmount(number_format($request['price'], 2, '.', ''));
             $depositionRequest->setClientOrderId($request['id']);
             //Заполняем общие параметры для платежей
             //Например реквизиты юзера
             switch ($type) {
                 case ReservesPayoutPopup::PAYMENT_TYPE_RS:
                     //Реквизиты юзера
                     $fio = explode(' ', $reqv['fio']);
                     $depositionRequest->setTmpFirstName(@$fio[1]);
                     $depositionRequest->setTmpMiddleName(@$fio[2]);
                     $depositionRequest->setTmpLastName(@$fio[0]);
                 case ReservesPayoutPopup::PAYMENT_TYPE_CARD:
                     //Реквизиты юзера
                     $fio = explode(' ', $reqv['fio']);
                     $depositionRequest->setPdrFirstName(@$fio[1]);
                     $depositionRequest->setPdrMiddleName(@$fio[2]);
                     $depositionRequest->setPdrLastName(@$fio[0]);
                     if (isset($reqv['rez_type']) && @$reqv['rez_type'] == sbr::RT_UABYKZ) {
                         $depositionRequest->setPdrDocType(10);
                     } else {
                         $depositionRequest->setPdrDocType(21);
                     }
                     $depositionRequest->setPdrDocNumber(@$reqv['idcard_ser'] . @$reqv['idcard']);
                     $date = explode('.', @$reqv['idcard_from']);
                     $depositionRequest->setPdrDocIssueYear(@$date[2]);
                     $depositionRequest->setPdrDocIssueMonth(@$date[1]);
                     $depositionRequest->setPdrDocIssueDay(@$date[0]);
                     $depositionRequest->setPdrDocIssuedBy(@$reqv['idcard_by']);
                     $country_iso = @$reqv['country_iso'];
                     //@todo: если не удалось выявить код то Россия Матушка :D !
                     $depositionRequest->setPdrCountry($country_iso ? $country_iso : 643);
                     //парсим адрес по формату:
                     //127287, Россия, г. Москва, ул. 2-я Хуторская д 38А стр.9
                     $info = explode(',', @$reqv['address']);
                     if (isset($reqv['index']) && !empty($reqv['index'])) {
                         $depositionRequest->setPdrPostcode($reqv['index']);
                     } else {
                         $depositionRequest->setPdrPostcode(trim(@$info[0]));
                     }
                     if (isset($reqv['city']) && !empty($reqv['city'])) {
                         $depositionRequest->setPdrCity($reqv['city']);
                         $depositionRequest->setPdrBirthPlace($reqv['city']);
                     } else {
                         $depositionRequest->setPdrCity(trim(@$info[2]));
                         $depositionRequest->setPdrBirthPlace(trim(@$info[2]));
                     }
                     if (count($info) > 4) {
                         unset($info[0], $info[1], $info[2]);
                         $depositionRequest->setPdrAddress(trim(implode(',', $info)));
                     } else {
                         $depositionRequest->setPdrAddress(trim(@$info[3]));
                     }
                     $depositionRequest->setPdrBirthDate(@$reqv['birthday']);
                     break;
             }
             //Специфика для каждого платежа в отдельности
             switch ($type) {
                 case ReservesPayoutPopup::PAYMENT_TYPE_YA:
                     $depositionRequest->setDstAccount($reqv['el_yd']);
                     break;
                 case ReservesPayoutPopup::PAYMENT_TYPE_CARD:
                     $depositionRequest->setDstAccount(25700130535186);
                     $depositionRequest->setSkrDestinationCardSynonim($reqv['skr_destinationCardSynonim']);
                     break;
                 case ReservesPayoutPopup::PAYMENT_TYPE_RS:
                     $depositionRequest->setDstAccount(2570066962077);
                     $bank = explode(',', $reqv['bank_name']);
                     $depositionRequest->setBankName(trim(@$bank[0]));
                     if (isset($reqv['bank_city']) && !empty($reqv['bank_city'])) {
                         $depositionRequest->setBankCity(trim(@$reqv['bank_city']));
                     } else {
                         $depositionRequest->setBankCity(trim(@$bank[1]));
                     }
                     $depositionRequest->setBankBIK(trim(@$reqv['bank_bik']));
                     $depositionRequest->setBankCorAccount(trim(@$reqv['bank_ks']));
                     $depositionRequest->setBankKPP(trim(@$reqv['bank_kpp']));
                     $depositionRequest->setBankINN(trim(@$reqv['bank_inn']));
                     /*@todo: ЯД меняет формат на ходу, тут устаревший
                       if (isset($reqv['bank_assignment']) && 
                          !empty($reqv['bank_assignment'])) {
                           $depositionRequest->setDepositAccount(@$reqv['bank_rs']);
                           $depositionRequest->setFaceAccount(@$reqv['bank_assignment']);
                       } else {
                           $depositionRequest->setRubAccount(@$reqv['bank_rs']);
                       }
                       */
                     $bank_rs = trim(@$reqv['bank_rs']);
                     $depositionRequest->setDepositAccount($bank_rs);
                     $depositionRequest->setFaceAccount($bank_rs);
                     $depositionRequest->setCustAccount($bank_rs);
                     break;
                 default:
                     throw new ReservesPayoutException(ReservesPayoutException::TYPE_INVALID, $type);
             }
             $current_substatus = ReservesModel::SUBSTATUS_PAYED;
             //Запрос к API
             $result = $this->getApiFacade()->testDeposition($depositionRequest);
             if (!$result->isSuccess() && $result->getError() != 26) {
                 $current_substatus = ReservesModel::SUBSTATUS_ERR;
             } else {
                 $result = $this->getApiFacade()->makeDeposition($depositionRequest);
                 if ($result->getStatus() == static::STATUS_INPROGRESS) {
                     $current_substatus = ReservesModel::SUBSTATUS_INPROGRESS;
                 } elseif ($result->getStatus() == static::STATUS_FAIL) {
                     $current_substatus = ReservesModel::SUBSTATUS_ERR;
                 }
             }
             $_request = array('status' => $result->getStatus(), 'error' => !$result->isSuccess() ? $result->getError() : 0, 'last' => 'NOW()', 'cnt' => $request['cnt'] + 1, 'techmessage' => $result->getTechMessage());
             $this->db()->update($this->TABLE, $_request, 'id = ?i', $result->getClientOrderId());
             if ($current_substatus == ReservesModel::SUBSTATUS_ERR) {
                 if ($substatus != ReservesModel::SUBSTATUS_INPROGRESS) {
                     $substatus = $current_substatus;
                 }
                 $techmessage = $result->getTechMessage();
                 if ($techmessage) {
                     $techmessage = " ({$techmessage})";
                 }
                 $this->errorLog($reserve_id, sprintf(ReservesPayoutException::LAST_PAYED_FAIL, $result->getClientOrderId(), $result->getError(), $techmessage));
             } elseif ($current_substatus == ReservesModel::SUBSTATUS_INPROGRESS) {
                 $substatus = $current_substatus;
             }
         }
         //Сохраняем в историю слепок с последнего ответа
         $this->saveToHistory($reserve_id);
     } catch (Exception $e) {
         $this->errorLog($reserve_id, $e->getMessage());
         return ReservesModel::SUBSTATUS_ERR;
     }
     return $substatus;
 }