(11) Receber pagamentos
Contas ligadas
Criar e gerir pela API as contas dos vendedores da tua plataforma: verificação, cobranças, saldo e saques.
O que é
Uma plataforma (uma bilheteira, um marketplace) cria pela API uma conta ligada para cada vendedor que vende por ela. O vendedor nunca fala connosco: a plataforma envia a verificação dele, cobra em nome dele, lê o saldo dele, pede os saques dele para a conta bancária dele, e recebe os eventos de todas as contas nos webhooks dela.
Estão desligadas por omissão. Quem as habilita é a equipa do Vibra Pay, comerciante a comerciante, com dois limites: a comissão máxima que a plataforma tira de cada pagamento, e até quanto um saque se aprova sem a equipa. Depois, o dono da plataforma confirma pelo botão do email que recebe. Sem habilitação ativa, todas as rotas abaixo dão 403 contas_ligadas_nao_habilitadas. O estado vê-se no painel, em Contas ligadas.
A plataforma responde pelos vendedores
Um estorno ou uma disputa que deixe a conta de um vendedor negativa trava os saques da própria plataforma, até essa conta voltar a zero ou mais.
Criar a conta
Com a chave da plataforma. O reference é o id do vendedor do teu lado, único por plataforma e modo, e serve para o encontrar depois com GET /v1/accounts?reference=.... Uma conta criada com uma chave de teste só existe no modo teste.
curl -s "$VIBRA_API_URL/v1/accounts" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Idempotency-Key: vendedor-4471" \
-H "Content-Type: application/json" \
-d '{
"name": "Eventos Kianda",
"legal_name": "Maria Kianda Lopes",
"email": "maria@kianda.ao",
"reference": "vendedor-4471"
}'A verificação, simplificada
Bastam dois documentos (PDF, JPEG ou PNG, até 10 MB): o documento de identificação do titular e o comprovativo do IBAN. Com os dois e a conta bancária, a verificação segue sozinha para a equipa. Em modo teste fica verificada logo.
# 1. O documento de identificação do titular
curl -s "$VIBRA_API_URL/v1/accounts/mer_.../documents" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Idempotency-Key: vendedor-4471-bi" \
-F type=identity_document -F file=@bi.pdf
# 2. O comprovativo do IBAN, que devolve doc_...
curl -s "$VIBRA_API_URL/v1/accounts/mer_.../documents" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Idempotency-Key: vendedor-4471-iban" \
-F type=bank_account_proof -F file=@comprovativo.pdf
# 3. A conta bancária, com esse comprovativo: a verificação segue sozinha
curl -s -X PUT "$VIBRA_API_URL/v1/accounts/mer_.../bank_account" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Content-Type: application/json" \
-d '{"iban": "AO06 0044 0000 6729 5030 1010 2", "holder": "Maria Kianda Lopes", "proof_document": "doc_..."}'| verification.status | Quer dizer |
|---|---|
pending | Faltam dados ou documentos: verification.missing diz quais. |
in_review | Com a equipa. Não se mexe nos documentos até à decisão. |
verified | Pode receber pagamentos em produção, e a plataforma pode pedir os saques dela. |
more_documents | A equipa pediu mais: o motivo vem em verification.reason, para mostrares ao vendedor. |
rejected | Recusada, com o motivo. Podes enviar documentos novos. |
Cada mudança chega no evento account.updated. Mudar o IBAN depois de verificado põe a conta bancária em pending_verification até a equipa a ver, e um saque nas 72 horas a seguir a uma mudança nunca se aprova sozinho.
Cobrar em nome da conta
Qualquer rota de /v1 com o cabeçalho Vibra-Account faz-se em nome da conta: a sessão, o pagamento e o estorno são dela, e o dinheiro entra no saldo dela. A tua comissão vai em platform_fee, sem o platform (és tu), até ao máximo da habilitação. Em produção, uma escrita pede a conta verificada (403 conta_por_verificar).
curl -s "$VIBRA_API_URL/v1/checkout/sessions" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Vibra-Account: mer_..." \
-H "Idempotency-Key: bilhete-90211" \
-H "Content-Type: application/json" \
-d '{
"amount": 1500000,
"currency": "AOA",
"description": "2 bilhetes, Festival da Ilha",
"platform_fee": {"amount": 150000}
}'| HTTP | erro | Quando |
|---|---|---|
| 404 | conta_nao_existe | Não é uma conta ligada da tua plataforma. |
| 403 | conta_de_outro_modo | A conta foi criada com uma chave do outro modo. |
| 403 | conta_por_verificar | Em produção, a conta ainda não está verificada. |
| 400 | vibra_account_nao_serve_aqui | O cabeçalho numa rota de /v1/accounts, onde a conta vai no caminho. |
Saldo e saques
GET /v1/accounts/{id}/balance dá o pendente, o disponível e a reserva da conta, do livro. Quando o vendedor pede um saque na tua plataforma, pedes tu por ele, para a conta bancária verificada dele. Até ao limite da habilitação, o saque aprova-se sozinho; acima, espera pela equipa.
curl -s "$VIBRA_API_URL/v1/accounts/mer_.../payouts" \
-H "Authorization: Bearer $CHAVE_DA_PLATAFORMA" \
-H "Idempotency-Key: saque-vendedor-4471-0007" \
-H "Content-Type: application/json" \
-d '{"amount": 2500000, "metadata": {"pedido_na_plataforma": "7"}}'| status | evento | Quer dizer |
|---|---|---|
pending | payout.created | Pedido, à espera da equipa (acima do limite, ou IBAN mudado há pouco). |
processing | payout.processing | Aprovado, a transferência está a ser feita. |
paid | payout.paid | Transferido para a conta do vendedor. |
failed | payout.failed | Recusado, com o motivo; o valor volta ao disponível. |
Quando dinheiro passa a disponível numa conta, chega balance.available. Todos os eventos de uma conta ligada trazem account no envelope, com o mer_ dela, e vão para os endpoints da plataforma. Um saque aprovado e pago sozinho dá os três eventos no mesmo instante, e podem chegar por qualquer ordem: guarda o status do objeto, e não o último evento que chegou.
Com os SDK
conta, err := plataforma.CreateAccount(ctx, &vibra.AccountParams{
Name: "Eventos Kianda", LegalName: "Maria Kianda Lopes", Reference: "vendedor-4471",
}, vibra.WithIdempotencyKey("vendedor-4471"))
// Cobrar em nome da conta: o cliente manda o Vibra-Account em cada pedido.
vendedor := plataforma.WithAccount(conta.ID)
sessao, err := vendedor.CreateCheckoutSession(ctx, &vibra.CheckoutSessionParams{
Amount: 1500000, Currency: "AOA", Description: "2 bilhetes, Festival da Ilha",
PlatformFee: &vibra.PlatformFee{Amount: 150000},
})
saque, err := plataforma.CreateAccountPayout(ctx, conta.ID, &vibra.PayoutParams{Amount: 2500000})const conta = await plataforma.createAccount({ name: "Eventos Kianda", legal_name: "Maria Kianda Lopes", reference: "vendedor-4471" });
const vendedor = plataforma.withAccount(conta.id);
const sessao = await vendedor.createCheckoutSession({ amount: 1500000n, currency: "AOA", description: "2 bilhetes", platform_fee: { amount: 150000n } });
const saque = await plataforma.createAccountPayout(conta.id, { amount: 2500000n });Em modo teste
Tudo funciona com dinheiro de teste: a conta fica verificada logo, e um saque aprova-se e paga-se sozinho, com os eventos todos, para ensaiares a tua integração de ponta a ponta.