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 deVIEWpara 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.