Beispiel #1
0
    def get_coupon_info(self, reg_id):
        url = self.common_url.format("coupon/info?lang=ru")

        self.coupon_info["clientId"] = self.account['login']

        payload = self.coupon_info
        payload["random"] = get_random_str()
        payload["sign"] = "secret password"
        payload["regId"] = reg_id
        payload['fsid'] = self.payload['fsid']

        msg = get_dumped_payload(payload)
        sign = hmac.new(key=sha512(self.account['password'].encode()).hexdigest().encode(), msg=msg.encode(), digestmod=sha512).hexdigest()
        payload["sign"] = sign
        data = get_dumped_payload(payload)
        # url = 'https://23.111.238.130/session/coupon/info?lang=en'
        prnt('BET_FONBET.PY - get_coupon_info rq: ' + str(url) + ': ' + str(data), 'hide')
        resp = requests_retry_session().post(
            url,
            headers=self.fonbet_headers,
            data=data,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        prnt('BET_FONBET.PY - get_coupon_info rs: ' + str(resp.text), 'hide')
        check_status_with_resp(resp)
        res = resp.json()

        # if res.get("result") == "error":
        # prnt('BET_FONBET.PY: error get coupon info: ' + str(res))
        # raise LoadException("BET_FONBET.PY: " + str(res.get('errorMessage')))

        return res
Beispiel #2
0
    def _check_sell_result(self, requestId: int) -> None:
        """Check if bet is placed successfully"""

        url = self.common_url.format("coupon/sell/result")
        url = url.replace('session/', '')

        payload = self.payload_sell_check_result.copy()
        headers = self.fonbet_headers

        payload['requestId'] = requestId
        payload['clientId'] = self.base_payload["clientId"]
        payload['fsid'] = self.payload['fsid']
        prnt('BET_FONBET.PY - _check_sell_result rq: ' + str(payload), 'hide')
        resp = requests_retry_session().post(
            url,
            headers=headers,
            json=payload,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        check_status_with_resp(resp)
        res = resp.json()
        prnt('BET_FONBET.PY _check_sell_result rs: ' + str(res), 'hide')

        if self.cnt_sale_attempt > 40:
            err_str = 'BET_FONBET.PY: error sale bet in Fonbet(coupon is lock): ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)

        # {'result': 'unableToSellCoupon', 'requestId': 19920670, 'regId': 14273664108, 'reason': 4, 'actualSellSum': 4900}

        if res.get('result') == "sellDelay":
            sell_delay_sec = (float(res.get('sellDelay')) / 1000) + self.add_sleep
            prnt('BET_FONBET.PY: sell_delay: ' + str(sell_delay_sec) + ' sec...')
            time.sleep(sell_delay_sec)
            return self._check_sell_result(res.get('requestId'))

        elif res.get('result') == 'unableToSellCoupon':
            if res.get('reason') in (3, 2):
                sleep_tempblock = 3 + self.add_sleep
                err_str = 'BET_FONBET.PY, err sale bet, coupon tempBlock = True: ' + str(res) + ' ' + \
                          'sell_delay: ' + str(sleep_tempblock) + ' sec...'
                time.sleep(sleep_tempblock)
                prnt(err_str)
                return self.sale_bet()
            else:
                err_str = 'BET_FONBET.PY, err sale bet, new actualSellSum: ' + str(res.get('actualSellSum') / 10)
                prnt(err_str)
                return self.sale_bet()

        elif res.get('result') == 'couponCompletelySold':
            sold_sum = res.get('soldSum')
            prnt('BET_FONBET.PY: Fonbet sell successful, sold_sum: ' + str(sold_sum / 100))
            return True
        else:
            # if res.get("errorCode") != "0":
            err_str = 'BET_FONBET.PY: error sell result: ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)
Beispiel #3
0
    def get_operations(self, count: 45):

        url = self.common_url.format("client/lastOperations?lang=ru")

        payload = self.payload_hist.copy()
        headers = self.fonbet_headers

        payload['maxCount'] = count
        payload['clientId'] = self.base_payload["clientId"]
        payload['fsid'] = self.payload['fsid']

        resp = requests_retry_session().post(
            url,
            headers=headers,
            json=payload,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        check_status_with_resp(resp)
        res = resp.json()

        if res.get('operations'):
            return res
        else:
            prnt('BET_FONBET.PY: error get history: ' + str(res))
            raise LoadException("BET_FONBET.PY: " + str(resp))
Beispiel #4
0
def get_urls(mirror, proxies):
    global fb_browser_head
    url = "https://" + mirror + "/urls.json?{}".format(random())
    resp = requests_retry_session().get(
        url,
        headers=fb_browser_head,
        verify=False,
        timeout=4,
        proxies=proxies
    )
    check_status_with_resp(resp)
    return resp.json()
Beispiel #5
0
    def get_history_bet(self, event_id=None, filter="0100", offset="0"):

        if event_id and not self.matchid:
            self.matchid = event_id

        if not self.session_payload.get("session"):
            self.sign_in()

        req_url = olimp_url2.format("user/history")

        payload = {}

        payload["filter"] = filter  # только не расчитанные
        payload["offset"] = offset
        payload["session"] = self.session_payload["session"]
        payload["lang_id"] = "0"
        payload["platforma"] = "ANDROID1"
        payload["time_shift"] = "0"

        headers = base_headers.copy()
        headers.update(get_xtoken_bet(payload))
        headers.update({'X-XERPC': '1'})
        prnt('BET_OLIMP.PY - get_history_bet rq hist: ' + str(payload), 'hide')
        resp = requests_retry_session().post(
            req_url,
            headers=headers,
            data=payload,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        prnt('BET_OLIMP.PY - get_history_bet rs hist: ' + str(resp.text), 'hide')
        check_status_with_resp(resp)
        res = resp.json()
        prnt('BET_OLIMP.PY - get_history_bet rs js hist: ' + str(res), 'hide')
        if res.get('error').get('err_code') != 0:
            prnt('BET_OLIMP.PY: error get history: ' + str(res))
            raise LoadException("BET_OLIMP.PY: " + str(res.get('error').get('err_desc')))

        if event_id is not None:
            for bet_list in res.get('data').get('bet_list'):
                if str(bet_list.get('events')[0].get('matchid')) == str(event_id):
                    self.reg_id = bet_list.get('bet_id')
                    return {
                        'bet_id': bet_list.get('bet_id'),
                        'amount': bet_list.get('cashout_amount'),
                        'cashout_allowed': bet_list.get('cashout_allowed')
                    }
        else:
            return res.get('data')
Beispiel #6
0
    def _check_in_bounds(self, wager: dict) -> None:
        """Check if amount is in allowed bounds"""
        url = self.common_url.format("coupon/getMinMax")

        payload = self.payload_bet.copy()
        headers = self.fonbet_headers

        if wager.get('param'):
            payload["coupon"]["bets"][0]["param"] = int(wager['param'])
        payload["coupon"]["bets"][0]["score"] = wager['score']
        payload["coupon"]["bets"][0]["value"] = float(wager['value'])
        payload["coupon"]["bets"][0]["event"] = int(wager['event'])
        payload["coupon"]["bets"][0]["factor"] = int(wager['factor'])

        payload['fsid'] = self.payload['fsid']
        payload['clientId'] = self.base_payload["clientId"]

        prnt('BET_FONBET.PY: check bet to bk fonbet, time: ' + str(datetime.datetime.now()))
        resp = requests_retry_session().post(
            url,
            headers=headers,
            json=payload,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        check_status_with_resp(resp)
        res = resp.json()
        prnt('BET_FONBET.PY: Fonbet, check in bound request:' + str(resp.status_code) + ', res: ' + str(res), 'hide')
        if "min" not in res:
            err_str = 'BET_FONBET.PY: error (min): ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)

        min_amount, max_amount = round(res["min"] * self.cur_rate // 100, 2), round(res["max"] * self.cur_rate // 100, 2)

        if not (min_amount <= self.amount_rub <= self.balance) or not (min_amount <= self.amount_rub <= max_amount):
            prnt('BET_FONBET.PY: balance:' + str(self.balance))
            err_str = 'BET_FONBET.PY: error (min_amount: {} <= amount: {} <= max_amount: {}| balance: {}'.format(min_amount, self.amount_rub, max_amount, self.balance)
            prnt(err_str)
            raise LoadException(err_str)
        prnt('BET_FONBET.PY: Min_amount=' + str(min_amount) + ' Max_amount=' + str(max_amount))
Beispiel #7
0
    def get_urls(self):

        mirror = get_account_info('fonbet', 'mirror')
        if not mirror:
            url = self.not_url
        else:
            url = mirror

        url = "https://" + url + "/urls.json?{}".format(random())
        prnt('BET_FONBET.PY: Fonbet, get_urls request: ' + str(url) + '\n' + str(browser_headers), 'hide')
        resp = requests_retry_session().get(
            url,
            headers=browser_headers,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        prnt('BET_FONBET.PY: Fonbet, get_urls responce: ' + str(resp.status_code) + ', ' + str(resp.text), 'hide')
        check_status_with_resp(resp)
        return resp.json()
Beispiel #8
0
    def _get_request_id(self) -> int:
        """request_id is generated every time we placing bet"""
        url = self.common_url.format("coupon/requestId")

        headers = self.fonbet_headers

        payload_req = self.payload_req.copy()
        payload_req['fsid'] = self.payload['fsid']
        payload_req['clientId'] = self.base_payload["clientId"]
        payload_req['client']['id'] = self.base_payload["clientId"]

        resp = requests_retry_session().post(url, headers=headers, json=payload_req, verify=False, timeout=self.timeout)
        check_status_with_resp(resp)
        res = resp.json()
        if "requestId" not in res:
            prnt('BET_FONBET.PY: rror in def:_get_request_id' + str(res))
            raise LoadException("BET_FONBET.PY: key 'requestId' not found in response")
        else:
            prnt('BET_FONBET.PY: Success get requestId=' + str(res["requestId"]))
        self.payload['requestId'] = res["requestId"]
        return res["requestId"]
Beispiel #9
0
    def get_cur_max_bet_id(self, event_id=None, filter="0100", offset="0"):

        if not self.session_payload.get("session"):
            self.sign_in()

        req_url = olimp_url2.format("user/history")

        payload = {}

        payload["filter"] = filter  # только не расчитанные
        payload["offset"] = offset
        payload["session"] = self.session_payload["session"]
        payload["lang_id"] = "0"
        payload["platforma"] = "ANDROID1"
        payload["time_shift"] = "0"

        headers = base_headers.copy()
        headers.update(get_xtoken_bet(payload))
        headers.update({'X-XERPC': '1'})
        prnt('BET_OLIMP.PY - get_cur_bet_id rq: ' + str(payload), 'hide')
        resp = requests_retry_session().post(
            req_url,
            headers=headers,
            data=payload,
            verify=False,
            timeout=self.timeout,
            proxies=self.proxies
        )
        prnt('BET_OLIMP.PY - get_cur_bet_id rs: ' + str(resp.status_code) + ' ' + str(resp.text), 'hide')
        check_status_with_resp(resp)
        res = resp.json()
        prnt('BET_OLIMP.PY - get_cur_bet_id rs js: ' + str(res), 'hide')

        if res.get('error').get('err_code') != 0:
            err_str = 'BET_OLIMP.PY: error get_cur_bet_id: ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)

        max_bet_id = 0
        coupon_data = {}
        # reg_id - мы знаем заранее - только при ручном выкупе как правило
        if self.reg_id:
            coupon_found = False
            for bet_list in res.get('data').get('bet_list', []):
                cur_bet_id = bet_list.get('bet_id')
                if cur_bet_id == self.reg_id:
                    coupon_found = True
                    max_bet_id = cur_bet_id
                    coupon_data = bet_list
            if not coupon_found:
                err_str = 'BET_OLIMP.PY: coupon reg_id ' + str(self.reg_id) + ' not found: ' + str(res)
                prnt(err_str)
                raise LoadException(err_str)

        # Мы не знаем reg_id и берем последний по матчу
        elif event_id:
            for bet_list in res.get('data').get('bet_list', []):
                if str(bet_list.get('events')[0].get('matchid')) == str(event_id):
                    cur_bet_id = bet_list.get('bet_id')
                    if cur_bet_id > max_bet_id:
                        max_bet_id = cur_bet_id
                        coupon_data = bet_list
        # Мы не знаем мата и берем просто последний
        else:
            for bet_list in res.get('data').get('bet_list', []):
                cur_bet_id = bet_list.get('bet_id')
                if cur_bet_id > max_bet_id:
                    max_bet_id = cur_bet_id
                    coupon_data = bet_list

        if max_bet_id:
            self.reg_id = max_bet_id
            return coupon_data
Beispiel #10
0
    def place_bet(self, obj={}) -> None:
        """
        :param amount: amount of money to be placed (RUB)
        :param wager: defines on which wager bet is to be placed (could be either OlimpWager or OlimpCondWager)
        """
        wager = obj.get('wager_olimp')
        amount = obj.get('amount_olimp')
        if self.wager is None and wager:
            self.wager = wager
        if self.amount is None and amount:
            self.amount = amount

        self.amount = round(self.amount / self.cur_rate, 2)
        self.amount_rub = round(self.amount * self.cur_rate, 2)

        if obj.get('fonbet_err', 'ok') != 'ok':
            err_str = 'BET_OLIMP.PY: Олимп получил ошибку от Фонбета: ' + str(obj.get('fonbet_err'))
            prnt(err_str)
            raise FonbetBetError(err_str)

        url = olimp_url2.format("basket/fast")

        payload = self.session_payload.copy()

        payload.update({
            "coefs_ids": '[["{apid}",{factor},1]]'.format(
                apid=self.wager.get('apid'), factor=self.wager.get('factor')),
            "sport_id": self.wager.get('sport_id'),
            "sum": self.amount,
            "save_any": 3,
            "fast": 1,
            "any_handicap": 1
        })
        # Принимать с изменёнными коэффициентами:
        # save_any: 1 - никогда, 2 - при повышении, 3 - всегда

        # Принимать с измененными тоталами/форами:
        # any_handicap: 1 - Нет, 2 - Да

        headers = base_headers.copy()
        headers.update(get_xtoken_bet(payload))

        if not self.amount_rub <= self.balance:
            err_str = 'BET_OLIMP.PY: error amount > balance, balance:' + str(self.balance)
            prnt(err_str)
            raise LoadException(err_str)

        prnt('BET_OLIMP.PY: send bet to bk olimp, time: ' + str(datetime.datetime.now()))
        prnt('BET_OLIMP.PY: rq olimp: ' + str(payload), 'hide')
        try:
            resp = requests_retry_session().post(
                url,
                headers=headers,
                data=payload,
                verify=False,
                timeout=15,
                proxies=self.proxies
            )
        except Exception as e:
            prnt('BET_OLIMP.PY: rs timeout: ' + str(e))
            self.place_bet(obj=obj)

        prnt('BET_OLIMP.PY: rs olimp: ' + str(resp.text), 'hide')

        if resp.status_code in (504, 500):
            return self.place_bet(obj=obj)

        check_status_with_resp(resp, True)
        res = resp.json()
        prnt('BET_OLIMP.PY: rs js olimp: ' + str(res), 'hide')

        req_time = round(resp.elapsed.total_seconds(), 2)
        n_sleep = max(0, (self.sleep - req_time))

        err_code = res.get("error", {}).get('err_code')
        err_msg = res.get("error", {}).get('err_desc')

        # {"error": {"err_code": 400, "err_desc": "Выбранный Вами исход недоступен"}, "data": null}
        # {"error": {"err_code": 417, "err_desc": "Невозможно принять ставку на указанный исход!"}, "ata": null}
        # Прием ставок приостановлен

        # {'error': {'err_code': 417, 'err_desc': 'Такой исход не существует'}, 'data': None}
        # тут ничего сделать не сможем

        # {"error": {"err_code": 417, "err_desc": "Сменился коэффициент на событие (5=>1.24)"}, "data": null}

        if err_code == 0:
            #  {'isCache': 0, 'error': {'err_code': 0, 'err_desc': None}, 'data': 'Ваша ставка успешно принята!'}
            self.matchid = self.wager['event']
            self.get_cur_max_bet_id(self.matchid)
            prnt('BET_OLIMP.PY: bet successful, reg_id: ' + str(self.reg_id))
        elif err_code in (400, 417):
            if err_code == 417 and 'Такой исход не существует' in err_msg:
                err_str = 'BET_OLIMP.PY: error place bet: ' + str(res.get("error", {}).get('err_desc'))
                prnt(err_str)
                raise LoadException(err_str)
            # MaxBet
            elif 'максимальная ставка' in err_msg:
                err_str = 'BET_OLIMP.PY: error max bet: ' + str(res.get("error", {}).get('err_desc'))
                prnt(err_str)
                raise LoadException(err_str)
            else:
                if self.cnt_bet_attempt > (60 * 0.4) / self.sleep:
                    err_str = 'BET_OLIMP.PY: error place bet: ' + str(res.get("error", {}).get('err_desc'))
                    prnt(err_str)
                    raise LoadException(err_str)

                self.cnt_bet_attempt = self.cnt_bet_attempt + 1
                prnt('BET_OLIMP.PY: ' + str(res.get("error", {}).get('err_desc')) + '. попытка #'
                     + str(self.cnt_bet_attempt) + ' через ' + str(n_sleep) + ' сек')
                time.sleep(n_sleep)
                return self.place_bet(obj=obj)
        elif "data" not in res or res.get("data") != "Ваша ставка успешно принята!":
            # res["data"] != "Your bet is successfully accepted!" :
            err_str = 'BET_OLIMP.PY: error place bet: ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)
        else:
            err_str = 'BET_OLIMP.PY: error place bet: ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)
Beispiel #11
0
def get_new_bets_fonbet(match_id, proxies, time_out):
    from meta_fb import url_fonbet_match, fonbet_header2, VICTS, TTO, TTU, TT1O, TT1U, TT2O, TT2U
    key_id = str(match_id)
    bets_fonbet = {}
    try:
        resp = requests_retry_session().get(
            url_fonbet_match + str(match_id) + "&lang=en",
            headers=fonbet_header2,
            timeout=time_out,
            verify=False,
            proxies=proxies,
        )
        resp = resp.json()

        TT = []
        for bet in [TTO, TTU, TT1O, TT1U, TT2O, TT2U]:
            TT.extend(bet)

        for event in resp.get("events"):
            # prnt(jsondumps(event, ensure_ascii=False))
            # exit()

            score = event.get('score', '0:0').replace('-', ':')
            timer = event.get('timer')
            minute = event.get('timerSeconds', 0) / 60
            skId = event.get('skId')
            skName = event.get('skName')
            sport_name = event.get('sportName')
            name = event.get('name')
            priority = event.get('priority')
            score_1st = event.get('scoreComment', '').replace('-', ':')

            if event.get('parentId') == 0 or event.get('name') in ('1st half', '2nd half'):
                if event.get('parentId') == 0:
                    try:
                        bets_fonbet[key_id].update({
                            'sport_id': skId,
                            'sport_name': skName,
                            'league': sport_name,
                            'name': name,
                            'priority': priority,
                            'score': score,
                            'score_1st': score_1st,
                            'time': timer,
                            'minute': minute,
                            'time_req': round(time.time())
                        })
                    except Exception as e:
                        bets_fonbet[key_id] = {
                            'sport_id': skId,
                            'sport_name': skName,
                            'league': sport_name,
                            'name': name,
                            'priority': priority,
                            'score': score,
                            'score_1st': score_1st,
                            'time': timer,
                            'minute': minute,
                            'time_req': round(time.time()),
                            'time_change_total': round(time.time()),
                            'avg_change_total': [],
                            'kofs': {}
                        }

                # prnt('event_name', event.get('name'))

                half = ''
                if event.get('name') == '1st half':
                    half = '1'
                elif event.get('name') == '2nd half':
                    half = '2'

                for cat in event.get('subcategories'):

                    cat_name = cat.get('name')
                    # prnt('cat_name', cat_name)
                    if cat_name in ('1X2 (90 min)', '1X2', 'Goal - no goal', 'Total', 'Totals', 'Team Totals-1', 'Team Totals-2', 'Hcap'):  # , '1st half', '2nd half'
                        for kof in cat.get('quotes'):
                            factorId = str(kof.get('factorId'))
                            pValue = kof.get('pValue', '')
                            p = kof.get('p', '')
                            kof_is_block = kof.get('blocked', False)
                            if kof_is_block:
                                value = 0
                            else:
                                value = kof.get('value')
                            # {'event': '12788610', 'factor': '921', 'param': '', 'score': '1:0', 'value': '1.25'}
                            for vct in VICTS:
                                coef = half + str(vct[0])  # + num_team
                                if str(vct[1]) == factorId:
                                    bets_fonbet[key_id]['kofs'].update(
                                        {
                                            coef:
                                                {
                                                    'time_req': round(time.time()),
                                                    'event': event.get('id'),
                                                    'value': value,
                                                    'param': '',
                                                    'factor': factorId,
                                                    'score': score
                                                }
                                        }
                                    )

                            for stake in TT:
                                coef = half + str(stake[0].format(p))  # + num_team
                                if str(stake[1]) == factorId:
                                    bets_fonbet[key_id]['kofs'].update(
                                        {
                                            coef:
                                                {
                                                    'time_req': round(time.time()),
                                                    'event': event.get('id'),
                                                    'value': value,
                                                    'param': pValue,
                                                    'factor': factorId,
                                                    'score': score
                                                }}
                                    )
        return bets_fonbet
    except Exception as e:
        prnt(e)
        raise ValueError(e)
Beispiel #12
0
def get_fonbet_info(match_id, factor_id, param, bet_type=None):
    dop_stat = dict()
    sc1 = None
    sc2 = None

    prnt('get_fonbet_info: match_id:{}, factor_id:{}, param:{}, bet_type:{}'.
         format(match_id, factor_id, param, bet_type))

    header = copy.deepcopy(fb_headers)
    url = url_fonbet + "/line/eventView?eventId=" + str(match_id) + "&lang=ru"
    prnt('FORK_RECHECK.PY: get_fonbet_info rq: ' + url + ' ' + str(header),
         'hide')
    resp = requests_retry_session().get(url,
                                        headers=header,
                                        timeout=10,
                                        verify=False)
    prnt('FORK_RECHECK.PY: get_fonbet_info rs: ' + str(resp.text), 'hide')
    res = resp.json()

    result = res.get('result')

    if result == "error":
        prnt('fonbet err : ' + str(res))
        return 0, '0:0', round(resp.elapsed.total_seconds(), 2), {}

    for event in res.get("events"):
        if event.get('id') == match_id:
            sc = event.get('score', '0:0').replace('-', ':')
            period = 1
            time_break_fonbet = False
            if re.match('\(\d+:\d+\)', event.get('scoreComment', '').replace('-', ':').replace(' ', '')) and \
                    str(event.get('timer', '')) == '45:00' and \
                    event.get('timerSeconds', 0) == 45.0:
                time_break_fonbet = True
                period = 2
            elif re.match('\(\d+:\d+\)', event.get('scoreComment', '').replace('-', ':').replace(' ', '')) and \
                    event.get('timerSeconds', 0) / 60 > 45.0:
                period = 2
            try:
                sc1 = int(sc.split(':')[0])
            except:
                pass
            try:
                sc2 = int(sc.split(':')[1])
            except:
                pass

            dop_stat = {
                'cur_score':
                sc,
                'sc1':
                sc1,
                'sc2':
                sc2,
                '1st_half_score':
                event.get('scoreComment'),
                'minutes':
                round(event.get('timerSeconds', 0) / 60) +
                (event.get('timerSeconds', 0) % 60 / 100),
                'timer':
                event.get('timer'),
                'period':
                period,
                'timebreak':
                time_break_fonbet
            }
            if bet_type:
                dop_stat.update({'vector': get_vector(bet_type, sc1, sc2)})

            for cat in event.get('subcategories'):
                for kof in cat.get('quotes'):
                    if kof.get('factorId') == factor_id:

                        if param:
                            err_str = None
                            if kof.get('pValue') != param:
                                prnt(
                                    'Изменилась тотал ставки, param не совпадает: '
                                    + 'new: ' + str(kof.get('pValue')) +
                                    ', old: ' + str(param))

                                if bet_type:
                                    prnt('поиск нового id тотала: ' + bet_type)
                                    new_wager = get_new_bets_fonbet(match_id,
                                                                    proxies={})
                                    new_wager = new_wager.get(
                                        str(match_id),
                                        {}).get('kofs', {}).get(bet_type)
                                    if new_wager:
                                        prnt('Тотал найден: ' + str(new_wager))
                                        k = new_wager.get('value', 0)
                                        sc = new_wager.get('score',
                                                           '0:0').replace(
                                                               '-', ':')
                                        return k, sc, round(
                                            resp.elapsed.total_seconds(),
                                            2), dop_stat
                                    else:
                                        err_str = 'Тотал не найден: ' + str(
                                            new_wager)
                                else:
                                    err_str = 'Тип ставки, например 1ТМ(2.5) - не задан: bet_type:' + bet_type
                            if err_str:
                                prnt(err_str)
                                raise BetIsLost(err_str)
                        k = kof.get('value', 0)
                        prnt('fonbet kof is blocked ' +
                             str(kof.get('blocked', 'None')))
                        if kof.get('blocked'):
                            prnt('fonbet kof is blocked ' + str(kof))
                            k = 0
                        prnt('fonbet score: ' + sc)
                        dop_stat.update({'val': k})
                        prnt('FORK_RECHECK.PY: get_olimp_info end work',
                             'hide')
                        return k, sc, round(resp.elapsed.total_seconds(),
                                            2), dop_stat
Beispiel #13
0
    def _check_result(self, payload: dict, obj) -> None:
        """Check if bet is placed successfully"""

        self.check_stat_olimp(obj)

        url = self.common_url.format("coupon/result")
        try:
            del payload["coupon"]
        except:
            pass

        '''
        del wager["appVersion"]
        del wager["deviceManufacturer"]
        del wager["deviceModel"]
        del wager["platform"]
        '''

        headers = self.fonbet_headers
        resp = requests_retry_session().post(
            url,
            headers=headers,
            json=payload,
            verify=False,
            timeout=self.timeout
        )
        req_time = round(resp.elapsed.total_seconds(), 2)
        check_status_with_resp(resp)
        res = resp.json()
        prnt(res, 'hide')
        err_res = res.get('result')

        if self.cnt_bet_attempt > (60 * 0.4) / self.sleep:
            err_str = 'BET_FONBET.PY: error place bet in Fonbet: ' + str(res)
            prnt(err_str)
            raise LoadException(err_str)

        if err_res == 'couponResult':
            err_code = res.get('coupon').get('resultCode')

            # 100 - Блокировка по матчу: 'Ставки на событие XXX временно не принимаются'
            # 2 - Коэффициента вообще нет или котировка поменялась: 'Изменена котировка на событие XXX' - делаем выкуп
            if err_code == 0:
                regId = res.get('coupon').get('regId')
                prnt('BET_FONBET.PY: Fonbet bet successful, regId: ' + str(regId))
                self.reg_id = regId
            elif err_code == 100:
                # {
                #     "result": "couponResult",
                #     "coupon": {
                #         "resultCode": 100,
                #         "errorMessage": "Ставки на событие \"Веракрус Кампинас (ж) - Санту-Андре/Семаса (ж)\" временно не принимаются",
                #         "errorMessageRus": "Ставки на событие \"Веракрус Кампинас (ж) - Санту-Андре/Семаса (ж)\" временно не принимаются",
                #         "errorMessageEng": "The betting on event \"Veracruz Campinas (w) - Santo-Andre/Semasa (w)\" is temporary suspended",
                #         "amountMin": 30,
                #         "amountMax": 200,
                #         "amount": 30,
                #         "bets": [
                #             {
                #                 "event": 18285127,
                #                 "factor": 921,
                #                 "value": 3.15,
                #                 "score": "32:40"
                #             }
                #         ]
                #     }
                # }
                if 'Слишком частые ставки на событие' in res.get('coupon').get('errorMessageRus'):
                    err_str = "BET_FONBET.PY error:" + str(res)
                    prnt(err_str)
                    raise LoadException(err_str)

                self.cnt_bet_attempt = self.cnt_bet_attempt + 1
                n_sleep = max(0, (self.sleep - req_time))
                prnt('BET_FONBET.PY: ' + str(res.get('coupon').get('errorMessageRus')) + ', новая котировка:'
                     + str(res.get('coupon').get('bets')[0]['value']) + ', попытка #'
                     + str(self.cnt_bet_attempt) + ' через ' + str(n_sleep) + ' сек')
                time.sleep(n_sleep)
                return self.place_bet(obj=obj)

            # Изменился ИД: {'result': 'couponResult', 'coupon': {'resultCode': 2, 'errorMessage': 'Изменена котировка на событие "LIVE 0:0 Грузия U17 - Словакия U17 < 0.5"', 'errorMessageRus': 'Изменена котировка на событие "LIVE 0:0 Грузия U17 - Словакия U17 < 0.5"', 'errorMessageEng': 'Odds changed "LIVE 0:0 Georgia U17 - Slovakia U17 < 0.5"', 'amountMin': 30, 'amountMax': 81100, 'amount': 100, 'bets': [{'event': 13013805, 'factor': 1697, 'value': 1.37, 'param': 150, 'paramText': '1.5', 'paramTextRus': '1.5', 'paramTextEng': '1.5', 'score': '0:0'}]}}
            # Вообще ушла: {"result":"couponResult","coupon":{"resultCode":2,"errorMessage":"Изменена котировка на событие \"LIVE 1:0 Берое - Ботев Галабово Поб 1\"","errorMessageRus":"Изменена котировка на событие \"LIVE 1:0 Берое - Ботев Галабово Поб 1\"","errorMessageEng":"Odds changed \"LIVE 1:0 Beroe - Botev Galabovo 1\"","amountMin":30,"amountMax":3000,"amount":30,"bets":[{"event":13197928,"factor":921,"value":0,"score":"0:0"}]}}
            elif err_code == 2:
                err_str = str(res.get('coupon').get('errorMessageRus'))
                # Котировка вообще ушла
                if res.get('coupon').get('bets')[0]['value'] == 0:
                    err_str = "BET_FONBET.PY: error while placing the bet, current bet is hide: " + str(err_str)
                    prnt(err_str)
                    raise LoadException(err_str)
                # Изменился ИД тотола(как правило)
                else:
                    new_wager = res.get('coupon').get('bets')[0]
                    # {'result': 'couponResult', 'coupon':
                    # {'resultCode': 2,
                    # 'errorMessage': 'Изменена котировка на событие "LIVE 0:0 1-й тайм Альбион Роверс (р) - Ливингстон (р) < 0.5"',
                    # 'errorMessageRus': 'Изменена котировка на событие "LIVE 0:0 1-й тайм Альбион Роверс (р) - Ливингстон (р) < 0.5"',
                    # 'errorMessageEng': 'Odds changed "LIVE 0:0 1st half Albion Rovers (r) - Livingston (r) < 0.5"',
                    # 'amountMin': 30,
                    # 'amountMax': 32300,
                    # 'amount': 180,
                    # 'bets': [{'event': 13223785,
                    # 'factor': 931, 'value': 1.35, 'param': 150, 'paramText': '1.5',
                    # 'paramTextRus': '1.5', 'paramTextEng': '1.5', 'score': '0:1'}]}}

                    if str(new_wager.get('param', '')) == str(self.wager.get('param', '')) and \
                            int(self.wager.get('factor', 0)) != int(new_wager.get('factor', 0)):
                        prnt('Изменилась ИД ставки: old: ' + str(self.wager)
                             + ', new: ' + str(new_wager) + ' ' + str(err_str))
                        self.wager.update(new_wager)
                        return self.place_bet(obj=obj)
                    # В данном случае мы не проверяем кофы на изменение, если добавм надо подумать нужно ли это
                    # if float(new_wager.get('value', 0)) < float(self.wager.get('value', 0)):
                    #     n_sleep = max(0, (self.sleep - req_time))
                    #     self.cnt_bet_attempt = self.cnt_bet_attempt + 1
                    #     prnt('Коф-меньше запрошенного: ' + str(self.wager)
                    #          + ', new: ' + str(new_wager) + ' ' + str(err_str) +
                    #          ', попытка #' + str(self.cnt_bet_attempt) + ' через ' + str(n_sleep) + ' сек')
                    #     time.sleep(n_sleep)
                    #     return self.place_bet(obj=obj)
                    elif str(new_wager.get('param', '')) != str(self.wager.get('param', '')) and \
                            int(self.wager.get('factor', 0)) == int(new_wager.get('factor', 0)):
                        err_str = "BET_FONBET.PY: error Изменилась тотал ставки, 'param' не совпадает: " + \
                                  str(err_str) + ', new_wager: ' + str(new_wager) + ', old_wager: ' + str(self.wager)
                        prnt(err_str)
                        if self.fonbet_bet_type:
                            prnt('BET_FONBET.PY: поиск нового ИД тотала: ' + str(self.fonbet_bet_type))
                            match_id = self.wager.get('event')
                            new_wager = get_new_bets_fonbet(match_id, self.proxies, self.timeout)
                            new_wager = new_wager.get(str(match_id), {}).get('kofs', {}).get(self.fonbet_bet_type)
                            if new_wager:
                                prnt('BET_FONBET.PY: Тотал найден: ' + str(new_wager))
                                self.wager.update(new_wager)
                                return self.place_bet(obj=obj)
                            else:
                                err_str = 'BET_FONBET.PY: Тотал не найден'
                                prnt(err_str)
                                raise LoadException(err_str)
                        else:
                            err_str = 'BET_FONBET.PY: Тип ставки, например 1ТМ(2.5) - не задан, выдаю ошибку.'
                            prnt(err_str)
                            raise LoadException(err_str)
                    else:
                        err_str = "BET_FONBET.PY: error неизвестная ошибка: " + \
                                  str(err_str) + ', new_wager: ' + str(new_wager) + ', old_wager: ' + str(self.wager)
                        prnt(err_str)
                        raise LoadException(err_str)
            else:
                raise LoadException(res.get('coupon').get('errorMessage', ''))
        elif err_res == 'error' and "temporary unknown result" in resp.text:
            # there's situations where "temporary unknown result" means successful response
            # {'result': 'error', 'errorCode': 200, 'errorMessage': 'temporary unknown result'}
            err_str = 'BET_FONBET.PY: Get temporary unknown result: ' + str(res)
            prnt(err_str)
            time.sleep(3)
            return self._check_result(payload, obj)
        else:
            err = 'BET_FONBET.PY: error bet place result: ' + str(res)
            prnt(err)
            raise LoadException("BET_FONBET.PY: response came with an error: " + str(err))
Beispiel #14
0
    def place_bet(self, obj={}) -> None:

        self.check_stat_olimp(obj)
        self._get_request_id()

        wager = obj.get('wager_fonbet')
        amount = obj.get('amount_fonbet')
        if self.wager is None and wager:
            self.wager = wager
        if self.amount is None and amount:
            self.amount = amount

        self.amount = round(self.amount / self.cur_rate, 2)
        self.amount_rub = round(self.amount * self.cur_rate, 2)

        fonbet_bet_type = obj['fonbet_bet_type']
        if self.fonbet_bet_type is None and fonbet_bet_type:
            self.fonbet_bet_type = fonbet_bet_type

        url = self.common_url.format("coupon/register")

        payload = self.payload_bet.copy()
        headers = self.fonbet_headers

        payload["client"] = {"id": self.base_payload["clientId"]}

        payload["requestId"] = self.payload['requestId']

        if self.wager.get('param'):
            payload["coupon"]["bets"][0]["param"] = int(self.wager['param'])

        payload["coupon"]["bets"][0]["score"] = self.wager['score']
        payload["coupon"]["bets"][0]["value"] = float(self.wager['value'])
        payload["coupon"]["bets"][0]["event"] = int(self.wager['event'])
        payload["coupon"]["bets"][0]["factor"] = int(self.wager['factor'])
        payload["coupon"]["amount"] = self.amount
        payload['fsid'] = self.payload['fsid']
        payload['clientId'] = self.base_payload["clientId"]
        # payload['coupon']['flexBet'] = 'up'

        self._check_in_bounds(self.wager)

        prnt('BET_FONBET.PY: send bet to bk fonbet, time: ' + str(datetime.datetime.now()))
        try:
            resp = requests_retry_session().post(
                url,
                headers=headers,
                json=payload,
                verify=False,
                timeout=15,
                proxies=self.proxies
            )
        except Exception as e:
            prnt('BET_FONBET.PY: rs timeout: ' + str(e))
            self.place_bet(obj=obj)

        prnt('BET_FONBET.PY: response fonbet: ' + str(resp.text), 'hide')

        check_status_with_resp(resp)
        res = resp.json()
        prnt(res, 'hide')

        req_time = round(resp.elapsed.total_seconds(), 2)
        n_sleep = max(0, (self.sleep - req_time))

        result = res.get('result')

        if result == "betDelay":
            # {"result":"betDelay","betDelay":3000}
            bet_delay_sec = (float(res.get('betDelay')) / 1000) + self.add_sleep
            prnt('BET_FONBET.PY: bet_delay: ' + str(bet_delay_sec) + ' sec...')
            time.sleep(bet_delay_sec)

        self._check_result(payload, obj)
Beispiel #15
0
def get_olimp_info(id_matche, olimp_k, sport_id, proxies=None, place=None):
    prnt(
        'get_olimp_info: id_matche=' + str(id_matche) + ';sport_id=' +
        str(sport_id) + ';olimp_k=' + str(olimp_k) + ';proxies=' +
        str(proxies), 'hide')
    bet_into = {}
    olimp_data = copy.deepcopy(ol_payload)
    olimp_data.update({"live": 1, "sport_id": sport_id})
    olimp_data.update({'id': id_matche})
    if place == 'pre':
        olimp_data.update({'live': 0})
    olimp_stake_head = copy.deepcopy(ol_headers)
    olimp_stake_head.update(get_xtoken_bet(olimp_data))
    olimp_stake_head.pop('Accept-Language', None)

    prnt('FORK_RECHECK.PY: get_olimp_info rq: ' + str(olimp_data), 'hide')

    res = requests_retry_session().post(
        # ol_url_api.format('10', 'stakes/'),
        ol_url_api.format('stakes/'),
        data=olimp_data,
        headers=olimp_stake_head,
        timeout=10,
        verify=False,
        proxies=proxies)
    prnt('FORK_RECHECK.PY: get_olimp_info rs: ' + str(res.text), 'hide')

    resp = res.json()
    if not resp.get('error', {}).get('err_code', 0):
        stake = resp.get('data', {})

        bet_into['ID'] = id_matche

        is_block = ''
        if place == 'pre':
            if stake:
                is_block = stake.get('ms', False)
            else:
                is_block = False
        else:
            if str(stake.get('ms', '')) == '1':
                is_block = True  # 1 - block, 2 - available
                # prnt('Олимп: ставки приостановлены: http://olimp.com/app/event/live/1/' + str(stake.get('id', '')))
        bet_into['BLOCKED'] = is_block
        prnt('olimp kof is blocked: ' + str(is_block))

        minutes = "-1"
        try:
            minutes = re.findall('\d{1,2}\"',
                                 stake.get('scd', ''))[0].replace('"', '')
        except:
            pass
        bet_into['MINUTES'] = minutes

        # startTime=datetime.datetime.strptime(stake.get('dt',''), "%d.%m.%Y %H:%M:%S")
        # currentTime=datetime.datetime.strptime(datetime.datetime.now(pytz.timezone('Europe/Moscow')).strftime("%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S")
        # timeDif = currentTime-startTime

        # minuts
        bet_into['SCORE'] = stake.get('sc',
                                      '0:0')  # .get('sc', '0:0').split(' ')[0]
        for c in stake.get('it', []):
            # del: угловые
            # if c.get('n','') in ['Main Bets', 'Goals', 'Corners', 'Individual total', 'Additional total']:
            # if c.get('n', '').replace(' ', '').lower() in ['основные', 'голы', 'угловые', 'инд.тотал', 'доп.тотал', 'исходыпотаймам']:
            group_kof = c.get('n', '').replace(' ', '').lower()
            group_kof = group_kof.replace('азиатские', '')
            if group_kof in [
                    'основные', 'голы', 'инд.тотал', 'доп.тотал',
                    'исходыпотаймам', 'победасучетомфоры', 'форы', 'тоталы',
                    'инд.тоталы'
            ]:
                for d in c.get('i', []):
                    if 'обе забьют: '.lower() \
                            in d.get('n', '').lower() \
                            or 'забьет: '.lower() \
                            in d.get('n', '').lower() \
                            or 'никто не забьет: '.lower() \
                            in d.get('n', '').lower() \
                            or 'победа '.lower() \
                            in d.get('n', '').lower() \
                            or d.get('n', '').lower().endswith(' бол') \
                            or d.get('n', '').lower().endswith(' мен') \
                            or 'с форой'.lower() \
                            in d.get('n', '').lower() \
                            or 'первая не проиграет'.lower() \
                            in d.get('n', '').lower() \
                            or 'вторая не проиграет'.lower() \
                            in d.get('n', '').lower() \
                            or 'ничьей не будет' \
                            in d.get('n', '').lower() \
                            or 'ничья'.lower() \
                            in d.get('n', '').lower() \
                            or 'форы' in group_kof:
                        if 'форы' in group_kof:
                            key_r = d.get('n', '').replace(
                                stake.get('c1', ''),
                                'П1сфорой').replace(stake.get('c2', ''),
                                                    'П2сфорой')
                            key_r = key_r.replace(' ', '')
                        else:
                            key_r = d.get('n', '').replace(
                                stake.get('c1', ''),
                                'Т1').replace(stake.get('c2', ''), 'Т2')
                        olimp_factor_short = str([
                            abbreviations[c.replace(' ', '')] if c.replace(
                                ' ', '') in abbreviations.keys() else
                            c.replace(' ', '') if '(' not in c.replace(
                                ' ', '') else to_abb(c) for c in [key_r]
                        ][0])

                        val_kof = d.get('v', '')
                        if is_block:
                            val_kof = 0

                        bet_into[olimp_factor_short] = val_kof

    else:
        is_block = True
    k = bet_into.get(olimp_k, 0)
    if is_block:
        k = 0
    try:
        sc = bet_into.get('SCORE', '0:0').split(' ')[0]
    except:
        sc = '0'
    prnt('olimp is_block: ' + str(is_block))
    prnt('olimp score: ' + sc)
    prnt('olimp bet_into: ' + str(bet_into))
    prnt('olimp k: ' + str(k))
    prnt('FORK_RECHECK.PY: get_olimp_info end work', 'hide')
    return k, sc, round(res.elapsed.total_seconds(), 2)
Beispiel #16
0
    def sale_bet(self, reg_id=None):
        # Перезапишем ИД если он указан явно
        if not self.reg_id:
            self.reg_id = reg_id

        coupon = self.get_cur_max_bet_id(self.matchid)
        cashout_allowed = coupon.get('cashout_allowed', False)
        cashout_amount = coupon.get('cashout_amount', 0)
        prnt('BET_OLIMP: get coupon: ' + str(coupon), 'hide')
        prnt('BET_OLIMP: get coupon cashout_allowed: ' + str(cashout_allowed))
        prnt('BET_OLIMP: get coupon amount: ' + str(cashout_amount))

        if cashout_allowed is True and cashout_amount != 0:

            req_url = olimp_url2.format("user/cashout")

            payload = {}
            payload["bet_id"] = self.reg_id
            payload["amount"] = cashout_amount
            payload["session"] = self.session_payload["session"]
            payload["lang_id"] = "0"
            payload["platforma"] = "ANDROID1"

            headers = base_headers.copy()
            headers.update(get_xtoken_bet(payload))
            headers.update({'X-XERPC': '1'})
            prnt('BET_OLIMP: sale_bet rq: ' + str(payload), 'hide')
            resp = requests_retry_session().post(
                req_url,
                headers=headers,
                data=payload,
                verify=False,
                timeout=self.timeout,
                proxies=self.proxies
            )
            prnt('BET_OLIMP: sale_bet rs: ' + str(resp.text), 'hide')
            req_time = round(resp.elapsed.total_seconds(), 2)
            check_status_with_resp(resp, True)
            res = resp.json()
            prnt('BET_OLIMP: sale_bet rs js: ' + str(res), 'hide')

            if str(res.get('error').get('err_code')) in ('406', '403'):
                if self.cnt_sale_attempt < 5:
                    prnt('BET_OLIMP.PY: error sale bet olimp: ' +
                         str(res.get('error').get('err_desc')))
                    timer_update = 4
                    prnt('BET_OLIMP.PY: wait ' + str(timer_update) + ' sec...')
                    time.sleep(timer_update)
                    self.cnt_sale_attempt = self.cnt_sale_attempt + 1
                    return self.sale_bet(self.reg_id)
                else:
                    str_err = 'BET_OLIMP.PY: error sell result: ' + str(res.get('error').get('err_desc'))
                    prnt(str_err)
                    raise LoadException(str_err)

            if str(res.get('error').get('err_code')) != str('0'):
                prnt('BET_OLIMP.PY: error sell result: ' + str(res))
                raise LoadException("BET_OLIMP.PY: response came with an error")

            if res.get('data').get('status') == 'ok':
                prnt(res.get('data').get('msg'))
        else:
            prnt('BET_OLIMP.PY: error sale bet_id ' + str(self.reg_id))
            timer_update = 5
            prnt('BET_OLIMP.PY: coupon ' + str(self.reg_id) + ' is lock, time sleep ' + str(timer_update) + ' sec...')
            time.sleep(timer_update)
            return self.sale_bet(self.reg_id)
Beispiel #17
0
    def sale_bet(self, reg_id=None):
        """Bet return by requestID"""
        if reg_id:
            self.reg_id = reg_id

        if self.reg_id:

            # step1 get from version and sell sum
            url = self.common_url.format("coupon/sell/conditions/getFromVersion")

            url = url.replace('session/', '')

            payload = self.payload_coupon_sum.copy()
            headers = self.fonbet_headers

            payload['clientId'] = self.base_payload["clientId"]
            payload['fsid'] = self.payload['fsid']
            prnt('BET_FONBET.PY - sale_bet rq 1: ' + str(payload), 'hide')
            resp = requests_retry_session().post(
                url,
                headers=headers,
                json=payload,
                verify=False,
                timeout=self.timeout
            )
            check_status_with_resp(resp)
            res = resp.json()

            if self.cnt_sale_attempt > 40:
                err_str = 'BET_FONBET.PY: error sale bet in Fonbet(coupon is lock): ' + str(res)
                prnt(err_str)
                raise LoadException(err_str)

            prnt('BET_FONBET.PY - sale_bet rs 1: ' + str(res), 'hide')
            # payload['version'] = res.get('version')

            timer_update = float(res.get('recommendedUpdateFrequency', 3))

            coupon_found = False
            for coupon in res.get('conditions'):
                if str(coupon.get('regId')) == str(self.reg_id):
                    coupon_found = True
                    self.cnt_sale_attempt = self.cnt_sale_attempt + 1
                    prnt('BET_FONBET.PY: canSell: ' + str(coupon.get('canSell', True)))
                    prnt('BET_FONBET.PY: tempBlock: ' + str(coupon.get('tempBlock', False)))
                    if coupon.get('canSell', True) is True and coupon.get('tempBlock', False) is False:
                        self.sell_sum = float(coupon.get('completeSellSum'))
                    else:
                        prnt('BET_FONBET.PY: coupon is lock, time sleep ' + str(timer_update) + ' sec...')
                        time.sleep(timer_update)
                        return self.sale_bet()
            if not coupon_found:
                err_str = 'BET_FONBET.PY: coupon regId ' + str(self.reg_id) + ' not found: ' + str(res)
                prnt(err_str)
                raise LoadException(err_str)

            if not self.sell_sum:
                prnt('BET_FONBET.PY: coupon is BAG (TODO), time sleep ' + str(timer_update) + ' sec...')
                prnt('BET_FONBET.PY: ' + str(res.get('conditions')))
                time.sleep(timer_update)
                self.cnt_sale_attempt = self.cnt_sale_attempt + 1
                return self.sale_bet()
                # raise LoadException("BET_FONBET.PY: reg_id is not found")

            # step2 get rqid for sell coupn
            url = self.common_url.format("coupon/sell/requestId")
            url = url.replace('session/', '')

            payload = self.payload_coupon_sum.copy()
            headers = self.fonbet_headers

            payload['clientId'] = self.base_payload["clientId"]
            payload['fsid'] = self.payload['fsid']
            prnt('BET_FONBET.PY - sale_bet rq 2: ' + str(payload), 'hide')
            resp = requests_retry_session().post(
                url,
                headers=headers,
                json=payload,
                verify=False,
                timeout=self.timeout,
                proxies=self.proxies
            )
            check_status_with_resp(resp)
            res = resp.json()
            prnt('BET_FONBET.PY - sale_bet rs 2: ' + str(res), 'hide')
            if res.get('result') == 'requestId':
                requestId = res.get('requestId')

            # step3 sell
            url = self.common_url.format("coupon/sell/completeSell")
            url = url.replace('session/', '')

            payload = self.payload_coupon_sell.copy()
            headers = self.fonbet_headers

            payload['regId'] = int(self.reg_id)
            payload['requestId'] = int(requestId)
            payload['sellSum'] = self.sell_sum
            payload['clientId'] = self.base_payload["clientId"]
            payload['fsid'] = self.payload['fsid']
            prnt('BET_FONBET.PY - sale_bet rq 3: ' + str(payload), 'hide')
            resp = requests_retry_session().post(
                url,
                headers=headers,
                json=payload,
                verify=False,
                timeout=self.timeout,
                proxies=self.proxies
            )
            check_status_with_resp(resp)
            res = resp.json()
            prnt('BET_FONBET.PY - sale_bet rs 3: ' + str(res), 'hide')
            result = res.get('result')

            if result == "sellDelay":
                sell_delay_sec = (float(res.get('sellDelay')) / 1000) + self.add_sleep
                prnt('BET_FONBET.PY: sell_delay: ' + str(sell_delay_sec) + ' sec...')
                time.sleep(sell_delay_sec)

            try:
                self._check_sell_result(requestId)
            except Exception as e:
                prnt('BET_FONBET.PY: error _check_sell_result: ' + str(res) + ' ' + str(e))
                self.cnt_sale_attempt = self.cnt_sale_attempt + 1
                return self.sale_bet()