Paginação
Endpoints que listam recursos (/user/transactions, /user/callbacks, /user/infractions) usam paginação clássica por page + limit com flag hasNextPage.
Padrão de loop
PAGE=1
LIMIT=100
while : ; do
RESP=$(curl -s "https://api.magen.processamento.com/v1/user/transactions?dateFrom=2025-11-01&page=$PAGE&limit=$LIMIT" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json")
echo "$RESP" | jq -c '.data[]'
HAS_NEXT=$(echo "$RESP" | jq -r '.hasNextPage')
[ "$HAS_NEXT" != "true" ] && break
PAGE=$((PAGE+1))
doneasync function* iterateTransactions(filters: Record<string, string>) {
let page = 1;
const limit = 100;
while (true) {
const params = new URLSearchParams({ ...filters, page: String(page), limit: String(limit) });
const res = await fetch(`https://api.magen.processamento.com/v1/user/transactions?${params}`, {
headers: {
Authorization: `Bearer ${process.env.MAGEN_TOKEN}`,
'Content-Type': 'application/json',
},
});
const { data, hasNextPage } = await res.json();
for (const tx of data) yield tx;
if (!hasNextPage) return;
page++;
}
}
for await (const tx of iterateTransactions({ dateFrom: '2025-11-01' })) {
await process(tx);
}def iterate_transactions(**filters):
page = 1
limit = 100
while True:
res = requests.get(
'https://api.magen.processamento.com/v1/user/transactions',
params={**filters, 'page': page, 'limit': limit},
headers={
'Authorization': f'Bearer {os.environ["MAGEN_TOKEN"]}',
'Content-Type': 'application/json',
},
)
body = res.json()
for tx in body['data']:
yield tx
if not body.get('hasNextPage'):
return
page += 1func IterateTransactions(filters url.Values, fn func(tx Transaction) error) error {
page := 1
for {
filters.Set("page", strconv.Itoa(page))
filters.Set("limit", "100")
req, _ := http.NewRequest("GET",
"https://api.magen.processamento.com/v1/user/transactions?"+filters.Encode(), nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("MAGEN_TOKEN"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { return err }
var body struct {
Data []Transaction `json:"data"`
HasNextPage bool `json:"hasNextPage"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
res.Body.Close()
return err
}
res.Body.Close()
for _, tx := range body.Data {
if err := fn(tx); err != nil { return err }
}
if !body.HasNextPage { return nil }
page++
}
}Filtros disponíveis
| Filtro | Quando usar |
|---|---|
dateFrom / dateTo | Janela temporal (ISO 8601). |
clientReference | Encontra a transação correspondente ao seu pedido. |
virtualAccount | Filtro por tenant (multi-loja). |
status | CSV: COMPLETED,PENDING. Aceita múltiplos. |
type | CSV: DEPOSIT,WITHDRAW,COMMISSION. |
endToEndId | Identificador único Bacen. |
document, name | Filtros por pagador. document apenas dígitos (11 ou 14). |
amount | Filtro por valor exato. |
Limite e tamanho da página
| Item | Valor |
|---|---|
limit max | 100 por página |
| Default | 20 |
Páginas grandes demais degradam latência. Se precisa de período longo (mês, ano) ou exportar tudo, prefira o relatório assíncrono.
Quando usar relatório assíncrono em vez de paginar
| Cenário | Recomendação |
|---|---|
| Listagem em tela (dashboard) | GET /user/transactions com paginação. |
| Verificação pontual | GET /user/transactions?clientReference=order-1234. |
| Conciliação diária (< 10k transações) | GET /user/transactions paginado. |
| Conciliação mensal/anual | POST /user/report (CSV assíncrono). |
| BI/Data Warehouse | POST /user/report rodado diariamente, ingestão por ETL. |
O relatório assíncrono gera arquivo CSV com URL assinada de download. Não tem limite de linhas e roda em background. Veja o tutorial de Conciliação.
Armadilhas comuns
| Armadilha | Sintoma |
|---|---|
Pegar tudo sem dateFrom em conta com volume | Resposta lenta, possível timeout |
limit=1000 (acima do permitido) | API rejeita ou trunca |
Iterar até data.length === 0 em vez de hasNextPage | Loop infinito em página vazia da última iteração |
Página fixa (page=1 sempre) | Só lê o primeiro 100, perde o resto |
Passar document com pontuação (123.456.789-00) | Erro 400, regex aceita só dígitos |
Lidando com callbacks
Responda em menos de 5 segundos, enfileire o processamento pesado, deduplique por id + status e teste localmente com ngrok. O retry da Magen é robusto, mas só funciona se o seu handler se comportar bem.
Dinheiro e precisão
A Magen Pix API usa reais com casas decimais, não centavos. Como armazenar internamente sem perder precisão, converter na borda e respeitar os limites mínimos de cada operação.