MED Integration
Overview
This guide shows how to integrate the MED flow into your application. You will learn how to:
- Configure webhooks to receive MED notifications
- Query the list of MEDs in your account
- Handle each event type (creation, approval, rejection)
Before starting, read the MED overview to understand the lifecycle and concepts involved.
1. Configure MED webhooks
Register an endpoint for each MED event type you want to receive in the dashboard https://banking.fypay.me, under Settings → Webhooks. The URL must be HTTPS; each event accepts up to 3 URLs and up to 5 custom headers. See the step-by-step in Configure Webhooks.
| Event | Description |
|---|---|
med_created | Notification of a new MED received against your account. |
med_accepted | Notification of an approved MED (refund accepted — amount will be returned to payer). |
med_rejected | Notification of a rejected MED (refund denied — balance remains with beneficiary). |
We recommend configuring all three webhook types (med_created, med_accepted, med_rejected) for full visibility of the MED lifecycle.
2. Query MEDs
Use GET /api/med to list MEDs in your account with filters and pagination.
| Parameter | Type | Description |
|---|---|---|
status | string | OPEN, RECEIVED, CANCELLED, or ANALYZED (CANCELED is also accepted) |
isReconciled | boolean | true for MEDs linked to a transaction in your account |
startDate | string | Start date (ISO 8601) |
endDate | string | End date (ISO 8601) |
page | integer | Page (default: 1) |
pageSize | integer | Items per page (default: 20, maximum: 100) |
List all MEDs
curl -X GET "https://api.fypay.me/api/med" \
-H "Authorization: Bearer $TOKEN"Filter by status
curl -X GET "https://api.fypay.me/api/med?status=RECEIVED" \
-H "Authorization: Bearer $TOKEN"Filter by period
curl -X GET "https://api.fypay.me/api/med?startDate=2026-01-01T00:00:00.000Z&endDate=2026-01-31T23:59:59.999Z&page=1&pageSize=50" \
-H "Authorization: Bearer $TOKEN"Example response
{
"data": [
{
"id": 42,
"endToEnd": "E12345678202604101030abcdef123456",
"status": "RECEIVED",
"reason": "REFUND_REQUEST",
"cause": "UNAUTHORIZED_TRANSACTION",
"description": "Customer claims not to have performed the transaction",
"analysisResult": null,
"analysisDetails": null,
"requestingBank": {
"ispb": "00000000",
"name": "REQUESTING BANK S.A."
},
"contestedBank": {
"ispb": "11111111",
"name": "CONTESTED INSTITUTION S.A."
},
"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
}
}The isReconciled field indicates whether the MED was automatically linked to a local transaction in your account. When true, originalTransactionId contains the ID of the original PIX transaction.
Get MED details
Use GET /api/med/\{id\} (the numeric MED id) to get all fields, including the status history (statusHistory), the detailed original transaction, the regulatory identifier idSolicitacaoDevolucao, and the block data (blockStatus, blockAmount). If the MED does not belong to your account, the API responds 404.
curl -X GET "https://api.fypay.me/api/med/42" \
-H "Authorization: Bearer $TOKEN"3. Handle MED webhooks
Example 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':
// New MED received — notify team and/or block beneficiary operations
await notifyTeam({
message: `MED #${medId} received — cause: ${cause}`,
amount: originalTransaction?.amount,
endToEndId: originalTransaction?.endToEndId,
});
break;
case 'MedAccepted':
// Refund approved — amount will be returned to payer
await updateTransaction({
medId,
status: 'REFUNDED',
note: 'MED approved — amount returned to original payer',
});
break;
case 'MedRejected':
// Refund rejected — balance remains with beneficiary
await updateTransaction({
medId,
status: 'KEPT',
note: 'MED rejected — balance unblocked',
});
break;
}
// Always return 200 to confirm receipt
res.status(200).json({ received: true });
});Example 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} (cause: {cause})")
if event == 'MedCreated':
# New MED — alert team
notify_team(med_id, cause, data.get('originalTransaction'))
elif event == 'MedAccepted':
# Refund approved
update_transaction(med_id, 'REFUNDED')
elif event == 'MedRejected':
# Refund rejected
update_transaction(med_id, 'KEPT')
return jsonify({'received': True}), 2004. Recommended flow
┌─────────────────────────────────────────────────────────────┐
│ YOUR APPLICATION │
│ │
│ MedCreated webhook ──────▶ Alert risk team │
│ │ Mark transaction as "under MED" │
│ │ (Optional) Block beneficiary │
│ │ │
│ ▼ │
│ Query GET /api/med ──────▶ Check details and cause │
│ │ Track status │
│ │ │
│ ▼ │
│ MedAccepted webhook ─────▶ Record refund │
│ OR Update customer balance │
│ MedRejected webhook ─────▶ Unblock beneficiary │
│ Keep balance │
└─────────────────────────────────────────────────────────────┘Best Practices
Configure all 3 webhooks
Always configure med_created, med_accepted, and med_rejected for full lifecycle visibility.
Return 200 quickly
Process the webhook asynchronously. Delivery has a 10-second timeout and only 2xx responses count as success; otherwise, the system retries delivery.
Use idempotency
Use the medId + event combination as the idempotency key (the same medId appears in MedCreated and later in MedAccepted or MedRejected). The same webhook may be redelivered if delivery fails.
Monitor open MEDs
Periodically query GET /api/med?status=RECEIVED to ensure no MED is left unattended.