Koywe

Detalle de Movimiento

El endpoint de Detalle de Movimiento proporciona un recibo detallado para un movimiento específico del libro mayor, perfecto para documentación de auditoría, soporte al cliente y comprobantes contables.

¿Qué es un Recibo de Movimiento?

Cada movimiento en tu estado de cuenta tiene un ledgerEntryId único. Usa este ID para obtener información detallada sobre esa transacción específica, incluyendo:

  • Saldo antes y después del movimiento
  • Detalles del comercio y cuenta
  • Referencias a órdenes o liquidaciones asociadas
  • Descripción legible

Casos de Uso

Cuándo usar Detalle de Movimiento:

  • Documentación de auditoría: Generar comprobantes de transacciones específicas
  • Soporte al cliente: Recuperar rápidamente detalles de transacciones para consultas
  • Comprobante contable: Proporcionar recibos detallados para contabilidad
  • Resolución de disputas: Documentar detalles de transacciones para disputas
  • Cumplimiento: Mantener registros detallados para requisitos regulatorios

Endpoint de API

Texto
GET /api/v1/organizations/{organizationId}/merchants/{merchantId}/accounts/{accountId}/reports/ledger-entry/{ledgerEntryId}

Parámetros de Ruta

ParámetroRequeridoDescripción
organizationIdSíID de organización
merchantIdSíID de comercio
accountIdSíID de cuenta virtual
ledgerEntryIdSíID de entrada del libro mayor (del estado de cuenta)

Ejemplo Rápido

const response = await axios.get(
  `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/137`,
  {
    headers: { 'Authorization': `Bearer ${token}` }
  }
);
 
console.log('ID de Entrada:', response.data.ledgerEntryId);
console.log('Monto:', response.data.amount, response.data.currency);
console.log('Saldo Antes:', response.data.balanceBefore);
console.log('Saldo Después:', response.data.balanceAfter);
console.log('Descripción:', response.data.description);

Entendiendo la Respuesta

JSON
{
  "ledgerEntryId": "137",
  "accountId": "acc_0031c537-2301-40ab-9153-0f7c48505350",
  "merchantId": "mrc_2e8f96ab-dbd5-45f9-b4b6-645945daf340",
  "merchantName": "Acme Corporation",
  "type": "credit",
  "amount": "1000000.00",
  "currency": "CLP",
  "postedAt": "2025-01-15T10:30:00.000Z",
  "description": "PAYIN de Juan Pérez - Transferencia bancaria recibida",
  "category": "PAYIN",
  "references": {
    "orderId": "ord_abc123",
    "settlementId": null
  },
  "balanceBefore": "4000000.00",
  "balanceAfter": "5000000.00",
  "generatedAt": "2025-01-31T12:00:00.000Z"
}

Explicación de Campos de Respuesta

CampoDescripción
ledgerEntryIdIdentificador único de esta entrada del libro mayor
merchantIdID del comercio asociado con la cuenta
merchantNameNombre del comercio legible
typecredit (aumenta saldo) o debit (disminuye saldo)
amountMonto de la transacción
currencySímbolo de moneda
postedAtMarca de tiempo cuando se registró el movimiento
descriptionDescripción legible
categoryCategoría de movimiento (PAYIN, PAYOUT, SETTLEMENT, etc.)
references.orderIdID de orden asociada (si aplica)
references.settlementIdID de liquidación asociada (si aplica)
balanceBeforeSaldo de cuenta antes de este movimiento
balanceAfterSaldo de cuenta después de este movimiento

Los campos balanceBefore y balanceAfter proporcionan prueba lista para auditoría de cómo la transacción afectó el saldo de la cuenta.


Flujo de Trabajo: Del Estado de Cuenta al Detalle

El flujo típico es primero obtener un estado de cuenta, luego obtener detalles de entradas específicas:

Dibujando diagrama…

Ejemplo Completo: Del Estado al Detalle

