feslima / pyinterboleto

Biblioteca para facilitar o manuseio de boletos de contas PJ no Banco Inter
GNU Lesser General Public License v3.0
6 stars 1 forks source link

Emissão de boleto: JSONDecodeError: [Errno Expecting value] #7

Open brendasalenave opened 2 years ago

brendasalenave commented 2 years ago

Olá,

Estou tentanto utilizar a biblioteca para emitir boletos de pagamento pelo banco inter. Segui os exemplos de uso mas quando tento emitir um boleto utilizando boleto.emitir(emissao) recebo como retorno o seguinte erro: JSONDecodeError: [Errno Expecting value] : 0 Já conferi o formato de todos os dados passados como parâmetros e não encontrei problema nenhum.

Poderia me ajudar a esclarecer a causa desse erro?

Obrigada

feslima commented 2 years ago

Olá @brendasalenave,

Se não for pedir muito, você poderia postar o stacktrace completo desse erro aqui? Só tenha cuidado pra não colocar informação sensitiva.

brendasalenave commented 2 years ago

Segue o erro completo:

{
    "name": "JSONDecodeError",
    "message": "[Errno Expecting value] : 0",
    "stack": "---------------------------------------------------------------------------
    JSONDecodeError                           Traceback (most recent call last)
    File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py:910, in Response.json(self, **kwargs)
        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=908'>909</a> try:
        --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=909'>910</a>     return complexjson.loads(self.text, **kwargs)
            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=910'>911</a> except JSONDecodeError as e:
            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=911'>912</a>     # Catch JSON-related errors and raise as requests.JSONDecodeError
                <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=912'>913</a>     # This aliases json.JSONDecodeError and simplejson.JSONDecodeError

        File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py?line=342'>343</a> if (cls is None and object_hook is None and
                <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py?line=343'>344</a>         parse_int is None and parse_float is None and
                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py?line=344'>345</a>         parse_constant is None and object_pairs_hook is None and not kw):
                    --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py?line=345'>346</a>     return _default_decoder.decode(s)
                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/__init__.py?line=346'>347</a> if cls is None:

                    File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=332'>333</a> \"\"\"Return the Python representation of ``s`` (a ``str`` instance
                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=333'>334</a> containing a JSON document).
                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=334'>335</a> 
                            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=335'>336</a> \"\"\"
                        --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=336'>337</a> obj, end = self.raw_decode(s, idx=_w(s, 0).end())
                            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=337'>338</a> end = _w(s, end).end()

                        File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
                            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=353'>354</a> except StopIteration as err:
                        --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=354'>355</a>     raise JSONDecodeError(\"Expecting value\", s, err.value) from None
                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/json/decoder.py?line=355'>356</a> return obj, end

                        JSONDecodeError: Expecting value: line 1 column 1 (char 0)

                        During handling of the above exception, another exception occurred:

                        JSONDecodeError                           Traceback (most recent call last)
                        c:/Users/brenda/Documents/GitHub/backend/teste_inter.py in <module>
                              <a href='file://c:/Users/brenda/Documents/GitHub/backend/teste_inter.py?line=57'>58</a> # %%
                              ----> <a href='file://c:/Users/brenda/Documents/GitHub/backend/teste_inter.py?line=58'>59</a> result = boleto.emitir(emissao)
                                    <a href='file://c:/Users/brenda/Documents/GitHub/backend/teste_inter.py?line=59'>60</a> print(result)

                              File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py:138, in Boleto.emitir(self, dados)
                                  <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py?line=134'>135</a> if not self.pode_emitir:
                                  <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py?line=135'>136</a>     raise ValueError(\"Este boleto j\u00e1 foi emitido.\")
                                  --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py?line=137'>138</a> result = emitir_boleto(dados, self.configs)
                                      <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py?line=138'>139</a> self._emitido = True
                            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/boleto.py?line=139'>140</a> self._numero = result['nossoNumero']

                            File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py:246, in emitir_boleto(dados, configs)
                                <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=236'>237</a> headers = {
                                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=237'>238</a>     'content-type': 'application/json',
                            <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=238'>239</a>     'x-inter-conta-corrente': acc
                                <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=239'>240</a> }
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=241'>242</a> response = post(API_URL, data=dados.to_json(),
                                <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=242'>243</a>                 headers=headers,
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=243'>244</a>                 cert=(certificate, key))
                                    --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=245'>246</a> contents = check_response(response, \"Boleto n\u00e3o foi emitido\")
                                        <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=247'>248</a> result = BoletoResponse(**contents)
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/emissao/emissor.py?line=248'>249</a> return result

                                    File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py:37, in check_response(response, additional_message)
                                         <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py?line=34'>35</a> def check_response(response: Response,
                                         <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py?line=35'>36</a>                    additional_message: Optional[str] = None) -> dict:
                                ---> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py?line=36'>37</a>     contents = response.json()
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py?line=37'>38</a>     print(f'Contents{contents}')
                                         <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/pyinterboleto/utils/sanitize.py?line=38'>39</a>     if response.status_code != 200:

                                File c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py:917, in Response.json(self, **kwargs)
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=914'>915</a>     raise RequestsJSONDecodeError(e.message)
                                    <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=915'>916</a> else:
                                --> <a href='file://c:/Users/brenda/AppData/Local/Programs/Python/Python39/lib/site-packages/requests/models.py?line=916'>917</a>     raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

                                JSONDecodeError: [Errno Expecting value] : 0"
}

