├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── README.rst ├── docs ├── ContaDigital.rst └── Recebimentos.rst ├── pjbank ├── __init__.py ├── api.py ├── config.py ├── contadigital │ ├── __init__.py │ ├── consultas.py │ ├── credenciamento.py │ ├── subcontas.py │ └── transacoes.py ├── modelos.json └── recebimentos │ ├── __init__.py │ ├── boleto.py │ └── cartaocredito.py ├── setup.py └── tests ├── ContaDigitalTest.py ├── __init__.py ├── context.py ├── dados.py └── test_recebimentos.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | pjbank.egg-info 3 | pjbank.egg-info/* 4 | .vscode 5 | .vscode/* 6 | __pycache__ 7 | */__pycache__/* 8 | build 9 | build/* 10 | dist 11 | dist/* 12 | .pytest* 13 | .pytest*/* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.3" 4 | - "3.5" 5 | - "3.6" 6 | - "3.6-dev" # 3.6 development branch 7 | - "3.7-dev" # 3.7 development branch 8 | # command to install dependencies 9 | # install: 10 | # - pip install -r requirements.txt 11 | # command to run tests 12 | script: 13 | - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then python -m unittest discover; fi 14 | - if [[ $TRAVIS_PYTHON_VERSION == '3.4' ]]; then python -m unittest discover; fi 15 | # - pytest # or py.test for Python versions 3.5 and below -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Python Packaging Authority (PyPA) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Include the license file 2 | include LICENSE.txt 3 | 4 | # Include the data files 5 | recursive-include data * 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pjbank-python-sdk 2 | PJbank SDK para Python! :snake: :snake: :snake: 3 | 4 | [![Build Status](https://travis-ci.org/pjbank/pjbank-python-sdk.svg?branch=master)](http://travis-ci.org/pjbank/pjbank-python-sdk) 5 | 6 | Consulte a [documentação da API PJBank](http://docs.pjbank.com.br) para mais informações. 7 | 8 | # Instalação 9 | 10 | ``` 11 | pip install pjbank 12 | ``` 13 | 14 | # Quickstart 15 | 16 | ``` 17 | import pjbank 18 | 19 | conta_boleto = pjbank.Boleto() 20 | 21 | #modo de desenvolvimento 22 | conta_boleto.dev(True) 23 | 24 | conta_boleto.credenciar(dados_empresa) 25 | 26 | conta_boleto.emitir(dados_boleto) 27 | ``` 28 | 29 | 30 | ![Construcao](https://openclipart.org/image/2400px/svg_to_png/231626/underconstruction.png) 31 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | PJBank Python SDK 2 | ======================= 3 | 4 | PJbank SDK para Python! :snake: :snake: :snake: 5 | ---- 6 | -------------------------------------------------------------------------------- /docs/ContaDigital.rst: -------------------------------------------------------------------------------- 1 | Conta Digital PJBank 2 | ================================ 3 | 4 | Realizar o credenciamento 5 | ---- 6 | 7 | 8 | Documentação 9 | ---- 10 | 11 | 12 | Administradores 13 | ---- 14 | 15 | 16 | Subcontas 17 | ---- 18 | 19 | 20 | Transações 21 | ---- 22 | 23 | -------------------------------------------------------------------------------- /docs/Recebimentos.rst: -------------------------------------------------------------------------------- 1 | Recebimento PJBank 2 | ======================= 3 | 4 | Receber por Boleto Bancário 5 | ---- 6 | 7 | 8 | Receber por Cartão de Crédito 9 | ---- 10 | 11 | Consultar Extratos 12 | ---- -------------------------------------------------------------------------------- /pjbank/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | pjbank 6 | """ 7 | from pjbank.api import PJBankAPI 8 | from pjbank.contadigital import ContaDigital 9 | from pjbank.recebimentos.boleto import Boleto 10 | from pjbank.recebimentos.cartaocredito import CartaoCredito 11 | from pjbank.config import __version__ 12 | 13 | conta_digital = ContaDigital() 14 | boleto = Boleto() 15 | cartao = CartaoCredito() -------------------------------------------------------------------------------- /pjbank/api.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import requests 5 | from pjbank.config import __apiurls__ as apiurls 6 | 7 | class PJBankAPI(object): 8 | """Classe representando a API PJBank.""" 9 | 10 | def __init__(self, credencial=None, chave=None, modo="sandbox"): 11 | self._modo = modo 12 | self._url = apiurls.get(self._modo) 13 | self._endpoint_base = '' 14 | self._credencial = credencial 15 | self._chave = chave 16 | self._chave_headers = "X-CHAVE-CONTA" 17 | self._content_type = "application/json" 18 | 19 | @property 20 | def credencial(self): 21 | return self._credencial 22 | 23 | @credencial.setter 24 | def credencial(self, credencial): 25 | self._credencial = credencial 26 | 27 | @property 28 | def chave(self): 29 | return self._chave 30 | 31 | @chave.setter 32 | def chave(self, chave): 33 | self._chave = chave 34 | 35 | @property 36 | def modo(self): 37 | return self._modo 38 | 39 | def dev(self, dev=True): 40 | if type(dev) == str and dev == 'producao': 41 | dev = False 42 | if dev == True: 43 | self._modo = 'sandbox' 44 | elif dev == False: 45 | self._modo = 'producao' 46 | self._url = apiurls.get(self._modo) 47 | return self.modo 48 | 49 | @property 50 | def headers_chave(self): 51 | return {self._chave_headers: self.chave} 52 | 53 | @property 54 | def headers_content(self): 55 | return {"Content-Type": self._content_type} 56 | 57 | def _get_endpoint(self, recursos=None): 58 | base = [self._url, self._endpoint_base] 59 | if self.credencial: 60 | base.extend([self.credencial]) 61 | if recursos: 62 | base.extend(recursos) 63 | url = '/'.join(base) 64 | return url 65 | 66 | def _request(self, metodo, endpoint, headers, dados=None, params=None): 67 | url = self._get_endpoint(endpoint) 68 | response = requests.request(metodo, url, json=dados, headers=headers, params=params) 69 | return response 70 | 71 | def _get(self, endpoint, headers, params=None): 72 | return self._request("GET", endpoint, headers, params) 73 | 74 | def _post(self, endpoint, headers, dados, params=None): 75 | return self._request("POST", endpoint, headers, dados, params) 76 | 77 | def _put(self, endpoint, headers, dados, params=None): 78 | return self._request("PUT", endpoint, headers, dados, params) 79 | 80 | def _delete(self, endpoint, headers, dados=None, params=None): 81 | return self._request("DELETE", endpoint, headers, dados, params) 82 | 83 | def _consulta(self, endpoint=None): 84 | headers = self.headers_chave 85 | response = self._get(endpoint, headers) 86 | return response.json() 87 | 88 | def credenciar(self, dados_empresa): 89 | headers = self.headers_content 90 | response = self._post(None, headers, dados_empresa) 91 | info = response.json() 92 | if self.credencial or self.chave: 93 | raise Exception("Esta conta já está credenciada.".encode("utf-8")) 94 | if not response.ok: 95 | raise Exception(response.text) 96 | self.credencial = info['credencial'] 97 | self.chave = info['chave'] 98 | self.resposta_credenciamento = info 99 | return info 100 | 101 | -------------------------------------------------------------------------------- /pjbank/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __version__ = "0.9dev4" 4 | __packagename__ = "pjbank" 5 | __pypi_packagename__ = "pjbank" 6 | __apiurls__ = { 7 | "producao": "https://api.pjbank.com.br", 8 | "sandbox": "https://sandbox.pjbank.com.br" 9 | } 10 | -------------------------------------------------------------------------------- /pjbank/contadigital/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.api import PJBankAPI 5 | from pjbank.recebimentos.boleto import Boleto 6 | from pjbank.recebimentos.cartaocredito import CartaoCredito 7 | 8 | class ContaDigital(PJBankAPI): 9 | """docstring for ContaDigital.""" 10 | def __init__(self, credencial=None, chave=None, webhook_chave=None): 11 | super(ContaDigital, self).__init__(credencial, chave) 12 | self._endpoint_base = "contadigital" 13 | self._webhook_chave = webhook_chave 14 | self._recebimentos() 15 | 16 | def _recebimentos(self): 17 | self.boleto = Boleto(self.credencial, self.chave) 18 | self.boleto._endpoint_base = "contadigital/recebimentos" 19 | self.boleto._chave_headers = "X-CHAVE-CONTA" 20 | 21 | self.cartao = CartaoCredito(self.credencial, self.chave) 22 | self.cartao._endpoint_base = "contadigital/recebimentos" 23 | self.cartao._chave_headers = "X-CHAVE-CONTA" 24 | 25 | def automatico(f): 26 | def wrapper(self, *args, **kwargs): 27 | if 'c' in kwargs.keys(): 28 | self.credencial = kwargs['c'] 29 | kwargs.pop('c') 30 | if 'ch' in kwargs.keys(): 31 | self.chave = kwargs['ch'] 32 | kwargs.pop('ch') 33 | return f(self, *args, **kwargs) 34 | return wrapper 35 | 36 | @property 37 | def webhook_chave(self): 38 | return self._webhook_chave 39 | 40 | @webhook_chave.setter 41 | def webhook_chave(self, chave): 42 | self._webhook_chave = chave 43 | 44 | def credenciar(self, dados): 45 | super(ContaDigital, self).credenciar(dados) 46 | self.webhook_chave = self.resposta_credenciamento['webhook_chave'] 47 | return self -------------------------------------------------------------------------------- /pjbank/contadigital/consultas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.contadigital import ContaDigital 5 | 6 | class Consultas(ContaDigital): 7 | """docstring for Consultas.""" 8 | def __init__(self): 9 | super().__init__() 10 | 11 | @automatico 12 | def dados_conta(self): 13 | return self._consulta() 14 | @automatico 15 | def documentos(self): 16 | return self._consulta(['documentos']) 17 | 18 | @automatico 19 | def status_socio(self, email): 20 | return self._consulta(['administradores', email]) 21 | 22 | @automatico 23 | def administradores(self): 24 | return self._consulta(['administradores']) -------------------------------------------------------------------------------- /pjbank/contadigital/credenciamento.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.contadigital import ContaDigital 5 | 6 | class Credenciamento(ContaDigital): 7 | """docstring for Credenciamento.""" 8 | def __init__(self): 9 | super(Credenciamento, self).__init__() 10 | 11 | def documentos(self, dados): 12 | pass 13 | 14 | def adicionar_saldo(self, dados): 15 | headers = self.headers_chave 16 | headers.update(self.headers_content) 17 | response = self._post(None, headers, dados) 18 | return response.json() 19 | 20 | def webhook(self, dados): 21 | headers = self.headers_chave 22 | headers.update(self.headers_content) 23 | response = self._put(None, headers, dados) 24 | return response.json() 25 | 26 | def novo_administrador(self, dados): 27 | headers = self.headers_chave 28 | response = self._post(['administradores'], headers, dados) 29 | return response.json() 30 | 31 | def excluir_administrador(self, email): 32 | headers = self.headers_chave 33 | response = self._delete(['administradores', email], headers) 34 | return response.json() -------------------------------------------------------------------------------- /pjbank/contadigital/subcontas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.contadigital import ContaDigital 5 | 6 | class SubContas(ContaDigital): 7 | """docstring for SubContas.""" 8 | def __init__(self): 9 | super(SubContas, self).__init__() 10 | 11 | def novo_cartao(self, dados): 12 | headers = self.headers_chave 13 | headers.update(self.headers_content) 14 | response = self._post(['subcontas'], headers, dados) 15 | return response.json() 16 | 17 | def subconta(self, subconta): 18 | headers = self.headers_chave 19 | headers.update(self.headers_content) 20 | response = self._get(['subcontas', subconta], headers) 21 | return response.json() 22 | 23 | def adicionar_saldo(self, subconta, dados): 24 | headers = self.headers_chave 25 | headers.update(self.headers_content) 26 | response = self._post(['subcontas', subconta], headers, dados) 27 | return response.json() 28 | 29 | def extrato(self, dados): 30 | headers = self.headers_chave 31 | headers.update(self.headers_content) 32 | response = self._post(['subcontas'], headers, dados) 33 | return response.json() 34 | -------------------------------------------------------------------------------- /pjbank/contadigital/transacoes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.contadigital import ContaDigital 5 | 6 | class Transacoes(ContaDigital): 7 | """docstring for Transacoes.""" 8 | def __init__(self): 9 | super().__init__() 10 | 11 | -------------------------------------------------------------------------------- /pjbank/modelos.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Recebimentos": { 4 | "Boleto": { 5 | "credenciar": { 6 | "nome_empresa": "", 7 | "conta_repasse": "", 8 | "agencia_repasse": "", 9 | "banco_repasse": "", 10 | "cnpj": "", 11 | "ddd": "", 12 | "telefone": "", 13 | "email": "" 14 | }, 15 | "emitir": { 16 | "vencimento": "12/30/2019", 17 | "valor": 50.75, 18 | "juros": 0, 19 | "multa": 0, 20 | "desconto": "", 21 | "nome_cliente": "Cliente de Exemplo", 22 | "cpf_cliente": "62936576000112", 23 | "endereco_cliente": "Rua Joaquim Vilac", 24 | "numero_cliente": "509", 25 | "complemento_cliente": "", 26 | "bairro_cliente": "Vila Teixeira", 27 | "cidade_cliente": "Campinas", 28 | "estado_cliente": "SP", 29 | "cep_cliente": "13301510", 30 | "logo_url": "http://wallpapercave.com/wp/xK64fR4.jpg", 31 | "texto": "Exemplo de emissão de boleto", 32 | "grupo": "Boletos", 33 | "pedido_numero": "2342" 34 | }, 35 | "imprimir": { 36 | "pedido_numero": ["2342", "2343"] 37 | } 38 | }, 39 | "CartaoCredito": { 40 | "credenciar": { 41 | "nome_empresa": "", 42 | "conta_repasse": "", 43 | "agencia_repasse": "", 44 | "banco_repasse": "", 45 | "cnpj": "", 46 | "ddd": "", 47 | "telefone": "", 48 | "email": "" 49 | } 50 | } 51 | }, 52 | "ContaDigital": { 53 | "credenciar": { 54 | "nome_empresa": "", 55 | "cnpj": "", 56 | "cep": "", 57 | "endereco": "", 58 | "numero": "", 59 | "bairro": "", 60 | "complemento": "", 61 | "cidade": "", 62 | "estado": "", 63 | "ddd": "", 64 | "telefone": "", 65 | "email": "" 66 | }, 67 | "administradores": {}, 68 | "credenciamento": {}, 69 | "subcontas": {}, 70 | "transacoes": {}, 71 | "recebimentos": {} 72 | } 73 | } 74 | ] -------------------------------------------------------------------------------- /pjbank/recebimentos/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.api import PJBankAPI 5 | 6 | class Recebimentos(PJBankAPI): 7 | """docstring for Recebimentos.""" 8 | def __init__(self, credencial=None, chave=None): 9 | super(Recebimentos, self).__init__(credencial, chave) 10 | self._endpoint_base = "recebimentos" 11 | self._chave_headers = "X-CHAVE" 12 | 13 | def extrato(self, pago=None, data_inicio=None, data_fim=None, pagina=None): 14 | params = {} 15 | if pago: 16 | params.update({"pago":pago}) 17 | if data_inicio: 18 | params.update({"data_inicio":data_inicio}) 19 | if data_fim: 20 | params.update({"data_fim":data_fim}) 21 | if pagina: 22 | params.update({"pagina":pagina}) 23 | 24 | headers = self.headers_chave.update(self.headers_content) 25 | response = self._get(['transacoes'], headers, params=params) 26 | return response.text -------------------------------------------------------------------------------- /pjbank/recebimentos/boleto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.recebimentos import Recebimentos 5 | 6 | class Boleto(Recebimentos): 7 | """docstring for Boleto.""" 8 | def __init__(self, credencial=None, chave=None): 9 | super(Boleto, self).__init__(credencial, chave) 10 | 11 | def automatico(f): 12 | def wrapper(self, *args, **kwargs): 13 | if 'c' in kwargs.keys(): 14 | self.credencial = kwargs['c'] 15 | kwargs.pop('c') 16 | if 'ch' in kwargs.keys(): 17 | self.chave = kwargs['ch'] 18 | kwargs.pop('ch') 19 | return f(self, *args, **kwargs) 20 | return wrapper 21 | 22 | def credenciar(self, dados): 23 | dados.pop('cartao', None) 24 | return super(Boleto, self).credenciar(dados) 25 | 26 | @automatico 27 | def emitir(self, dados): 28 | headers = self.headers_content 29 | response = self._post(['transacoes'], headers, dados) 30 | return response 31 | 32 | @automatico 33 | def imprimir(self, ids_boletos, carne=None): 34 | headers = self.headers_content 35 | headers.update(self.headers_chave) 36 | dados = {"pedido_numero": ids_boletos} 37 | if carne: 38 | dados.update({"formato": carne}) 39 | response = self._post(['transacoes', 'lotes'], headers, dados) 40 | return response 41 | 42 | @automatico 43 | def invalidar(self, id_boleto): 44 | headers = self.headers_content 45 | headers.update(self.headers_chave) 46 | response = self._delete(['transacoes', id_boleto], headers, dados) 47 | return response 48 | 49 | @automatico 50 | def verificar_nao_liquidados(self): 51 | response = self._consulta() -------------------------------------------------------------------------------- /pjbank/recebimentos/cartaocredito.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pjbank.recebimentos import Recebimentos 5 | 6 | class CartaoCredito(Recebimentos): 7 | """docstring for CartaoCredito.""" 8 | def __init__(self, credencial=None, chave=None): 9 | super(CartaoCredito, self).__init__(credencial, chave) 10 | 11 | def automatico(f): 12 | def wrapper(self, *args, **kwargs): 13 | if 'c' in kwargs.keys(): 14 | self.credencial = kwargs['c'] 15 | kwargs.pop('c') 16 | if 'ch' in kwargs.keys(): 17 | self.chave = kwargs['ch'] 18 | kwargs.pop('ch') 19 | return f(self, *args, **kwargs) 20 | return wrapper 21 | 22 | def credenciar(self, dados): 23 | dados.update({'cartao': True}) 24 | return super(CartaoCredito, self).credenciar(dados) 25 | 26 | @automatico 27 | def tokenizar(self, dados): 28 | headers = self.headers_chave 29 | headers.update(self.headers_content) 30 | response = self._post(['tokens'], headers, dados) 31 | return response.json() 32 | 33 | @automatico 34 | def nova_transacao(self, dados): 35 | headers = self.headers_chave 36 | headers.update(self.headers_content) 37 | response = self._post(['transacoes'], headers, dados) 38 | return response.json() 39 | 40 | @automatico 41 | def cancelar(self, id_operacao): 42 | headers = self.headers_chave 43 | response = self._delete(['transacoes', id_operacao], headers) 44 | return response.json() 45 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """Setup pjbank-sdk 2 | """ 3 | 4 | # To use a consistent encoding 5 | from codecs import open 6 | from os import path 7 | # Always prefer setuptools over distutils 8 | from setuptools import setup, find_packages 9 | #configs do pacote 10 | from pjbank.config import __version__, __packagename__ 11 | 12 | HERE = path.abspath(path.dirname(__file__)) 13 | 14 | # Get the long description from the README file 15 | with open(path.join(HERE, 'README.rst'), encoding='utf-8') as f: 16 | LONG_DESCRIPTION = f.read() 17 | 18 | setup( 19 | name=__packagename__, 20 | 21 | # Versions should comply with PEP440. For a discussion on single-sourcing 22 | # the version across setup.py and the project code, see 23 | # https://packaging.python.org/en/latest/single_source_version.html 24 | version=__version__, 25 | 26 | description='PJBank Python SDK', 27 | long_description=LONG_DESCRIPTION, 28 | 29 | # The project's main homepage. 30 | url='https://github.com/pjbank/pjbank-python-sdk', 31 | download_url = 'https://github.com/pjbank/pjbank-python-sdk/archive/'+__version__+'.tar.gz', 32 | 33 | # Author details 34 | author='Raphael Mattos', 35 | author_email='raphael.mattos@pjbank.com.br', 36 | 37 | # Choose your license 38 | license='MIT', 39 | 40 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 41 | classifiers=[ 42 | # How mature is this project? Common values are 43 | # 3 - Alpha 44 | # 4 - Beta 45 | # 5 - Production/Stable 46 | 'Development Status :: 4 - Beta', 47 | 48 | # Indicate who your project is intended for 49 | 'Intended Audience :: Developers', 50 | 'Topic :: Software Development :: Build Tools', 51 | 52 | # Pick your license as you wish (should match "license" above) 53 | 'License :: OSI Approved :: MIT License', 54 | 55 | # Specify the Python versions you support here. In particular, ensure 56 | # that you indicate whether you support Python 2, Python 3 or both. 57 | 'Programming Language :: Python :: 2', 58 | 'Programming Language :: Python :: 2.7', 59 | 'Programming Language :: Python :: 3', 60 | 'Programming Language :: Python :: 3.3', 61 | 'Programming Language :: Python :: 3.4', 62 | 'Programming Language :: Python :: 3.5', 63 | 'Programming Language :: Python :: 3.6', 64 | ], 65 | 66 | # What does your project relate to? 67 | keywords='pjbank contadigital boleto cartao pagamentos recebimentos', 68 | 69 | # You can just specify the packages manually here if your project is 70 | # simple. Or you can use find_packages(). 71 | packages=find_packages(exclude=['contrib', 'docs', 'tests']), 72 | 73 | # Alternatively, if you want to distribute just a my_module.py, uncomment 74 | # this: 75 | # py_modules=["my_module"], 76 | 77 | # List run-time dependencies here. These will be installed by pip when 78 | # your project is installed. For an analysis of "install_requires" vs pip's 79 | # requirements files see: 80 | # https://packaging.python.org/en/latest/requirements.html 81 | install_requires=['requests'], 82 | 83 | # List additional groups of dependencies here (e.g. development 84 | # dependencies). You can install these using the following syntax, 85 | # for example: 86 | # $ pip install -e .[dev,test] 87 | extras_require={ 88 | 'dev': ['check-manifest'], 89 | 'test': ['coverage'], 90 | }, 91 | 92 | # If there are data files included in your packages that need to be 93 | # installed, specify them here. If using Python 2.6 or less, then these 94 | # have to be included in MANIFEST.in as well. 95 | # package_data={ 96 | # 'sample': ['package_data.dat'], 97 | # }, 98 | 99 | # Although 'package_data' is the preferred approach, in some case you may 100 | # need to place data files outside of your packages. See: 101 | # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa 102 | # In this case, 'data_file' will be installed into '/my_data' 103 | # data_files=[('my_data', ['data/data_file'])], 104 | 105 | # To provide executable scripts, use entry points in preference to the 106 | # "scripts" keyword. Entry points provide cross-platform support and allow 107 | # pip to create the appropriate form of executable for the target platform. 108 | # entry_points={ 109 | # 'console_scripts': [ 110 | # 'pjbank=pjbank:main', 111 | # ], 112 | # }, 113 | ) 114 | -------------------------------------------------------------------------------- /tests/ContaDigitalTest.py: -------------------------------------------------------------------------------- 1 | # the inclusion of the tests module is not meant to offer best practices for 2 | # testing in general, but rather to support the `find_packages` example in 3 | # setup.py that excludes installing the "tests" package 4 | 5 | 6 | def test_success(): 7 | assert True 8 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # the inclusion of the tests module is not meant to offer best practices for 2 | # testing in general, but rather to support the `find_packages` example in 3 | # setup.py that excludes installing the "tests" package 4 | 5 | import pickle 6 | import dados 7 | 8 | # with open('dados_testes.pkl', 'rb') as dump: 9 | # dados_testes = pickle.load(dump) -------------------------------------------------------------------------------- /tests/context.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 4 | 5 | import pjbank 6 | -------------------------------------------------------------------------------- /tests/dados.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | dados = { 4 | "recebimentos": { 5 | "boleto": { 6 | "credenciamento": { 7 | 'agencia_virtual': '', 8 | 'chave': '733a1fa031098bf1fe1b582fceea0ad79c555079', 9 | 'conta_virtual': '141333', 10 | 'credencial': '0be30ccbf543205790778426c8138ae11c404d15', 11 | 'msg': 'Sucesso ao credenciar', 12 | 'status': '201' 13 | }, 14 | "credenciar": { 15 | "nome_empresa": "Teste Python SDK", 16 | "conta_repasse": "99991", 17 | "agencia_repasse": "9999", 18 | "banco_repasse": "001", 19 | "cnpj": "62338615000180", 20 | "ddd": "91", 21 | "telefone": "40046830", 22 | "email": "atendimentos@pjbank.com.br" 23 | }, 24 | "emitir": { 25 | "vencimento": "12/30/2019", 26 | "valor": 50.75, 27 | "juros": 0, 28 | "multa": 0, 29 | "desconto": "", 30 | "nome_cliente": "Cliente de Exemplo", 31 | "cpf_cliente": "62936576000112", 32 | "endereco_cliente": "Rua Joaquim Vilac", 33 | "numero_cliente": "509", 34 | "complemento_cliente": "", 35 | "bairro_cliente": "Vila Teixeira", 36 | "cidade_cliente": "Campinas", 37 | "estado_cliente": "SP", 38 | "cep_cliente": "13301510", 39 | "logo_url": "https://www.python.org/static/img/python-logo.png", 40 | "texto": "Exemplo de emissão de boleto", 41 | "grupo": "Boletos" 42 | }, 43 | "imprimir": { 44 | 45 | } 46 | }, 47 | "cartao_credito": { 48 | "credenciar": { 49 | "nome_empresa": "", 50 | "conta_repasse": "", 51 | "agencia_repasse": "", 52 | "banco_repasse": "", 53 | "cnpj": "", 54 | "ddd": "", 55 | "telefone": "", 56 | "email": "" 57 | } 58 | } 59 | }, 60 | "conta_digital": { 61 | "credenciar": { 62 | "nome_empresa": "", 63 | "cnpj": "", 64 | "cep": "", 65 | "endereco": "", 66 | "numero": "", 67 | "bairro": "", 68 | "complemento": "", 69 | "cidade": "", 70 | "estado": "", 71 | "ddd": "", 72 | "telefone": "", 73 | "email": "" 74 | }, 75 | "administradores": {}, 76 | "credenciamento": {}, 77 | "subcontas": {}, 78 | "transacoes": {}, 79 | "recebimentos": {} 80 | } 81 | } -------------------------------------------------------------------------------- /tests/test_recebimentos.py: -------------------------------------------------------------------------------- 1 | # the inclusion of the tests module is not meant to offer best practices for 2 | # testing in general, but rather to support the `find_packages` example in 3 | # setup.py that excludes installing the "tests" package 4 | import unittest 5 | import pickle 6 | import datetime 7 | import random 8 | from pjbank import Boleto 9 | from dados import dados 10 | 11 | class DadosTeste(object): 12 | def __init__(self): 13 | super(DadosTeste, self).__init__() 14 | self._dados = dados 15 | 16 | @property 17 | def dados(self): 18 | return self._dados 19 | 20 | 21 | class BoletoTestCase(unittest.TestCase): 22 | def setUp(self): 23 | self.dados = DadosTeste().dados 24 | creds = self.dados['recebimentos']['boleto']['credenciamento'] 25 | self.boleto = Boleto(creds['credencial'], creds['chave']) 26 | 27 | def test_dados(self): 28 | self.assertGreaterEqual(len(self.dados), 0) 29 | self.assert_(self.boleto.credencial) 30 | self.assert_(self.boleto.chave) 31 | 32 | def emitir_boleto(self, dados, random_pedido=False): 33 | if random_pedido: 34 | dados['pedido_numero'] = random.randint(1000,99999) 35 | return self.boleto.emitir(dados) 36 | 37 | def test_emitir_boleto(self): 38 | dados_emis = self.dados['recebimentos']['boleto']['emitir'] 39 | data = (datetime.date.today()+datetime.timedelta(days=1)) 40 | dados_emis['vencimento'] = data.strftime('%m/%d/%Y') 41 | res = self.emitir_boleto(dados_emis, True) 42 | response = res.json() 43 | self.assertIn("id_unico", response) 44 | self.assertIn("nossonumero", response) 45 | self.assertIn("banco_numero", response) 46 | self.assertIn("linkBoleto", response) 47 | self.assertIn("linkGrupo", response) 48 | self.assertIn("linhaDigitavel", response) 49 | 50 | def test_editar_boleto(self): 51 | dados_emis = self.dados['recebimentos']['boleto']['emitir'] 52 | bol = self.emitir_boleto(dados_emis, True) 53 | bol.r = bol.json() 54 | self.assertEqual(bol.r['status'], '201') 55 | dados_emis['valor'] = 50.50 56 | dados_emis['pedido_numero'] = bol.r['pedido_numero'] 57 | bol2 = self.emitir_boleto(dados_emis, False) 58 | bol.r = bol.json() 59 | self.assertEqual(bol.r["linkBoleto"], bol2.r["linkBoleto"]) 60 | self.assertEqual(bol.r["linkGrupo"], bol2.r["linkGrupo"]) 61 | self.assertEqual(bol.r["linhaDigitavel"], bol2.r["linhaDigitavel"]) 62 | 63 | --------------------------------------------------------------------------------