Compare commits

..

1 Commits

Author SHA1 Message Date
hueso
4da1d1233c return pixTimestamp as padded bytes32
fixes signature bug
2025-07-04 12:53:04 -03:00
3 changed files with 34 additions and 59 deletions

View File

@@ -1,16 +0,0 @@
PRIVATE_KEY=0x....
CLIENT_ID=
CLIENT_SECRET=
DEV_APP_KEY=
DEBUG=false
ITP_TOKEN_URL = https://oauth.hm.bb.com.br/oauth/token
# Url de produção com autenticação mTLS.
#ITP_API_URL="https://api-bbpay.bb.com.br/checkout/v2"
# Url de homologação com autenticação mTLS.
ITP_API_URL = "https://api-bbpay.hm.bb.com.br/checkout/v2"
# Url de homologação sem autenticação mTLS.
#ITP_API_URL = "https://api.extranet.hm.bb.com.br/checkout/v2"
# 05/08/2025
#ITP_API_URL=https://checkout.mtls.api.bb.com.br
#ITP_API_URL=https://checkout.mtls.api.hm.bb.com.br

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
.env
*.pem
venv

View File

@@ -15,12 +15,9 @@ from eth_utils import to_wei
# Load environment variables from .env file # Load environment variables from .env file
load_dotenv() load_dotenv()
ENVIRONMENT = getenv('ENVIRONMENT', 'dev')
dotenv_path = f'.env.{ENVIRONMENT}'
load_dotenv(dotenv_path)
app = Flask(__name__) app = Flask(__name__)
CORS(app, origins=['https://p2pix.co']) CORS(app)
api = Api(app) api = Api(app)
class BBPay(Resource): class BBPay(Resource):
@@ -30,11 +27,18 @@ class BBPay(Resource):
self.cert = 'key.pem' self.cert = 'key.pem'
self.verify_ssl = 'bb.pem' self.verify_ssl = 'bb.pem'
self.baseUrl = getenv("ITP_API_URL")
self.token_url = getenv("ITP_TOKEN_URL") # Url de homologação com autenticação mTLS.
self.baseUrl = "https://api-bbpay.hm.bb.com.br/checkout/v2"
# Url de homologação sem autenticação mTLS.
#self.baseUrl = "https://api.extranet.hm.bb.com.br/checkout/v2"
# Url de produção com autenticação mTLS.
#self.baseUrl = "https://api-bbpay.bb.com.br/checkout/v2"
self.params = { self.params = {
'numeroConvenio': getenv("BBPAY_CONVENIO"), 'numeroConvenio': 701,
'gw-dev-app-key': getenv("DEV_APP_KEY") 'gw-dev-app-key': getenv("DEV_APP_KEY")
} }
@@ -44,7 +48,7 @@ class BBPay(Resource):
'checkout.participantes-info'] 'checkout.participantes-info']
self.oauth.fetch_token( self.oauth.fetch_token(
token_url=self.token_url, token_url='https://oauth.hm.bb.com.br/oauth/token',
client_id=getenv("CLIENT_ID"), client_id=getenv("CLIENT_ID"),
client_secret=getenv("CLIENT_SECRET"), scope=self.scope) client_secret=getenv("CLIENT_SECRET"), scope=self.scope)
@@ -55,9 +59,8 @@ class BBPay(Resource):
class Register(BBPay): class Register(BBPay):
def post(self): def post(self):
data = request.get_json() data = request.get_json()
app.logger.debug(data)
body = { body = {
'numeroConvenio': getenv("BBPAY_CONVENIO"), 'numeroConvenio': 701,
'nomeParticipante': data['chainID'], 'nomeParticipante': data['chainID'],
'tipoDocumento': data['tipoDocumento'], 'tipoDocumento': data['tipoDocumento'],
'numeroDocumento': data['numeroDocumento'], 'numeroDocumento': data['numeroDocumento'],
@@ -66,29 +69,23 @@ class Register(BBPay):
'tipoConta': data['tipoConta'], 'tipoConta': data['tipoConta'],
'codigoIspb': data['codigoIspb'] # Código identificador do Sistema de Pagamentos Brasileiro. Atualmente aceitamos apenas Banco do Brasil, codigoIspb igual a 0 'codigoIspb': data['codigoIspb'] # Código identificador do Sistema de Pagamentos Brasileiro. Atualmente aceitamos apenas Banco do Brasil, codigoIspb igual a 0
} }
app.logger.debug(body)
response = self.oauth.post( response = self.oauth.post(
self.baseUrl+"/participantes", self.baseUrl+"/participantes",
params=self.params, params=self.params,
json=body, json=body,
verify=self.verify_ssl, verify=self.verify_ssl,
cert=self.cert) cert=self.cert)
if response.status_code != 201:
app.logger.debug(response._content)
return response.reason, response.status_code
return response.json() return response.json()
class Request(BBPay): class Request(BBPay):
def post(self): def post(self):
data = request.get_json() data = request.get_json()
app.logger.debug(data)
body = { body = {
"geral": { "geral": {
"numeroConvenio": getenv("BBPAY_CONVENIO"), "numeroConvenio": 701,
"pagamentoUnico": True, "pagamentoUnico": True,
"descricaoSolicitacao": "P2Pix", "descricaoSolicitacao": "P2Pix",
"valorSolicitacao": data['amount'], "valorSolicitacao": data['amount']
#"codigoConciliacaoSolicitacao": data['lockid']
}, },
# "devedor": { # "devedor": {
# "tipoDocumento": 1, # "tipoDocumento": 1,
@@ -103,29 +100,23 @@ class Request(BBPay):
"valorRepasse": 100 }] "valorRepasse": 100 }]
} }
} }
app.logger.debug(body)
response = self.oauth.post( response = self.oauth.post(
self.baseUrl+"/solicitacoes", self.baseUrl+"/solicitacoes",
params=self.params, params=self.params,
json=body, json=body,
verify=self.verify_ssl, verify=self.verify_ssl,
cert=self.cert) cert=self.cert)
app.logger.debug(response._content)
if response.status_code != 201:
return response.reason, response.status_code
return response.json() return response.json()
class Release(BBPay): class Release(BBPay):
def get(self, numeroSolicitacao): def get(self, numeroSolicitacao):
app.logger.debug(request.get_json())
response = self.oauth.get( response = self.oauth.get(
self.baseUrl+f"/solicitacoes/{numeroSolicitacao}", self.baseUrl+f"/solicitacoes/{numeroSolicitacao}",
params=self.params, params=self.params,
verify=self.verify_ssl, verify=self.verify_ssl,
cert=self.cert) cert=self.cert)
app.logger.debug(response._content)
if response.status_code != 200: if response.status_code != 200:
return response.reason, response.status_code return 'Upstream error', response.status_code
data = response.json() data = response.json()
numeroParticipante = data['repasse']['recebedores'][0]['identificadorRecebedor'] numeroParticipante = data['repasse']['recebedores'][0]['identificadorRecebedor']
pixTimestamp = encode_packed(['bytes32'],[b85decode(data['informacoesPix']['txId'])]) pixTimestamp = encode_packed(['bytes32'],[b85decode(data['informacoesPix']['txId'])])
@@ -148,9 +139,9 @@ class Release(BBPay):
return { return {
'pixTarget': f"{chainID}-{numeroParticipante}", 'pixTarget': f"{chainID}-{numeroParticipante}",
'amount': str(valorSolicitacao), 'amount': str(valorSolicitacao),
'pixTimestamp': f"0x{pixTimestamp.hex()}", 'pixTimestamp': pixTimestamp.hex(),
'signature': f"0x{signature}" 'signature': signature }
}
# (CPF, nome, conta) -> participantID # (CPF, nome, conta) -> participantID
# should be called before deposit # should be called before deposit
@@ -164,10 +155,13 @@ api.add_resource(Request, '/request')
# should be called before release # should be called before release
api.add_resource(Release, '/release/<int:numeroSolicitacao>') api.add_resource(Release, '/release/<int:numeroSolicitacao>')
if __name__ == '__main__': if __name__ == '__main__':
if getenv("DEBUG"): if getenv("DEBUG"):
disable_warnings() disable_warnings()
app.run(host='::1', debug=True, port=getenv("PORT",5000)) app.run(debug=True)
else: else:
from waitress import serve from waitress import serve
serve(app, host=getenv("HOST","::1"), port=getenv("PORT",5000)) serve(app, host=getenv("HOST","0.0.0.0"), port=getenv("PORT",5000))