Obrigada pelo auxílio @feslima (:

MichelBueno2 commented 2 years ago

Olá, estou passando pelo mesmo problema.

O que me parece é que a estrutura dos certificados do Inter mudou. Eu tenho dois certificados, um antigo que vence hoje e um recém criado. Quando eu testo o código utilizando o certificado antigo não ocorre nenhum erro. No entanto, quando eu uso o certificado recém criado da esse mesmo erro citado.

Olhando no banco inter é possível ver que algumas coisas mudaram:

Data de Criação 20/10/2021

Permissões: Consulta dos status e geração de PDF dos boletos emitidos; Emissão e baixa manual dos boletos emitidos

Data de Criação: 19/08/2022

Permissões: Consulta de boletos e exportação para PDF; Emissão e cancelamento de boletos

feslima commented 2 years ago

Ah @MichelBueno2, obrigado pela info.

Infelizmente eu não tenho mais as credenciais de acesso à documentação do Inter. Eles ainda restringem a documentação?

Nesse caso, se quiser e puder, fique à vontade pra abrir um PR, ou se puder salvar e me mandar a documentação nova, quando eu tiver tempo eu posso implementar.

MichelBueno2 commented 2 years ago

@feslima Desde já agradeço sua disponibilidade, vou tentar viabilizar tudo que encontrar e vou tentar ajustar o código. Só deixo claro que sou ligeiramente iniciante na utilização de APIs, então toda ajuda vai ser fundamental para mim haha.

De fato, infelizmente a documentação do inter é fachada. Mas aqui está uma print de uma parte que acredito ser importante:

https://i.imgur.com/0Tl3Lcl.png

A API saiu da V1 para a V2

Aqui temos uma print do código atual contendo uma url da V1:

https://i.imgur.com/4K6SXo6.png

Bom, eu tentei alterar a URL antiga para a recente (V2), mas deu um erro (Motivo: 'Token inválido.'), não sei se errei em alguma coisa.

Recentemente teve uma discussão do fórum do banco inter relativo a mudança das versões:

https://i.imgur.com/xqoQtAt.png https://i.imgur.com/1swlNaP.png

feslima commented 2 years ago

@MichelBueno2 sabe dizer se o Inter proíbe a distribuição dessa documentação?

MichelBueno2 commented 2 years ago

@feslima, descobri que qualquer um pode criar uma conta, não necessariamente precisa ter conta no Banco.

Basta entrar aqui https://developers.bancointer.com.br

Na verdade nem precisa de conta para ler a documentação, acredito que o acesso é somente para quem quer abrir um chamado no suporte.

feslima commented 2 years ago

@MichelBueno2 valeu. Quando eu escrevi a v1 dessa lib eu só tinha acesso se tivesse conta no Inter.

Vou olhar o que mudou

MichelBueno2 commented 2 years ago

Olá, @feslima conseguiu encontrar algum caminho para a solução? Precisa de ajuda em algo?

feslima commented 2 years ago

Opa @MichelBueno2, eu achei uma solução sim, o problema é que não tive tempo de implementar. E também tem o problema do teste que não tenho mais acesso ao gerenciador de credenciais do inter.

Na nova documentação, pelo o que vi, não mudou muita coisa. O que acontece agora é, ao invés de postar o certificado em toda requisição, um token deve ser gerado fazendo uma requisição inicial ao endpoint de autenticação deles. Daí, com esse token setado em toda requisição, você pode fazer as operações de antes.

Acontece que eu tô muito sem tempo esses dias. Peço desculpas pelo vácuo a você e a @brendasalenave. Quando eu tiver uma folga e implementar essa mudanças, eu vou precisar de ajuda com os testes manuais.

MichelBueno2 commented 1 year ago

Claro, @feslima, pode contar comigo para os testes!

brendasalenave commented 1 year ago

Tranquilo! Fico a disposição também para ajudar (:

feslima commented 1 year ago

@brendasalenave e @MichelBueno2, mais uma vez peço desculpas pela demora.

Seguinte, eu modifiquei o fluxo de autenticação de acordo com a documentação do Inter. Mas não cheguei verificar se houve mudanças dos dados que são precisos nas operações de boletos em si.

Eu subi essas modificações pra branch dev nesse commit aqui e318a11.

Eu não consigo testar contra a API real. Vocês poderiam for favor, fazer o checkout da branch dev nesse commit que mencionei?

Pra rodar localmente vocês precisam ter o poetry instalado. Daí, depois que fizer o checkout, só rodar poetry install pra criar o ambiente virtual, instalar as dependências e o pacote como um todo.

Daí, para testar se essa modificação que fiz funciona, façam uma consulta/operação seguindo a nova API (eu documentei nos exemplos das funções da classe boleto).

Dando tudo certo, eu publico a nova versão desse pacote no PyPi o quanto antes.

Vocês precisam criar uma aplicação na interface do Inter de vocês seguindo esses passos. Mais especificamente, passos 7 e 8 vocês conseguem os arquivos de certificado/chave e o client_id e client_secret, respectivamente.

brendasalenave commented 1 year ago

Tranquilo! Fico a disposição também para ajudar


De: Felipe Lima @.> Enviado: quinta-feira, 15 de setembro de 2022 19:53 Para: feslima/pyinterboleto @.> Cc: Brenda @.>; Mention @.> Assunto: Re: [feslima/pyinterboleto] Emissão de boleto: JSONDecodeError: [Errno Expecting value] (Issue #7)

Opa @MichelBueno2https://github.com/MichelBueno2, eu achei uma solução sim, o problema é que não tive tempo de implementar. E também tem o problema do teste que não tenho mais acesso ao gerenciador de credenciais do inter.

Na nova documentação, pelo o que vi, não mudou muita coisa. O que acontece agora é, ao invés de postar o certificado em toda requisição, um token deve ser gerado fazendo uma requisição inicial ao endpoint de autenticação deles. Daí, com esse token setado em toda requisição, você pode fazer as operações de antes.

Acontece que eu tô muito sem tempo esses dias. Peço desculpas pelo vácuo a você e a @brendasalenavehttps://github.com/brendasalenave. Quando eu tiver uma folga e implementar essa mudanças, eu vou precisar de ajuda com os testes manuais.

— Reply to this email directly, view it on GitHubhttps://github.com/feslima/pyinterboleto/issues/7#issuecomment-1248721007, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACMEBL35DSDSTXJWLG7L26LV6OSGNANCNFSM56ZY7OFQ. You are receiving this because you were mentioned.Message ID: @.***>

feslima commented 1 year ago

@brendasalenave e @MichelBueno2 eu consegui ajuda com as credenciais pra testar as mudanças porém não testei todas as funcionalidades novas.

De qualquer forma, publiquei uma release nova do pacote que em teoria se integra com a API v2 do Inter.

Por favor, quando puderem, testem e me dêem um feedback.