Bs2Api
Integração com a API do Banco BS2: https://devs.bs2.com/manual/pix-clientes
TO-DO:
- Pagamentos (Transfere dinheiro para alguém)
- [x] Criar pagamento por Chave
- [x] Criar pagamento Manual
- [x] Confirmar pagamento
- [x] Consultar pagamento
- Recebimentos (Recebe dinheiro de alguém)
- [ ] Cobrança estático
- [ ] Cobrança dinâmico
- [ ] Consultar cobrança
Instalação
Adicionar no seu Gemfile:
gem 'bs2_api'
E então execute:
bundle install
Ou instale diretamente via:
gem install bs2_api
Configuração
Via variável de ambiente:
BS2_CLIENT_ID
BS2_CLIENT_SECRET
BS2_CLIENT_ENVIRONMENT # production or sandbox. Default to sandbox
ou via initializer:
Bs2Api.configure do |config|
config.client_id = 'you_bs2_client_id'
config.client_secret = 'you_bs2_client_secret'
config.env = 'sandbox' # ou production
end
Inicia ordem de Transferência PIX via: Chave
pix_key = Bs2Api::Entities::PixKey.new(
key: '[email protected]',
type: 'EMAIL'
)
# Caso ocorra algum problema na criação, um erro será lançado
# Veja abaixo (Classes de errors) quais erros que podem ser lançados
pay_key = Bs2Api::Payment::Key.new(pix_key).call
pay_key.payment.payment_id
=> "96f0b3c4-4c76-4a7a-9933-9c9f86df7490" # pagamentoId gerado no BS2
pay_key.payment.end_to_end_id
=> "E710278662021061618144401750781P" # endToEndId gerado no BS2
pay_key.payment.class
=> Bs2Api::Entities::Payment
Inicia ordem de Transferência PIX via: Manual
account = Bs2Api::Entities::Account.new(
bank_code: "218",
agency: "0993",
number: "042312",
type: "ContaCorrente" # ContaCorrente, ContaSalario ou Poupanca
)
customer = Bs2Api::Entities::Customer.new(
document: "88899988811",
type: "CPF",
name: "Rick Sanches",
business_name: "Nome fantasia" # Utilizar apenas se for type CNPJ
)
receiver_bank = Bs2Api::Entities::Bank.new(
account: account,
customer: customer
)
pay_manual = Bs2Api::Payment::Manual.new(receiver_bank).call
pay_manual.payment.payment_id
=> "96f0b3c4-4c76-4a7a-9933-9c9f86df7490" # Payment id no BS2
pay_manual.payment.end_to_end_id
=> "E710278662021061618144401750781P" # endToEndId gerado no BS2
pay_manual.payment.class
=> Bs2Api::Entities::Payment
Confirmar ordem de transferência
Após criar um Payment é necessário confirmar, nessa etapa o dinheiro é de fato transferido. Nessa etapa é necessário informar o valor que deseja ser transferido.
# Ambos modelos de criação da ordem de pagamento possuem o mesmo objeto payment
# podendo ser utilizado da mesma forma nos dois casos:
# pay_key.payment ou pay_manual.payment
payment = pay_key.payment
amount = 10.50
confirmation = Bs2Api::Payment::Confirmation.new(payment, value: amount).call
# Caso a confirmação dê problema, um erro será lançado.
raise Bs2Api::Errors::ConfirmationError
# Caso nenhum erro seja lançado significa que foi sucesso. Você pode ter certeza com
confirmation.success?
Busca informações do pagamento
payment_id = "96f0b3c4-4c76-4a7a-9933-9c9f86df7490"
payment = Bs2Api::Payment::Detail.new(payment_id).call # Payment id no BS2
payment.id
=> "96f0b3c4-4c76-4a7a-9933-9c9f86df7490"
payment.end_to_end_id
=> "E710278662021061618144401750781P" # endToEndId gerado no BS2
payment.class
=> Bs2Api::Entities::Payment
Async API
Add initial asyc BS2 API implementation.
The API allows to pass multiple request all at once. In order to do so you must:
- Create
Bs2Api::Payment::Async
- Create one or more PIX keys
- For each PIX key create
Bs2Api::Entities::AsyncRequest
passing in the PIX key, internal identifier and the value of the transaction - Add each async request to the async payment via
Bs2Api::Payment::Async#add_request
- When all requests are added call
Bs2Api::Payment::Async#call
- In the response you will get list of payments of type
Bs2Api::Entities::AsyncResponse
whose confirmation will be sent via webhook 6.1 If even one of the requests has invalid data, the response will be 400 and we won't get anything via webhook - If the response from 6 was 202 but we don't get a webhook notification we should start polling the response manually. This is done by calling
Bs2Api::Payment::Async::check_payment_status
. It has one parameter theBs2Api::Entities::AsyncResponse#request_id
.The result from this will beBs2Api::Entities::AsyncStatus
, using it you can check if the payment was rejected or confirmed.
pix_key = Bs2Api::Entities::PixKey.new(
key: '[email protected]',
type: 'EMAIL'
)
async_request = Bs2Api::Entities::AsyncRequest.new(
pix_key: pix_key,
value: 10.0,
identificator: 'payment1'
)
async_payment = Bs2Api::Payment::Async.new
async_payment.add_request(async_request)
response_list = async_payment.call
# Wait for webhook if notification does not arrive (for example for the first item)
response_status = Bs2Api::Payment::Async.check_payment_status(response_list[0].request_id)
# Check the status
if response_status.rejected?
puts response_status.rejection_description
end
Classes de erros:
# Todos erros herdam de:
Bs2Api::Errors::Base
# Errors possíveis de serem lançados
Bs2Api::Errors::BadRequest
Bs2Api::Errors::ConfirmationError
Bs2Api::Errors::InvalidCustomer
Bs2Api::Errors::InvalidPixKey
Bs2Api::Errors::MissingConfiguration
Bs2Api::Errors::ServerError
Bs2Api::Errors::Unauthorized
Observações
- Método
call
retorna o próprio objeto - Em caso de retorno diferente de sucesso na comunicação com a API do Bs2, um erro sempre será lançado.