Integração MED
Visão Geral
Este guia mostra como integrar o fluxo de MED na sua aplicação. Você vai aprender a:
- Configurar webhooks para receber notificações de MED
- Consultar a lista de MEDs da sua conta
- Tratar cada tipo de evento (criação, aprovação, rejeição)
Antes de começar, leia a visão geral do MED para entender o ciclo de vida e os conceitos envolvidos.
1. Configurar webhooks de MED
Configure um endpoint para cada tipo de evento MED que deseja receber. Use o endpoint POST /api/webhooks:
Notificação de novo MED recebido contra a sua conta.
curl -X POST https://api.avista.global/api/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.suaempresa.com/webhooks/med-created",
"eventType": "med_created",
"headers": [
{ "key": "Authorization", "value": "Bearer seu-token-secreto" }
]
}'Notificação de MED aprovado (devolução aceita — valor será devolvido ao pagador).
curl -X POST https://api.avista.global/api/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.suaempresa.com/webhooks/med-accepted",
"eventType": "med_accepted"
}'Notificação de MED rejeitado (devolução negada — saldo permanece com o beneficiário).
curl -X POST https://api.avista.global/api/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.suaempresa.com/webhooks/med-rejected",
"eventType": "med_rejected"
}'Recomendamos configurar os três tipos de webhook (med_created, med_accepted, med_rejected) para ter visibilidade completa do ciclo de vida do MED.
2. Consultar MEDs
Use GET /api/med para listar os MEDs da sua conta com filtros e paginação.
Listar todos os MEDs
curl -X GET "https://api.avista.global/api/med" \
-H "Authorization: Bearer $TOKEN"Filtrar por status
curl -X GET "https://api.avista.global/api/med?status=RECEIVED" \
-H "Authorization: Bearer $TOKEN"Filtrar por período
curl -X GET "https://api.avista.global/api/med?startDate=2026-01-01T00:00:00.000Z&endDate=2026-01-31T23:59:59.999Z&page=1&pageSize=50" \
-H "Authorization: Bearer $TOKEN"Exemplo de resposta
{
"data": [
{
"id": 42,
"endToEnd": "E12345678202604101030abcdef123456",
"status": "RECEIVED",
"reason": "REFUND_REQUEST",
"cause": "UNAUTHORIZED_TRANSACTION",
"description": "Cliente alega não ter realizado a transação",
"analysisResult": null,
"analysisDetails": null,
"requestingBank": {
"ispb": "00000000",
"name": "BCO DO BRASIL S.A."
},
"contestedBank": {
"ispb": "13140088",
"name": "ACESSO SOLUÇÕES DE PAGAMENTO"
},
"originalTransaction": {
"amount": 1500.00,
"type": "PIX",
"transactionType": "CASH_IN",
"name": "João da Silva",
"document": "***456789**",
"dateTime": "2026-04-05T14:30:00.000Z"
},
"isReconciled": true,
"originalTransactionId": 78432,
"createdAt": "2026-04-10T10:00:00.000Z",
"updatedAt": "2026-04-10T10:00:00.000Z"
}
],
"metadata": {
"total": 1,
"page": 1,
"pageSize": 20,
"totalPages": 1
}
}O campo isReconciled indica se o MED foi automaticamente vinculado a uma transação local da sua conta. Quando true, o campo originalTransactionId contém o ID da transação PIX original.
3. Tratar webhooks de MED
Exemplo de handler (Node.js)
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhooks/med', async (req, res) => {
const { event, medId, status, cause, originalTransaction } = req.body;
console.log(`MED ${medId}: ${event} (status: ${status})`);
switch (event) {
case 'MedCreated':
// Novo MED recebido — notificar equipe e/ou bloquear operações do beneficiário
await notifyTeam({
message: `MED #${medId} recebido — causa: ${cause}`,
amount: originalTransaction?.amount,
endToEndId: originalTransaction?.endToEndId,
});
break;
case 'MedAccepted':
// Devolução aprovada — o valor será devolvido ao pagador
await updateTransaction({
medId,
status: 'DEVOLVIDO',
note: 'MED aprovado — valor devolvido ao pagador original',
});
break;
case 'MedRejected':
// Devolução rejeitada — saldo permanece com o beneficiário
await updateTransaction({
medId,
status: 'MANTIDO',
note: 'MED rejeitado — saldo desbloqueado',
});
break;
}
// Sempre retorne 200 para confirmar recebimento
res.status(200).json({ received: true });
});Exemplo de handler (Python)
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhooks/med', methods=['POST'])
def handle_med_webhook():
data = request.json
event = data.get('event')
med_id = data.get('medId')
cause = data.get('cause')
print(f"MED {med_id}: {event} (causa: {cause})")
if event == 'MedCreated':
# Novo MED — alertar equipe
notify_team(med_id, cause, data.get('originalTransaction'))
elif event == 'MedAccepted':
# Devolução aprovada
update_transaction(med_id, 'DEVOLVIDO')
elif event == 'MedRejected':
# Devolução rejeitada
update_transaction(med_id, 'MANTIDO')
return jsonify({'received': True}), 2004. Fluxo recomendado
┌─────────────────────────────────────────────────────────────┐
│ SUA APLICAÇÃO │
│ │
│ Webhook MedCreated ──────▶ Alertar equipe de risco │
│ │ Marcar transação como "em MED" │
│ │ (Opcional) Bloquear beneficiário │
│ │ │
│ ▼ │
│ Consultar GET /api/med ──▶ Verificar detalhes e causa │
│ │ Acompanhar status │
│ │ │
│ ▼ │
│ Webhook MedAccepted ─────▶ Registrar devolução │
│ OU Atualizar saldo do cliente │
│ Webhook MedRejected ─────▶ Desbloquear beneficiário │
│ Manter saldo │
└─────────────────────────────────────────────────────────────┘Boas Práticas
Configure os 3 webhooks
Sempre configure med_created, med_accepted e med_rejected para ter visibilidade completa do ciclo de vida.
Retorne 200 rapidamente
Processe o webhook de forma assíncrona. Se o handler demorar mais de 5 segundos, o sistema tentará reenviar.
Use idempotência
Use o campo medId como chave de idempotência. O mesmo webhook pode ser reenviado em caso de falha de entrega.
Monitore MEDs abertos
Consulte periodicamente GET /api/med?status=RECEIVED para garantir que nenhum MED ficou sem tratamento.