Transferência de saldo do gateway para conta externa ou chave PIX

TLDR: expor uma API assíncrona para que organizações solicitem transferência do saldo Asaas para contas de outras instituições ou chaves PIX, com acompanhamento de status e webhook de conclusão.

Contexto

Organizações do checkout atreladas a um gateway — hoje o Asaas — precisam sacar valores reais do próprio saldo para outras contas ou chaves PIX, sem passar pelo painel do gateway.

Referência da API do gateway: Transferir para conta de outra instituição ou chave Pix.

Objetivos

  • Criar uma API de transferências, com autenticação por token.
  • Endpoint assíncrono: o cliente da API solicita a transferência e recebe um ID para acompanhar o status.
  • Além do CREATE, um endpoint de VIEW para consultar status e eventual erro.
  • Ao concluir ou falhar, enviar um webhook ao cliente da API com a informação.
  • No admin, uma seção “Transferências” guardando essas transações junto dos dados do gateway.
  • Arquitetura de eventos: tudo assíncrono, via jobs.

Fora de escopo

  • Na versão inicial, só PIX é suportado. TED fica para depois.

Mudanças

Modelo Transfer

belongs_to :organization.

Campo Tipo Descrição
pid string ID público
operation_type enum Tipo da transferência — PIX ou TED
organization_id references Referência para a Organization
total decimal Valor a ser transacionado
net_total decimal Valor líquido, descontada a taxa de transferência
transfer_fee decimal Valor cobrado pelo gateway
pix_address_key string Chave PIX, quando a transferência for para chave
pix_address_key_type enum CPF, CNPJ, EMAIL, PHONE, EVP
description string Descrição livre
scheduled_at datetime Data de agendamento
created_at datetime Data de criação
status enum PENDING, BANK_PROCESSING, DONE, CANCELED, FAILED
gateway string Gateway utilizado. Padrão: asaas
gateway_id string ID que identifica a transferência no gateway
fail_reason string Descrição da falha
authorized boolean Se foi autorizada via SMS (bypass no caso de API)
effective_date_at date Data em que o valor foi transferido
pix_end_to_end_id text Identificador único da transação PIX no Banco Central

API

POST /api/v1/transfers

json { "total": 1000, "pix_address_key": "fulano.sicrano@gmail.com", "pix_addressKey_type": "EMAIL", "operation_type": "PIX", "scheduled_at": "2018-01-26", "description": "Churrasco pago via Pix agendado" }

Erro 400:

json { "errors": { "total": ["Missing field", "Amount is not valid", "Has to be bigger than 0"] } }

Sucesso:

json { "pid": "transfer_8128973-123123-4356-8fd8-a1b0644b5282", "gateway": "asaas", "gateway_id": "777eb7c8-b1a2-4356-8fd8-a1b0644b5282", "operation_type": "PIX", "created_at": "2018-01-24 15:12:12", "total": 1000, "net_total": 1000, "status": "PENDING", "transfer_fee": 0, "effective_date_at": null, "pix_end_to_end_id": null, "scheduled_at": "2018-01-26 15:12:12", "authorized": true, "fail_reason": null, "transaction_receipt_url": null, "description": "Churrasco pago via Pix manual agendado" }

ActiveAdmin

Módulo de Transfers.

Como verificar

— (não registrado na spec original)

Documentação

Implementado como Api::V2::TransfersController — a spec original propunha a v1. Implementação: app/models/transfer.rb, app/controllers/api/v2/transfers_controller.rb, app/jobs/transfers/, app/listeners/transfer_listener.rb.