Obtener transacciones aprobadas
Cómo traer las transacciones según su estado de aprobación (aprobadas, rechazadas, pendientes…) y mantenerlas sincronizadas.
Cada transacción pasa por un flujo de aprobación: el responsable la envía y los aprobadores la aprueban, la rechazan o piden más información. Esta receta trae las transacciones aprobadas, pero sirve igual para cualquier estado de aprobación: solo cambia el valor del filtro.
Aprobada no es lo mismo que pago autorizado
Una transacción tiene dos estados independientes:
- Estado de aprobación (
approvalWorkflow.status, filtroapprovalWorkflowStatus): si tu empresa aprobó el gasto. Es el que usa esta receta. - Estado del pago (
summaryStatusytransactionStatus): si la transacción se autorizó, se confirmó o se rechazó en el procesador.AUTHORIZED_PAYMENTsignifica que el pago se autorizó, no que el gasto esté aprobado.
Estados de aprobación
Filtra con approvalWorkflowStatus y uno o más de estos valores:
| Valor | Significado |
|---|---|
AUTHORIZED | Aprobada en todos los niveles. |
PARTIAL_AUTHORIZED | Aprobada en al menos un nivel, esperando el siguiente. |
SUBMITTED | Enviada, esperando la primera aprobación. |
PENDING_SUBMISSION | Pendiente de envío: faltan campos obligatorios. |
INFORMATION_REQUIRED | Un aprobador pidió información al responsable. |
UNAUTHORIZED | Rechazada. |
EXEMPTED | Eximida del flujo por una regla de exención. |
ERROR | Error al procesar el flujo. |
PENDING | Valor histórico, solo en transacciones anteriores a PENDING_SUBMISSION. |
Un valor que no está en la lista responde 400.
1. Trae las transacciones en el estado que necesitas
curl -g -X GET 'https://{HOST}/api/public/v1/purchases?approvalWorkflowStatus=AUTHORIZED&size=500&page=0&sort[0].property=createdDate&sort[0].direction=DESC' \
-H 'X-API-KEY: tu_api_key_aqui'Para varios estados a la vez, repite el parámetro. Por ejemplo, aprobadas y eximidas:
curl -X GET 'https://{HOST}/api/public/v1/purchases?approvalWorkflowStatus=AUTHORIZED&approvalWorkflowStatus=EXEMPTED&size=500' \
-H 'X-API-KEY: tu_api_key_aqui'Cada transacción trae su estado en approvalWorkflow:
{
"uniqueCode": "…",
"companyCode": "…",
"approvalWorkflow": {
"status": "AUTHORIZED",
"lastEventType": "APPROVE",
"lastEventAuditorUniqueCode": "…",
"lastModifiedDate": "2026-10-02T17:52:23.687Z"
}
}Puedes combinar el filtro con los demás de GET /purchases: dateFrom/dateTo (fecha
de pago), companyCode si tu key tiene varias compañías (ver
Uso multi-compañía), comercio, presupuesto, etc. Recorre
todas las páginas como se explica en Paginación.
2. Mantente sincronizado con los cambios de aprobación
El estado de una transacción cambia con el tiempo: una aprobada puede revertirse, y una
pendiente puede aprobarse días después. Para enterarte sin volver a leer todo, filtra
por la fecha del último cambio en el flujo con approvalWorkflowLastModifiedDateFrom:
curl -X GET 'https://{HOST}/api/public/v1/purchases?approvalWorkflowStatus=AUTHORIZED&approvalWorkflowLastModifiedDateFrom=2026-10-01T00:00:00Z&size=500&page=0' \
-H 'X-API-KEY: tu_api_key_aqui'Con este filtro:
- El orden pasa a ser
approvalWorkflow.lastModifiedDateascendente y se ignora elsortque envíes. - No lo combines con
lastModifiedDateFrom/lastModifiedDateTo: la API responde400conNOT_SUPPORTED. - Guarda el
approvalWorkflow.lastModifiedDatemás reciente que procesaste y úsalo comoapprovalWorkflowLastModifiedDateFromen la próxima ejecución. Como el filtro es inclusive, vas a recibir otra vez la última transacción: deduplica poruniqueCode.
Para detectar las que dejaron de estar aprobadas
Si filtras por AUTHORIZED, no vas a ver las transacciones que pasaron de aprobadas a otro
estado. Si necesitas saberlo, sincroniza sin approvalWorkflowStatus y actualiza el
estado de cada transacción con el approvalWorkflow.status que trae.
La receta completa
// Node.js 18 o superior. Trae las transacciones aprobadas cuyo flujo cambió desde `since`.
const HOST = 'https://mx.stage.app.mendel.com';
const headers = { 'X-API-KEY': process.env.MENDEL_API_KEY, Accept: 'application/json' };
async function get(path) {
const res = await fetch(`${HOST}/api/public/v1${path}`, { headers });
if (!res.ok) throw new Error(`${res.status} en ${path}`);
return res.json();
}
async function approvedSince(since, statuses = ['AUTHORIZED']) {
const byCode = new Map();
for (let page = 0, totalPages = 1; page < totalPages; page++) {
const query = new URLSearchParams({
approvalWorkflowLastModifiedDateFrom: since, page, size: 500,
});
for (const status of statuses) query.append('approvalWorkflowStatus', status);
const body = await get(`/purchases?${query}`);
for (const purchase of body._embedded?.purchases ?? []) {
byCode.set(purchase.uniqueCode, purchase); // deduplica por uniqueCode
}
totalPages = body.page.totalPages;
}
const purchases = [...byCode.values()];
// Próximo punto de partida: el último cambio de aprobación procesado.
const checkpoint = purchases.reduce(
(max, p) => (p.approvalWorkflow.lastModifiedDate > max ? p.approvalWorkflow.lastModifiedDate : max),
since,
);
return { purchases, checkpoint };
}
const { purchases, checkpoint } = await approvedSince('2026-10-01T00:00:00Z');
console.log(`${purchases.length} transacciones aprobadas; próxima ejecución desde ${checkpoint}`);Para traer otro estado, cambia statuses: por ejemplo ['UNAUTHORIZED'] para las
rechazadas o ['SUBMITTED', 'PARTIAL_AUTHORIZED'] para las que esperan aprobación.
Problemas frecuentes
| Síntoma | Causa |
|---|---|
400 en approvalWorkflowStatus | El valor no es uno de los estados de la tabla. Los valores van en inglés y en mayúsculas. |
400 con NOT_SUPPORTED | Combinaste approvalWorkflowLastModifiedDateFrom con lastModifiedDateFrom o lastModifiedDateTo. |
El orden no es el que pediste en sort | Con approvalWorkflowLastModifiedDateFrom el orden es fijo: approvalWorkflow.lastModifiedDate ascendente. |
| Traes transacciones con pago autorizado que no están aprobadas | Filtraste por summaryStatus, que es el estado del pago. Usa approvalWorkflowStatus. |