Dinheiro e precisão
A Magen Pix API usa reais com casas decimais, não centavos. Atenção: muitos PSPs trabalham em centavos, então se você está migrando ou comparando integrações, o ponto decimal aqui não é opcional.
{ "amount": 99.90 }Precisão decimal em código
Em JavaScript, 0.1 + 0.2 !== 0.3. Em Python Decimal é seguro mas float não. Em SQL, FLOAT perde precisão.
| Linguagem | Use |
|---|---|
| JavaScript | Inteiro em centavos, ou biblioteca decimal.js. |
| Python | decimal.Decimal ao calcular, float só na API. |
| Go | shopspring/decimal ou inteiro em centavos. |
| Java | BigDecimal, nunca double. |
| PHP | bcmath, ou inteiro em centavos. |
| SQL/Postgres | NUMERIC(15,2), nunca FLOAT ou REAL. |
Padrão recomendado: centavos internamente
Armazene como inteiro em centavos no seu DB e converta apenas na borda da API:
function centsToReais(cents: number): number {
return cents / 100;
}
function reaisToCents(reais: number): number {
return Math.round(reais * 100);
}
await createPixCharge({
amount: centsToReais(order.totalCents),
clientReference: `order-${order.id}`,
});
const callbackAmountCents = reaisToCents(callback.amount);
if (callbackAmountCents !== order.totalCents) {
throw new Error('Valor divergente entre callback e pedido');
}from decimal import Decimal
def cents_to_reais(cents: int) -> Decimal:
return Decimal(cents) / Decimal(100)
def reais_to_cents(reais: float | Decimal) -> int:
return int((Decimal(str(reais)) * Decimal(100)).quantize(Decimal('1')))
create_pix_charge({
'amount': float(cents_to_reais(order.total_cents)),
'clientReference': f'order-{order.id}',
})import "github.com/shopspring/decimal"
func CentsToReais(cents int64) decimal.Decimal {
return decimal.NewFromInt(cents).Div(decimal.NewFromInt(100))
}
func ReaisToCents(reais decimal.Decimal) int64 {
return reais.Mul(decimal.NewFromInt(100)).Round(0).IntPart()
}<?php
function centsToReais(int $cents): float {
return $cents / 100;
}
function reaisToCents(float $reais): int {
return (int) round($reais * 100);
}
createPixCharge([
'amount' => centsToReais($order->totalCents),
'clientReference' => 'order-' . $order->id,
]);
$callbackAmountCents = reaisToCents($callback['amount']);
if ($callbackAmountCents !== $order->totalCents) {
throw new RuntimeException('Valor divergente entre callback e pedido');
}Limites mínimos por operação
A Magen valida no servidor. Pedido abaixo do mínimo retorna 400 Bad Request.
| Operação | amount mínimo |
|---|---|
POST /pix (cobrança) | R$ 1,00 |
POST /withdraw (saque por chave) | R$ 0,01 |
POST /withdraw/qrcode (pagar QR) | R$ 0,10 |
POST /internal-transfer | R$ 0,01 |
Tarifa
A tarifa cobrada na Magen chega no callback no campo serviceFeeCharged (em reais).
{
"amount": 99.90,
"serviceFeeCharged": 0.99,
"status": "COMPLETED"
}Para conciliação financeira, considere:
| Valor | Significado |
|---|---|
amount | O que o cliente pagou ou você sacou. |
serviceFeeCharged | Tarifa Magen sobre a operação. |
| Líquido | amount - serviceFeeCharged (recebimento) ou amount + serviceFeeCharged (saída total). |
Validar valor recebido no callback
Sempre confira que o callback bate com o pedido. Cliente pode pagar valor diferente (Pix permite QR sem valor fixo em alguns casos).
async function handleDepositCallback(tx: magenCallback, order: Order) {
const callbackCents = reaisToCents(tx.amount);
if (callbackCents !== order.totalCents) {
log.warn('Valor divergente', {
pedido: order.totalCents,
recebido: callbackCents,
});
await flagForReview(order, tx);
return;
}
await markOrderPaid(order, tx);
}Armadilhas comuns
| Armadilha | Sintoma |
|---|---|
Enviar amount: 9990 achando que é centavos | Cobra R$ 9.990,00 do cliente |
Armazenar amount como FLOAT no Postgres | Perda de centavos em soma de muitas linhas |
Somar Decimal com float em Python | Erro de tipo ou precisão perdida |
Confiar em parseFloat(tx.amount) sem arredondar | 99.90 vira 99.9000000000001 |
| Não verificar valor recebido vs valor esperado | Pagamento parcial passa como concluído |
Paginação
Endpoints de listagem (transações, callbacks, infrações) usam paginação clássica por page + limit com flag hasNextPage. Para janelas grandes prefira o relatório assíncrono em CSV.
Segurança
Token Bearer é a única credencial da Magen. Trate como senha. Esta página cobre armazenamento, rotação, mascaramento em log, proteção do webhook por IP e validação DICT antes de pagar.