Conceptos
Montos como texto decimal
Por qué el gateway envía y recibe dinero como texto decimal (MoneyCOP), qué tipos acepta cada SDK al enviar un monto y cómo leer los montos de las respuestas sin perder precisión.
En esta página
En el contrato, todo monto es un texto decimal: el esquema
MoneyCOP ("3500000", "467009.88", "53500.00"). Nunca
un número de punto flotante.
{ "amount": "467009.88", "currency": "COP" }La razón es simple: 0.1 + 0.2 no es 0.3 en binario. Un float puede convertir 467009.88 en
467009.87999999995 en algún punto del camino (tu ORM, tu serializador JSON, una hoja de
cálculo), y en dinero un centavo de diferencia rompe una conciliación. El texto viaja exacto de
punta a punta.
Enviar montos #
Cada SDK normaliza lo que le pases al mismo texto que enviaría el SDK de Python:
| SDK | Tipos aceptados | Recomendado |
|---|---|---|
| Python | str, int, Decimal | Decimal("467009.88") o "467009.88" |
| JavaScript / TS | string, number, bigint | string para dinero que no calculaste tú |
| PHP | string, int, objetos Stringable decimales (p. ej. brick/math BigDecimal); float se acepta pero se desaconseja | string |
| .NET | Amount, con conversión implícita desde string, int, long, decimal (y double, desaconsejado) | decimal o string |
| Go | compense.Amount (constante de texto), AmountFromInt, AmountFromRat, AmountFromFloat (desaconsejado) | "467009.88" o AmountFromInt |
from decimal import Decimal
client.loans.register_payment("CRD-00123", amount=Decimal("467009.88"),
reference="REC-2026-001", channel="CASH")
client.wallet.topups.create(document="1032456789", phone_number="3001234567",
carrier="CLARO", amount=20000) # int también valeawait client.loans.registerPayment("CRD-00123", { amount: "467009.88", reference: "REC-2026-001", channel: "CASH" });
await client.wallet.topups.create({ document: "1032456789", phoneNumber: "3001234567",
carrier: "CLARO", amount: 20000 }); // number entero: seguro
$client->loans->registerPayment('CRD-00123', amount: '467009.88', reference: 'REC-2026-001', channel: 'CASH');
$client->wallet->topups->create(document: '1032456789', phoneNumber: '3001234567',
carrier: 'CLARO', amount: 20000);await client.Loans.RegisterPaymentAsync("CRD-00123", 467009.88m, "REC-2026-001", channel: "CASH");
await client.Wallet.Topups.CreateAsync("1032456789", "3001234567", "CLARO", 20000);client.Loans.RegisterPayment(ctx, "CRD-00123", &compense.LoanPaymentParams{
Amount: "467009.88", Reference: "REC-2026-001", Channel: "CASH",
})
client.Wallet.Topups.Create(ctx, &compense.TopupParams{
Document: "1032456789", PhoneNumber: "3001234567", Carrier: "CLARO",
Amount: compense.AmountFromInt(20000),
})# En JSON, el monto va entre comillas:
-d '{"amount":"467009.88","reference":"REC-2026-001","channel":"CASH"}'Leer montos #
Las respuestas también traen los montos como texto. Los modelos tipados los exponen como Money
(amount en texto + currency), por ejemplo el saldo:
from decimal import Decimal
balance = client.wallet.balance("1032456789")
available = Decimal(balance.available.amount) # nunca float(...)
print(available, balance.available.currency)const balance = await client.wallet.balance("1032456789");
console.log(balance.available.amount, balance.available.currency); // texto: úsalo con una lib decimal
$balance = $client->wallet->balance('1032456789');
echo $balance->available->amount, ' ', $balance->available->currency, PHP_EOL; // usa bcmath o brick/math
Balance balance = await client.Wallet.BalanceAsync("1032456789");
decimal available = decimal.Parse(balance.Available.Amount, CultureInfo.InvariantCulture);balance, err := client.Wallet.Balance(ctx, "1032456789")
if err != nil {
log.Fatal(err)
}
r, _ := new(big.Rat).SetString(balance.Available.Amount) // exacto
fmt.Println(r.FloatString(2), balance.Available.Currency)curl -s "https://sandbox.dev.compense.co/gw/v1/gateway/wallet/balance/?document=1032456789" \
-H "X-API-Key: $COMPENSE_API_KEY" | jq -r '.available_cash'En los cuerpos sin modelo (dict, JsonObject, array, map[string]any) los montos llegan como
el texto del motor. En Go, el SDK decodifica con json.Number, así que los números del motor
conservan sus dígitos exactos (v.(json.Number).String()).
Algunas respuestas del sandbox traen números
Unos pocos cuerpos del sandbox (simuladores, cuota monetaria) devuelven montos como número JSON
(50000.0). Escribe tu código para aceptar ambos y convertir siempre a decimal, nunca a float.
Moneda #
La moneda por defecto es COP y los montos se expresan en pesos (no en centavos). Las operaciones
de cambio de divisas (FX) llevan la moneda explícita (sell_currency,
buy_currency).