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
Texto
GET /api/v1/organizations/{organizationId}/merchants/{merchantId}/accounts/{accountId}/reports/ordersPará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
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from: '2025-01-01',
to: '2025-01-31'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Total Órdenes:', response.data.summary.totalOrders);
console.log('Por Tipo:', response.data.summary.byType);
console.log('Por Estado:', response.data.summary.byStatus);response = requests.get(
f'https://api.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/accounts/{account_id}/reports/orders',
params={
'from': '2025-01-01',
'to': '2025-01-31'
},
headers={'Authorization': f'Bearer {token}'}
)
data = response.json()
print(f"Total Órdenes: {data['summary']['totalOrders']}")
print(f"Por Tipo: {data['summary']['byType']}")
print(f"Por Estado: {data['summary']['byStatus']}")curl -X GET 'https://api.koywe.com/api/v1/organizations/org3_xxx/merchants/mrc_xxx/accounts/acc_xxx/reports/orders?from=2025-01-01&to=2025-01-31' \
-H 'Authorization: Bearer TU_TOKEN'Filtrar por Tipo
Obtener solo tipos específicos de órdenes:
// Obtener solo órdenes PAYIN
const payinOrders = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from: '2025-01-01',
to: '2025-01-31',
type: 'PAYIN'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Órdenes PAYIN:', payinOrders.data.orders.length);
// Obtener solo órdenes PAYOUT
const payoutOrders = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from: '2025-01-01',
to: '2025-01-31',
type: 'PAYOUT'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Órdenes PAYOUT:', payoutOrders.data.orders.length);# Obtener solo órdenes PAYIN
curl -X GET 'https://api.koywe.com/api/v1/organizations/org3_xxx/merchants/mrc_xxx/accounts/acc_xxx/reports/orders?from=2025-01-01&to=2025-01-31&type=PAYIN' \
-H 'Authorization: Bearer TU_TOKEN'Filtrar por Estado
Obtener órdenes con estados específicos:
// Obtener solo órdenes completadas
const completedOrders = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from: '2025-01-01',
to: '2025-01-31',
status: 'COMPLETED'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Órdenes completadas:', completedOrders.data.orders.length);
// Obtener órdenes fallidas para investigación
const failedOrders = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from: '2025-01-01',
to: '2025-01-31',
status: 'FAILED'
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
console.log('Órdenes fallidas a investigar:', failedOrders.data.orders.length);# Obtener órdenes fallidas
curl -X GET 'https://api.koywe.com/api/v1/organizations/org3_xxx/merchants/mrc_xxx/accounts/acc_xxx/reports/orders?from=2025-01-01&to=2025-01-31&status=FAILED' \
-H 'Authorization: Bearer TU_TOKEN'Entendiendo la Respuesta
JSON
{
"accountId": "acc_0031c537-2301-40ab-9153-0f7c48505350",
"currency": "CLP",
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-01-31T23:59:59.999Z",
"orders": [
{
"orderId": "ord_abc123",
"type": "PAYIN",
"status": "COMPLETED",
"amountIn": "1000000.00",
"amountOut": "1000000.00",
"originCurrency": "CLP",
"destinationCurrency": "CLP",
"counterparty": {
"name": "Juan Pérez",
"identifier": "12345678-9"
},
"createdAt": "2025-01-15T10:30:00.000Z",
"completedAt": "2025-01-15T10:35:00.000Z",
"externalId": "FAC-2025-001"
},
{
"orderId": "ord_def456",
"type": "PAYOUT",
"status": "COMPLETED",
"amountIn": "500000.00",
"amountOut": "500000.00",
"originCurrency": "CLP",
"destinationCurrency": "CLP",
"counterparty": {
"name": "Proveedor SA",
"identifier": "98765432-1"
},
"createdAt": "2025-01-20T14:00:00.000Z",
"completedAt": "2025-01-20T14:15:00.000Z",
"externalId": "OC-2025-042"
}
],
"summary": {
"totalOrders": 150,
"byType": {
"PAYIN": 100,
"PAYOUT": 50
},
"byStatus": {
"COMPLETED": 140,
"PENDING": 5,
"FAILED": 5
}
},
"pagination": {
"cursor": "eyJvcmRlcklkIjoib3JkX2RlZjQ1NiJ9",
"hasMore": true,
"limit": 50
},
"generatedAt": "2025-01-31T12:00:00.000Z"
}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:
JavaScript
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: { from: '2025-01-01', to: '2025-01-31' },
headers: { 'Authorization': `Bearer ${token}` }
}
);
const { summary } = response.data;
// Análisis de volumen
console.log('=== Volumen Mensual ===');
console.log(`Total Órdenes: ${summary.totalOrders}`);
// Por tipo
console.log('\n=== Por Tipo ===');
Object.entries(summary.byType).forEach(([type, count]) => {
console.log(`${type}: ${count} órdenes`);
});
// Por estado
console.log('\n=== Por Estado ===');
Object.entries(summary.byStatus).forEach(([status, count]) => {
const percentage = ((count / summary.totalOrders) * 100).toFixed(1);
console.log(`${status}: ${count} (${percentage}%)`);
});
// Tasa de éxito
const completed = summary.byStatus.COMPLETED || 0;
const failed = summary.byStatus.FAILED || 0;
const successRate = (completed / (completed + failed) * 100).toFixed(1);
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.
JavaScript
// Obtener estado de cuenta
const ledger = await getLedgerStatement(orgId, merchantId, accountId, from, to, token);
// Obtener reporte de órdenes
const orders = await getOrdersReport(orgId, merchantId, accountId, from, to, token);
// Referencia cruzada
ledger.movements.forEach(movement => {
if (movement.orderId) {
const order = orders.orders.find(o => o.orderId === movement.orderId);
if (order) {
console.log(`Movimiento ${movement.ledgerEntryId} coincide con Orden ${order.orderId} (${order.type})`);
}
}
});Ejemplo de Integración Completa
JavaScript
async function generarAnalisisDeOrdenes(orgId, merchantId, accountId, from, to, token) {
// Obtener todas las órdenes (manejando paginación)
const todasLasOrdenes = [];
let cursor = null;
let summary = null;
do {
const response = await axios.get(
`https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/orders`,
{
params: {
from,
to,
limit: 100,
...(cursor && { cursor })
},
headers: { 'Authorization': `Bearer ${token}` }
}
);
todasLasOrdenes.push(...response.data.orders);
summary = response.data.summary;
cursor = response.data.pagination.hasMore ? response.data.pagination.cursor : null;
} while (cursor);
// Generar análisis
console.log('='.repeat(60));
console.log('REPORTE DE ANÁLISIS DE ÓRDENES');
console.log(`Período: ${from} a ${to}`);
console.log('='.repeat(60));
// Estadísticas de resumen
console.log('\n📊 RESUMEN');
console.log(`Total Órdenes: ${summary.totalOrders}`);
// Desglose por tipo
console.log('\n📈 POR TIPO');
Object.entries(summary.byType).forEach(([type, count]) => {
const pct = ((count / summary.totalOrders) * 100).toFixed(1);
console.log(` ${type.padEnd(20)} ${String(count).padStart(5)} (${pct}%)`);
});
// Desglose por estado
console.log('\n📋 POR ESTADO');
Object.entries(summary.byStatus).forEach(([status, count]) => {
const pct = ((count / summary.totalOrders) * 100).toFixed(1);
console.log(` ${status.padEnd(20)} ${String(count).padStart(5)} (${pct}%)`);
});
// Calcular totales por tipo
console.log('\n💰 VOLUMEN POR TIPO');
const volumenPorTipo = {};
todasLasOrdenes.forEach(order => {
if (!volumenPorTipo[order.type]) {
volumenPorTipo[order.type] = 0;
}
volumenPorTipo[order.type] += parseFloat(order.amountIn);
});
Object.entries(volumenPorTipo).forEach(([type, volume]) => {
console.log(` ${type.padEnd(20)} ${volume.toLocaleString()}`);
});
// Detalle de órdenes fallidas
const ordenesFallidas = todasLasOrdenes.filter(o => o.status === 'FAILED');
if (ordenesFallidas.length > 0) {
console.log('\n⚠️ ÓRDENES FALLIDAS');
ordenesFallidas.forEach(order => {
console.log(` ${order.orderId} | ${order.type} | ${order.amountIn} | ${order.createdAt}`);
});
}
console.log('\n' + '='.repeat(60));
return { orders: todasLasOrdenes, summary };
}
// Uso
const analisis = await generarAnalisisDeOrdenes(
'org3_xxx',
'mrc_xxx',
'acc_xxx',
'2025-01-01',
'2025-01-31',
token
);