Reporte de Órdenes
Reporte de órdenes a nivel de transacción
Reporte de Órdenes
El Reporte de Órdenes proporciona una vista a nivel de transacción de todas las órdenes asociadas con una cuenta virtual, con filtros potentes y estadísticas de resumen.
¿Qué es el Reporte de Órdenes?
Mientras el Estado de Cuenta muestra movimientos de saldo, el Reporte de Órdenes muestra las órdenes/transacciones subyacentes que causaron esos movimientos.
| Estado de Cuenta | Reporte de Órdenes |
|---|---|
| Enfocado en saldos | Enfocado en transacciones |
| Muestra débitos/créditos | Muestra detalles de orden |
| Saldo actualizado | Seguimiento de estado |
| Para conciliación | Para análisis de transacciones |
Conceptos Clave
Tipos de Orden
| Tipo | Descripción |
|---|---|
PAYIN | Pago de cliente recibido |
PAYOUT | Pago a proveedor enviado |
ONRAMP | Fiat convertido a crypto |
OFFRAMP | Crypto convertido a fiat |
BALANCE_TRANSFER | Cambio de divisa entre cuentas |
PAYMENT_LINK | Pago vía link de pago |
Estados de Orden
| Estado | Descripción |
|---|---|
DRAFT | Orden creada pero no enviada |
PENDING | Esperando pago o procesamiento |
PAID | Pago recibido, procesando |
PROCESSING | Siendo procesada |
COMPLETED | Completada exitosamente |
FAILED | Falló al completar |
CANCELLED | Cancelada por usuario o sistema |
REFUNDED | Pago reembolsado |
REFUND_REQUESTED | Reembolso en progreso |
EXPIRED | Orden expirada |
ON_HOLD | Temporalmente retenida |
Endpoint de API
GET /api/v1/organizations/{organizationId}/merchants/{merchantId}/accounts/{accountId}/reports/orders
Pará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) |
type | No | - | Filtrar por tipo de orden |
status | No | - | Filtrar por estado de orden |
cursor | No | - | Cursor de paginación |
limit | No | 50 | Items por página (1-100) |
Ejemplo Rápido
1 const response = await axios.get( 2 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 3 { 4 params: { 5 from: '2025-01-01', 6 to: '2025-01-31' 7 }, 8 headers: { 'Authorization': `Bearer ${token}` } 9 } 10 ); 11 12 console.log('Total Órdenes:', response.data.summary.totalOrders); 13 console.log('Por Tipo:', response.data.summary.byType); 14 console.log('Por Estado:', response.data.summary.byStatus);
Filtrar por Tipo
Obtener solo tipos específicos de órdenes:
1 // Obtener solo órdenes PAYIN 2 const payinOrders = await axios.get( 3 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 4 { 5 params: { 6 from: '2025-01-01', 7 to: '2025-01-31', 8 type: 'PAYIN' 9 }, 10 headers: { 'Authorization': `Bearer ${token}` } 11 } 12 ); 13 14 console.log('Órdenes PAYIN:', payinOrders.data.orders.length); 15 16 // Obtener solo órdenes PAYOUT 17 const payoutOrders = await axios.get( 18 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 19 { 20 params: { 21 from: '2025-01-01', 22 to: '2025-01-31', 23 type: 'PAYOUT' 24 }, 25 headers: { 'Authorization': `Bearer ${token}` } 26 } 27 ); 28 29 console.log('Órdenes PAYOUT:', payoutOrders.data.orders.length);
Filtrar por Estado
Obtener órdenes con estados específicos:
1 // Obtener solo órdenes completadas 2 const completedOrders = await axios.get( 3 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 4 { 5 params: { 6 from: '2025-01-01', 7 to: '2025-01-31', 8 status: 'COMPLETED' 9 }, 10 headers: { 'Authorization': `Bearer ${token}` } 11 } 12 ); 13 14 console.log('Órdenes completadas:', completedOrders.data.orders.length); 15 16 // Obtener órdenes fallidas para investigación 17 const failedOrders = await axios.get( 18 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 19 { 20 params: { 21 from: '2025-01-01', 22 to: '2025-01-31', 23 status: 'FAILED' 24 }, 25 headers: { 'Authorization': `Bearer ${token}` } 26 } 27 ); 28 29 console.log('Órdenes fallidas a investigar:', failedOrders.data.orders.length);
Entendiendo la Respuesta
1 { 2 "accountId": "acc_0031c537-2301-40ab-9153-0f7c48505350", 3 "currency": "CLP", 4 "periodStart": "2025-01-01T00:00:00.000Z", 5 "periodEnd": "2025-01-31T23:59:59.999Z", 6 "orders": [ 7 { 8 "orderId": "ord_abc123", 9 "type": "PAYIN", 10 "status": "COMPLETED", 11 "amountIn": "1000000.00", 12 "amountOut": "1000000.00", 13 "originCurrency": "CLP", 14 "destinationCurrency": "CLP", 15 "counterparty": { 16 "name": "Juan Pérez", 17 "identifier": "12345678-9" 18 }, 19 "createdAt": "2025-01-15T10:30:00.000Z", 20 "completedAt": "2025-01-15T10:35:00.000Z", 21 "externalId": "FAC-2025-001" 22 }, 23 { 24 "orderId": "ord_def456", 25 "type": "PAYOUT", 26 "status": "COMPLETED", 27 "amountIn": "500000.00", 28 "amountOut": "500000.00", 29 "originCurrency": "CLP", 30 "destinationCurrency": "CLP", 31 "counterparty": { 32 "name": "Proveedor SA", 33 "identifier": "98765432-1" 34 }, 35 "createdAt": "2025-01-20T14:00:00.000Z", 36 "completedAt": "2025-01-20T14:15:00.000Z", 37 "externalId": "OC-2025-042" 38 } 39 ], 40 "summary": { 41 "totalOrders": 150, 42 "byType": { 43 "PAYIN": 100, 44 "PAYOUT": 50 45 }, 46 "byStatus": { 47 "COMPLETED": 140, 48 "PENDING": 5, 49 "FAILED": 5 50 } 51 }, 52 "pagination": { 53 "cursor": "eyJvcmRlcklkIjoib3JkX2RlZjQ1NiJ9", 54 "hasMore": true, 55 "limit": 50 56 }, 57 "generatedAt": "2025-01-31T12:00:00.000Z" 58 }
Campos de Respuesta
| Campo | Descripción |
|---|---|
orders[] | Array de objetos de orden |
orders[].orderId | ID único de orden |
orders[].counterparty | Información de contacto/pagador |
orders[].externalId | Tu ID de referencia (si se proporcionó) |
summary.totalOrders | Total de órdenes en el período |
summary.byType | Desglose por tipo de orden |
summary.byStatus | Desglose por estado |
Entendiendo el Resumen
El objeto summary proporciona estadísticas agregadas para análisis rápido:
Node.js
1 const response = await axios.get( 2 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 3 { 4 params: { from: '2025-01-01', to: '2025-01-31' }, 5 headers: { 'Authorization': `Bearer ${token}` } 6 } 7 ); 8 9 const { summary } = response.data; 10 11 // Análisis de volumen 12 console.log('=== Volumen Mensual ==='); 13 console.log(`Total Órdenes: ${summary.totalOrders}`); 14 15 // Por tipo 16 console.log('\n=== Por Tipo ==='); 17 Object.entries(summary.byType).forEach(([type, count]) => { 18 console.log(`${type}: ${count} órdenes`); 19 }); 20 21 // Por estado 22 console.log('\n=== Por Estado ==='); 23 Object.entries(summary.byStatus).forEach(([status, count]) => { 24 const percentage = ((count / summary.totalOrders) * 100).toFixed(1); 25 console.log(`${status}: ${count} (${percentage}%)`); 26 }); 27 28 // Tasa de éxito 29 const completed = summary.byStatus.COMPLETED || 0; 30 const failed = summary.byStatus.FAILED || 0; 31 const successRate = (completed / (completed + failed) * 100).toFixed(1); 32 console.log(`\nTasa de Éxito: ${successRate}%`);
Tip de Conciliación
Relacionar Órdenes con Movimientos del Libro Mayor: Cada movimiento del libro mayor incluye un campo orderId. Usa esto para hacer referencias cruzadas entre el Reporte de Órdenes y el Estado de Cuenta.
1 // Obtener estado de cuenta 2 const ledger = await getLedgerStatement(orgId, merchantId, accountId, from, to, token); 3 4 // Obtener reporte de órdenes 5 const orders = await getOrdersReport(orgId, merchantId, accountId, from, to, token); 6 7 // Referencia cruzada 8 ledger.movements.forEach(movement => { 9 if (movement.orderId) { 10 const order = orders.orders.find(o => o.orderId === movement.orderId); 11 if (order) { 12 console.log(`Movimiento ${movement.ledgerEntryId} coincide con Orden ${order.orderId} (${order.type})`); 13 } 14 } 15 });
Ejemplo de Integración Completa
Node.js
1 async function generarAnalisisDeOrdenes(orgId, merchantId, accountId, from, to, token) { 2 // Obtener todas las órdenes (manejando paginación) 3 const todasLasOrdenes = []; 4 let cursor = null; 5 let summary = null; 6 7 do { 8 const response = await axios.get( 9 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`, 10 { 11 params: { 12 from, 13 to, 14 limit: 100, 15 ...(cursor && { cursor }) 16 }, 17 headers: { 'Authorization': `Bearer ${token}` } 18 } 19 ); 20 21 todasLasOrdenes.push(...response.data.orders); 22 summary = response.data.summary; 23 cursor = response.data.pagination.hasMore ? response.data.pagination.cursor : null; 24 25 } while (cursor); 26 27 // Generar análisis 28 console.log('='.repeat(60)); 29 console.log('REPORTE DE ANÁLISIS DE ÓRDENES'); 30 console.log(`Período: ${from} a ${to}`); 31 console.log('='.repeat(60)); 32 33 // Estadísticas de resumen 34 console.log('\n📊 RESUMEN'); 35 console.log(`Total Órdenes: ${summary.totalOrders}`); 36 37 // Desglose por tipo 38 console.log('\n📈 POR TIPO'); 39 Object.entries(summary.byType).forEach(([type, count]) => { 40 const pct = ((count / summary.totalOrders) * 100).toFixed(1); 41 console.log(` ${type.padEnd(20)} ${String(count).padStart(5)} (${pct}%)`); 42 }); 43 44 // Desglose por estado 45 console.log('\n📋 POR ESTADO'); 46 Object.entries(summary.byStatus).forEach(([status, count]) => { 47 const pct = ((count / summary.totalOrders) * 100).toFixed(1); 48 console.log(` ${status.padEnd(20)} ${String(count).padStart(5)} (${pct}%)`); 49 }); 50 51 // Calcular totales por tipo 52 console.log('\n💰 VOLUMEN POR TIPO'); 53 const volumenPorTipo = {}; 54 todasLasOrdenes.forEach(order => { 55 if (!volumenPorTipo[order.type]) { 56 volumenPorTipo[order.type] = 0; 57 } 58 volumenPorTipo[order.type] += parseFloat(order.amountIn); 59 }); 60 61 Object.entries(volumenPorTipo).forEach(([type, volume]) => { 62 console.log(` ${type.padEnd(20)} ${volume.toLocaleString()}`); 63 }); 64 65 // Detalle de órdenes fallidas 66 const ordenesFallidas = todasLasOrdenes.filter(o => o.status === 'FAILED'); 67 if (ordenesFallidas.length > 0) { 68 console.log('\n⚠️ ÓRDENES FALLIDAS'); 69 ordenesFallidas.forEach(order => { 70 console.log(` ${order.orderId} | ${order.type} | ${order.amountIn} | ${order.createdAt}`); 71 }); 72 } 73 74 console.log('\n' + '='.repeat(60)); 75 76 return { orders: todasLasOrdenes, summary }; 77 } 78 79 // Uso 80 const analisis = await generarAnalisisDeOrdenes( 81 'org3_xxx', 82 'mrc_xxx', 83 'acc_xxx', 84 '2025-01-01', 85 '2025-01-31', 86 token 87 );