saveinmed/saveinmed-bff/docs/mercadopago_split_frontend.md
Tiago Yamamoto b39caf0fd0 first commit
2025-12-17 13:58:26 -03:00

94 lines
4.1 KiB
Markdown

# Integração Frontend - Split de Pagamentos (Mercado Pago)
Este guia descreve como o frontend deve consumir os novos endpoints do BFF para criar preferências de pagamento com **split** no Mercado Pago, permitindo distribuir automaticamente os valores entre múltiplos recebedores.
## Visão Geral
O fluxo de split utiliza a rota pública do BFF para criar uma preferência com regras de repasse. O frontend obtém a `init_point` (ou `sandbox_init_point`) e redireciona o usuário para o checkout do Mercado Pago. Após o pagamento, o Mercado Pago se encarrega de transferir os valores conforme as regras de split enviadas.
### Endpoint principal
```
POST /mercadopago/split/preference
```
- **Autenticação**: não requer token (mesma política do endpoint público atual de preferência).
- **Objetivo**: criar uma preferência com o campo `transfers` configurado.
- **Resposta**: `201 Created` com payload `MercadoPagoPreferenceResponse` contendo `id`, `init_point`, `sandbox_init_point` e demais metadados.
## Payload esperado
```json
{
"purpose": "wallet_purchase",
"external_reference": "pedido-123",
"notification_url": "https://bff.saveinmed.com.br/mercadopago/webhook",
"items": [
{
"id": "consulta-xyz",
"title": "Consulta de especialidade",
"quantity": 1,
"unit_price": 120.0,
"currency_id": "BRL"
}
],
"payer": {
"email": "paciente@example.com",
"name": "Paciente",
"surname": "Teste"
},
"back_urls": {
"success": "https://app.saveinmed.com.br/pagamentos/sucesso",
"failure": "https://app.saveinmed.com.br/pagamentos/erro",
"pending": "https://app.saveinmed.com.br/pagamentos/pendente"
},
"transfers": [
{
"collector_id": 11223344,
"amount": 20.0,
"description": "Comissão da clínica"
},
{
"collector_id": 99887766,
"percentage": 50.0,
"description": "Participação do especialista"
}
],
"marketplace_fee": 5.0,
"metadata": {
"pedidoId": "123",
"tipo": "consulta"
}
}
```
### Campos importantes
- `purpose`: deve permanecer como `wallet_purchase` (o backend já força este valor por padrão).
- `transfers`: lista com as regras de split.
- Cada item aceita **apenas um** dos campos `amount` (valor absoluto) ou `percentage` (percentual do total), além do `collector_id` do recebedor.
- `marketplace_fee` (opcional): taxa em reais destinada ao marketplace SaveinMed.
- `metadata` (opcional): dados auxiliares que serão devolvidos nos webhooks.
## Fluxo recomendado no frontend
1. **Montagem do payload**: coletar os itens, dados do pagador e regras de split (definidas conforme negócio) e montar o corpo seguindo o formato acima.
2. **Chamada HTTP**: enviar `POST` para `/mercadopago/split/preference` com `Content-Type: application/json`.
3. **Tratamento de resposta**:
- Em caso de sucesso (`201`), redirecionar o usuário para `init_point` (produção) ou `sandbox_init_point` (sandbox).
- Em caso de erro (`400`), exibir feedback ao usuário com base na mensagem `detail` retornada.
4. **Monitoramento**: os webhooks continuarão chegando na rota `/mercadopago/webhook`. Utilize `external_reference`/`metadata` para reconciliar o pagamento no frontend após confirmação.
## Validações aplicadas pelo backend
- Ao menos uma regra em `transfers` é obrigatória.
- Cada regra precisa de `collector_id` e **exatamente um** entre `amount` ou `percentage`.
- O backend adiciona expiração padrão de 24 horas e garante `purpose = wallet_purchase`.
## Considerações adicionais
- Para ambiente de sandbox, utilize contas de teste do Mercado Pago e confira se o `collector_id` corresponde aos usuários secundários habilitados para split.
- Guarde o `id` da preferência para possíveis consultas posteriores (`GET /mercadopago/payment/{payment_id}` após webhook).
- Ajuste as URLs de redirecionamento (`back_urls`) conforme fluxo de UX desejado.
Qualquer dúvida adicional sobre os campos suportados pode ser sanada consultando a [documentação oficial do Mercado Pago - Split de Pagamentos](https://www.mercadopago.com.br/developers/pt/docs/marketplace/split-payouts/introduction).