async function obtenerReciboTransaccion(orgId, merchantId, accountId, date, token) {
  // Paso 1: Obtener estado de cuenta para la fecha
  const statementResponse = await axios.get(
    `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-statement`,
    {
      params: {
        from: date,
        to: date
      },
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );
  
  const movements = statementResponse.data.movements;
  console.log(`Encontrados ${movements.length} movimientos en ${date}`);
  
  // Paso 2: Obtener detalles de cada movimiento
  const recibos = [];
  
  for (const movement of movements) {
    console.log(`\nObteniendo detalles para entrada ${movement.ledgerEntryId}...`);
    
    const detailResponse = await axios.get(
      `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/${movement.ledgerEntryId}`,
      {
        headers: { 'Authorization': `Bearer ${token}` }
      }
    );
    
    const recibo = detailResponse.data;
    recibos.push(recibo);
    
    // Imprimir recibo
    console.log('='.repeat(50));
    console.log('RECIBO DE TRANSACCIÓN');
    console.log('='.repeat(50));
    console.log(`ID Entrada:     ${recibo.ledgerEntryId}`);
    console.log(`Fecha:          ${recibo.postedAt}`);
    console.log(`Comercio:       ${recibo.merchantName}`);
    console.log(`Tipo:           ${recibo.type.toUpperCase()}`);
    console.log(`Categoría:      ${recibo.category}`);
    console.log(`Monto:          ${recibo.amount} ${recibo.currency}`);
    console.log('-'.repeat(50));
    console.log(`Saldo Antes:    ${recibo.balanceBefore} ${recibo.currency}`);
    console.log(`Saldo Después:  ${recibo.balanceAfter} ${recibo.currency}`);
    console.log('-'.repeat(50));
    console.log(`Descripción:    ${recibo.description}`);
    
    if (recibo.references.orderId) {
      console.log(`ID Orden:       ${recibo.references.orderId}`);
    }
    if (recibo.references.settlementId) {
      console.log(`ID Liquidación: ${recibo.references.settlementId}`);
    }
    
    console.log('='.repeat(50));
  }
  
  return recibos;
}
 
// Uso: Obtener todos los recibos del 15 de enero 2025
const recibos = await obtenerReciboTransaccion(
  'org3_xxx',
  'mrc_xxx',
  'acc_xxx',
  '2025-01-15',
  token
);

Encontrar el ID de Entrada del Libro Mayor

El ledgerEntryId está disponible en la respuesta del estado de cuenta. Así es cómo encontrar una entrada específica:

// Encontrar entrada del libro mayor por orden asociada
const statement = await getLedgerStatement(orgId, merchantId, accountId, from, to, token);
 
const targetOrderId = 'ord_abc123';
const entry = statement.movements.find(m => m.orderId === targetOrderId);
 
if (entry) {
  console.log(`Encontrada entrada ${entry.ledgerEntryId} para orden ${targetOrderId}`);
  // Ahora obtener detalles
  const recibo = await getLedgerEntryDetails(orgId, merchantId, accountId, entry.ledgerEntryId, token);
}

Manejo de Errores

Errores Comunes:

  • 404 Not Found: El ID de entrada del libro mayor no existe o no pertenece a la cuenta especificada
  • 403 Forbidden: La entrada no pertenece al comercio o permisos insuficientes
  • 401 Unauthorized: Token inválido o expirado
JavaScript
async function obtenerEntradaSegura(orgId, merchantId, accountId, entryId, token) {
  try {
    const response = await axios.get(
      `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/${entryId}`,
      {
        headers: { 'Authorization': `Bearer ${token}` }
      }
    );
    return response.data;
  } catch (error) {
    if (error.response?.status === 404) {
      console.error(`Entrada del libro mayor ${entryId} no encontrada`);
      return null;
    }
    if (error.response?.status === 403) {
      console.error(`Acceso denegado a entrada ${entryId}`);
      return null;
    }
    throw error;
  }
}

Próximos Pasos