Estado de Cuenta
El Estado de Cuenta proporciona un extracto estilo bancario que muestra todos los movimientos que afectaron el saldo de tu cuenta virtual durante un período especificado.
¿Qué es un Estado de Cuenta?
Piénsalo como un extracto bancario para tu cuenta virtual:
- Saldo Inicial: Tu saldo al inicio del período
- Movimientos: Cada débito y crédito que ocurrió
- Saldo Actualizado: Saldo después de cada movimiento
- Saldo Final: Tu saldo al final del período
Dibujando diagrama…
Conceptos Clave
Tipos de Movimiento
| Tipo | Descripción | Efecto en Saldo |
|---|---|---|
| credit | Fondos agregados a la cuenta | Aumenta saldo |
| debit | Fondos removidos de la cuenta | Disminuye saldo |
Categorías de Movimiento
| Categoría | Descripción |
|---|---|
PAYIN | Pago de cliente recibido |
PAYOUT | Pago a proveedor enviado |
BALANCE_TRANSFER | Cambio de divisa entre cuentas |
SETTLEMENT | Retiro automático a banco |
ADJUSTMENT | Corrección manual de saldo |
FEE | Comisión por servicio |
TAX | Retención de impuesto |
ONRAMP | Fiat usado para comprar crypto |
OFFRAMP | Crypto vendido por fiat |
REVERSE | Reversión de transacción |
OTHER | Otros tipos de movimiento |
Endpoint de API
Texto
GET /api/v1/organizations/{organizationId}/merchants/{merchantId}/accounts/{accountId}/reports/ledger-statementParámetros de Ruta
| Parámetro | Requerido | Descripción |
|---|---|---|
organizationId | Sí | ID de organización |
merchantId | Sí | ID de comercio |
accountId | Sí | ID de cuenta virtual |
Parámetros de Query
| Parámetro | Requerido | Default | Descripción |
|---|---|---|---|
from | Sí | - | Fecha inicio (YYYY-MM-DD) |
to | Sí | - | Fecha fin (YYYY-MM-DD) |
granularity | No | daily | Corte de fecha: daily o monthly |
cursor | No | - | Cursor de paginación de respuesta anterior |
limit | No | 50 | Items por página (1-100) |
Ejemplo Rápido
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-statement`,
{
params: {
from: '2025-01-01',
to: '2025-01-31'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Saldo Inicial:', response.data.openingBalance);
console.log('Saldo Final:', response.data.closingBalance);
console.log('Movimientos:', response.data.movements.length);response = requests.get(
f'https://api.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/accounts/{account_id}/reports/ledger-statement',
params={
'from': '2025-01-01',
'to': '2025-01-31'
},
headers={'Authorization': f'Bearer {token}'}
)
data = response.json()
print(f"Saldo Inicial: {data['openingBalance']}")
print(f"Saldo Final: {data['closingBalance']}")
print(f"Movimientos: {len(data['movements'])}")curl -X GET 'https://api.koywe.com/api/v1/organizations/org3_xxx/merchants/mrc_xxx/accounts/acc_xxx/reports/ledger-statement?from=2025-01-01&to=2025-01-31' \
-H 'Authorization: Bearer TU_TOKEN'Entendiendo la Respuesta
JSON
{
"accountId": "acc_0031c537-2301-40ab-9153-0f7c48505350",
"currency": "CLP",
"merchantId": "mrc_2e8f96ab-dbd5-45f9-b4b6-645945daf340",
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-01-31T23:59:59.999Z",
"openingBalance": "4000000.00",
"closingBalance": "5500000.00",
"movements": [
{
"ledgerEntryId": "137",
"postedAt": "2025-01-15T10:30:00.000Z",
"type": "credit",
"amount": "1000000.00",
"currency": "CLP",
"runningBalance": "5000000.00",
"description": "PAYIN de Juan Pérez - Transferencia bancaria recibida",
"orderId": "ord_abc123",
"category": "PAYIN"
},
{
"ledgerEntryId": "142",
"postedAt": "2025-01-20T14:15:00.000Z",
"type": "debit",
"amount": "500000.00",
"currency": "CLP",
"runningBalance": "4500000.00",
"description": "PAYOUT a Proveedor SA - Pago de factura",
"orderId": "ord_def456",
"category": "PAYOUT"
}
],
"pagination": {
"cursor": "eyJpZCI6IjE0MiIsImRhdGUiOiIyMDI1LTAxLTIwVDE0OjE1OjAwLjAwMFoifQ==",
"hasMore": true,
"limit": 50
},
"generatedAt": "2025-01-31T12:00:00.000Z"
}Campos de Respuesta
| Campo | Descripción |
|---|---|
openingBalance | Saldo al inicio del período |
closingBalance | Saldo al final del período |
movements[] | Array de movimientos individuales |
movements[].ledgerEntryId | ID único (usar para recibo detallado) |
movements[].runningBalance | Saldo después de este movimiento |
movements[].type | credit o debit |
movements[].category | Categoría de movimiento (PAYIN, PAYOUT, etc.) |
pagination.cursor | Usar para siguiente página |
pagination.hasMore | Si existen más páginas |
Paginación
El estado de cuenta usa paginación basada en cursor. Para obtener todos los movimientos:
async function obtenerTodosLosMovimientos(orgId, merchantId, accountId, from, to, token) {
const todosLosMovimientos = [];
let cursor = null;
do {
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-statement`,
{
params: {
from,
to,
limit: 100,
...(cursor && { cursor })
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
const data = response.data;
todosLosMovimientos.push(...data.movements);
cursor = data.pagination.hasMore ? data.pagination.cursor : null;
console.log(`Obtenidos ${data.movements.length} movimientos, total: ${todosLosMovimientos.length}`);
} while (cursor);
return todosLosMovimientos;
}
// Uso
const movimientos = await obtenerTodosLosMovimientos(orgId, merchantId, accountId, '2025-01-01', '2025-01-31', token);
console.log('Total movimientos:', movimientos.length);def obtener_todos_los_movimientos(org_id, merchant_id, account_id, from_date, to_date, token):
todos_los_movimientos = []
cursor = None
while True:
params = {
'from': from_date,
'to': to_date,
'limit': 100
}
if cursor:
params['cursor'] = cursor
response = requests.get(
f'https://api.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/accounts/{account_id}/reports/ledger-statement',
params=params,
headers={'Authorization': f'Bearer {token}'}
)
data = response.json()
todos_los_movimientos.extend(data['movements'])
print(f"Obtenidos {len(data['movements'])} movimientos, total: {len(todos_los_movimientos)}")
if not data['pagination']['hasMore']:
break
cursor = data['pagination']['cursor']
return todos_los_movimientos
# Uso
movimientos = obtener_todos_los_movimientos(org_id, merchant_id, account_id, '2025-01-01', '2025-01-31', token)
print(f'Total movimientos: {len(movimientos)}')Opciones de Granularidad
El parámetro granularity controla cómo se aplican los límites de fecha:
| Granularidad | Inicio del Período | Fin del Período |
|---|---|---|
daily | Inicio del día (00:00:00) | Fin del día (23:59:59) |
monthly | Primer día del mes | Último día del mes |
Usa granularidad monthly para reportes de conciliación de fin de mes para asegurar límites de período consistentes.
Ejemplo de Integración Completa
JavaScript
async function generarEstadoMensual(orgId, merchantId, accountId, year, month, token) {
// Calcular rango de fechas del mes
const from = `${year}-${String(month).padStart(2, '0')}-01`;
const lastDay = new Date(year, month, 0).getDate();
const to = `${year}-${String(month).padStart(2, '0')}-${lastDay}`;
console.log(`Generando estado de cuenta para ${from} a ${to}`);
// Obtener primera página
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-statement`,
{
params: {
from,
to,
granularity: 'monthly',
limit: 100
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
const statement = response.data;
// Resumen
console.log('='.repeat(50));
console.log('ESTADO DE CUENTA MENSUAL');
console.log('='.repeat(50));
console.log(`Cuenta: ${statement.accountId}`);
console.log(`Moneda: ${statement.currency}`);
console.log(`Período: ${statement.periodStart} a ${statement.periodEnd}`);
console.log('-'.repeat(50));
console.log(`Saldo Inicial: ${statement.openingBalance}`);
console.log(`Saldo Final: ${statement.closingBalance}`);
console.log('-'.repeat(50));
// Calcular totales
let totalCreditos = 0;
let totalDebitos = 0;
statement.movements.forEach(m => {
const amount = parseFloat(m.amount);
if (m.type === 'credit') {
totalCreditos += amount;
} else {
totalDebitos += amount;
}
console.log(`${m.postedAt} | ${m.type.toUpperCase().padEnd(6)} | ${m.amount.padStart(15)} | ${m.category} | ${m.description.substring(0, 30)}`);
});
console.log('-'.repeat(50));
console.log(`Total Créditos: ${totalCreditos.toFixed(2)}`);
console.log(`Total Débitos: ${totalDebitos.toFixed(2)}`);
console.log(`Cambio Neto: ${(totalCreditos - totalDebitos).toFixed(2)}`);
console.log('='.repeat(50));
return statement;
}
// Uso: Generar estado de enero 2025
const statement = await generarEstadoMensual(
'org3_xxx',
'mrc_xxx',
'acc_xxx',
2025,
1,
token
);