API M2M v1.0.0
Bienvenido a la API Machine-to-Machine (M2M) oficial de Proyexa. Esta suite de integración ha sido diseñada meticulosamente bajo los más altos estándares de seguridad y escalabilidad para habilitar la comunicación programática directa entre instituciones financieras, pasarelas de pago o sistemas de terceros y el núcleo del ecosistema ERP de Proyexa.
A través de esta API, los integradores autorizados pueden consultar información financiera en tiempo real, validar saldos pendientes, aplicar pagos de manera automatizada y afectar la contabilidad de la empresa destino sin fricciones. Toda transacción realizada por esta vía genera trazas de auditoría completas, asegurando una conciliación bancaria transparente y en tiempo real.
Información Técnica
Todas las peticiones M2M deben realizarse desde el backend de tu integración apuntando al subdominio específico de tu cliente en Proyexa.
Entornos Disponibles
Descargar Colección Postman| Entorno | URL Base |
|---|---|
|
Sandbox (Pruebas)
Datos ficticios, ideal para
desarrollo.
| https://sandbox.proyexa.app |
|
Producción
Transacciones y contabilidad real.
| https://{tenant-del-cliente}.proyexa.app |
Límites de Petición (Rate Limiting)
Para proteger la estabilidad del ecosistema
ERP, la API M2M procesa un máximo de 60 peticiones por minuto por IP. Si superas este límite, recibirás un
error HTTP 429 Too Many Requests. Asegúrate de cachear tu token de acceso y
de no bombardear la API con retries
indiscriminados.
Estructura y Modelos
Información Técnica
Nuestra API Rest sigue un estándar estrictamente definido. Incluye distintos modelos, respuestas, entidades y excepciones, estructurados de manera que brinden una experiencia sin fricción para los desarrolladores de integraciones M2M.
Modelos
Los modelos dentro del API Rest brindan estructuras
predefinidas (JSON) para facilitar la interacción con
entidades de Proyexa, como ser facturación, clientes,
impuestos, etc.
Es muy importante conocer todas las utilidades de estos modelos
para poder explotar su potencial al máximo. Dentro de los
modelos podemos encontrar:
-
Invoice: datos de facturación e historial de cobros -
Customer: datos del cliente asociado a la factura -
Currency: datos de monedas y tipos de cambio -
InvoiceItem: todo tipo de artículos a la venta facturados -
Receipt: datos de recibos y comprobantes de pago
Invoice Object
| Propiedad | Tipo | Descripción |
|---|---|---|
| id | string (ULID) | Identificador único de la factura. |
| number | string | Número fiscal (CAI) o correlativo de la factura. |
| payment_code | string | null | Código de pago rápido asociado. |
| date | string (datetime) | Fecha de emisión de la factura (ISO 8601). |
| due_date | string (date) | null | Fecha de vencimiento para pago. |
| subtotal | string (decimal) | Monto antes de impuestos y descuentos (2 decimales). |
| discount | string (decimal) | Monto total de descuentos (2 decimales). |
| tax_amount | string (decimal) | Monto total de impuestos (2 decimales). |
| total | string (decimal) | Monto total original (2 decimales). |
| balance | string (decimal) | Saldo pendiente actual (varía según pagos aplicados) (2 decimales). |
| status | string | Estado actual. active, partially_paid, paid. |
| customer | object (Customer) | Información básica del cliente. |
| currency | object | Moneda aplicada. (Solo retorna: code, symbol y exchange_rate). |
| items | array (InvoiceItem) | null | Lista de productos o servicios (Sólo en Detalle). |
Customer Object
| Propiedad | Tipo | Descripción |
|---|---|---|
| name | string | null | Razón social o nombre completo del cliente. |
| rtn | string | null | Registro Tributario Nacional (DNI / NIT) del cliente. |
Currency Object
| Propiedad | Tipo | Descripción |
|---|---|---|
| id | string (ULID) | ID interno de la moneda. |
| code | string | Código ISO de la moneda (ej. HNL, USD). |
| name | string | Nombre comercial (ej. Lempiras). |
| symbol | string | Símbolo (ej. $, L). |
| purchase_rate | string (decimal) | Tasa de compra oficial del ERP (4 decimales). |
| sale_rate | string (decimal) | Tasa de venta oficial del ERP (4 decimales). |
| is_default | boolean | Verdadero si es la moneda base del tenant. |
InvoiceItem Object
| Propiedad | Tipo | Descripción |
|---|---|---|
| description | string | Nombre o detalle del producto/servicio. |
| quantity | number | Cantidad facturada. |
| price | string (decimal) | Precio unitario base (2 decimales). |
| subtotal | string (decimal) | Total de la línea sin impuestos (2 decimales). |
| discount_amount | string (decimal) | Descuento aplicado en la línea (2 decimales). |
| tax_rate | string (decimal) | Porcentaje de impuesto. |
| tax_amount | string (decimal) | Impuesto por la línea (2 decimales). |
| total | string (decimal) | Total de la línea con impuestos y descuentos (2 decimales). |
Receipt Object (Recibo de Pago)
| Propiedad | Tipo | Descripción |
|---|---|---|
| id | string (ULID) | Identificador único del recibo generado. |
| number | string | Correlativo interno del recibo (ej. REC-000001). |
| date | string (datetime) | Fecha de generación. |
| amount | string (decimal) | Monto total abonado (2 decimales). |
| reference | string | Referencia bancaria proporcionada. |
| notes | string | Nota autogenerada con el rastro del pago bancario (útil para auditoría). |
| status | string | Estado del recibo. |
| invoice | object | Estado actualizado de la factura (id, number, balance, status). |
Manejo de Errores
Todas las respuestas de error de la API (a excepción del endpoint de OAuth) devuelven una estructura de datos estandarizada. No es necesario adivinar el formato de error para cada petición individual; puedes programar tu interceptor de manera centralizada.
Estructura Estándar (4xx / 5xx)
Siempre devolverá "error".
Descripción humana del error (ej. "No tienes permisos").
Si es un error HTTP 422, contendrá las validaciones por campo.
{
"status": "error",
"message": "No autenticado. Token inválido o ausente.",
"data": null,
"pagination": null,
"errors": null
} Autenticación
/oauth/token Proyexa utiliza el estándar OAuth 2.0 (Client Credentials Grant). Obtén un token temporal para firmar tus peticiones.
Duración y Patrón de Integración
Por motivos de seguridad, los tokens de acceso M2M tienen un tiempo de vida estricto de 60 minutos (1 hora). Es una mala práctica (y puede generar bloqueos por límite de peticiones) solicitar un token nuevo antes de cada operación individual.
💡 Patrón Recomendado:
- Solicita el token y almacénalo temporalmente en la memoria o caché de tu sistema.
- Reutiliza el mismo token para todas tus operaciones continuas.
-
Configura un interceptor HTTP en tu
cliente para que, si recibe un error
401 Unauthorized, solicite silenciosamente un nuevo token y reintente la petición original.
Body (JSON)
Fijo: client_credentials
UUID de tu credencial M2M.
Llave secreta generada en Proyexa.
curl -X POST https://{tenant}.proyexa.app/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "99b0c...",
"client_secret": "kYxP9..."
}' {
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLC..."
} Monedas y Tasas
/m2m/billing/currencies Consulta las monedas configuradas en el tenant y su tasa de conversión oficial. Indispensable para procesar pagos en dólares u otras denominaciones soportadas.
Headers
Bearer {access_token}
curl -X GET https://{tenant}.proyexa.app/m2m/billing/currencies \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json" {
"status": "success",
"message": "Monedas obtenidas exitosamente.",
"data": [
{
"id": "019...",
"code": "HNL",
"name": "Lempiras",
"symbol": "L",
"purchase_rate": "1.0000",
"sale_rate": "1.0000",
"is_default": true
},
{
"id": "019...",
"code": "USD",
"name": "Dólares",
"symbol": "$",
"purchase_rate": "24.5000",
"sale_rate": "24.8000",
"is_default": false
}
],
"pagination": null,
"errors": null
} Listar Facturas
/m2m/billing/invoices
Devuelve la lista paginada de todas las facturas
pendientes de pago (estado active o partially_paid). Puedes buscar por ID de cliente o RTN.
Query Parameters
Filtro por ID interno del cliente.
Búsqueda exacta por RTN/DNI del cliente.
Número de página a consultar (Defecto: 1).
Resultados por página (Defecto: 15).
Manejo de Paginación
Este endpoint puede devolver un gran
volumen de datos, por lo que su
respuesta está dividida en páginas.
En el cuerpo JSON de la respuesta
encontrarás el objeto pagination. Para obtener el siguiente bloque
de registros, simplemente haz una
nueva petición agregando el
parámetro ?page=2 (o el número correspondiente) a la URL,
guiándote por la propiedad has_more_pages.
curl -X GET "https://{tenant}.proyexa.app/m2m/billing/invoices?customer_id=01H9&per_page=15" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json" {
"status": "success",
"message": "Facturas pendientes obtenidas exitosamente.",
"data": [
{
"id": "01J2X...",
"number": "000-001-01-00000042",
"payment_code": "42",
"date": "2026-06-30T10:00:00.000000Z",
"due_date": "2026-07-30T06:00:00.000000Z",
"subtotal": "1304.35",
"discount": "0.00",
"tax_amount": "195.65",
"total": "1500.00",
"balance": "1500.00",
"status": "active",
"customer": {
"name": "Empresa S.A.",
"rtn": "0801199012345"
},
"currency": {
"code": "HNL",
"symbol": "L",
"exchange_rate": "1.0000"
}
}
],
"pagination": {
"current_page": 1,
"last_page": 1,
"per_page": 15,
"total": 1,
"has_more_pages": false
},
"errors": null
} Detalle de Factura
/m2m/billing/invoices/{id_o_codigo} Validación Crítica
Siempre consulta este endpoint justo antes de procesar un abono monetario para verificar el saldo actualizado. Las facturas pueden haber recibido abonos desde otros canales.
Path Parameters
Soporta los siguientes formatos:
- UUID (ID interno de la base de datos)
-
Número de Factura (
000-001-01-00000601) -
Correlativo (
601) -
Payment Code (Código de pago) (
42)
curl -X GET "https://{tenant}.proyexa.app/m2m/billing/invoices/000-001-01-00000042" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json" {
"status": "success",
"message": "Detalle de factura obtenido exitosamente.",
"data": {
"id": "01J2X...",
"number": "000-001-01-00000042",
"payment_code": "42",
"date": "2026-06-30T10:00:00.000000Z",
"due_date": "2026-07-30T06:00:00.000000Z",
"subtotal": "1304.35",
"discount": "0.00",
"tax_amount": "195.65",
"total": "1500.00",
"balance": "1500.00",
"status": "active",
"customer": {
"name": "Empresa S.A.",
"rtn": "0801199012345"
},
"currency": {
"code": "HNL",
"symbol": "L",
"exchange_rate": "1.0000"
},
"items": [
{
"description": "Servicio de Consultoría",
"quantity": 1.0000,
"price": "1304.35",
"subtotal": "1304.35",
"discount_amount": "0.00",
"tax_rate": "15.00",
"tax_amount": "195.65",
"total": "1500.00"
}
]
},
"pagination": null,
"errors": null
} Registrar Pago
/m2m/billing/invoices/{id_o_codigo}/payments Aplica un abono monetario a la factura. Proyexa validará los alcances configurados en el ERP para determinar si tienes permitido registrar pagos parciales y generará el recibo contable automáticamente.
Body (JSON)
Monto depositado. Será rechazado si es superior al saldo pendiente.
Número de comprobante bancario único.
Código ISO (ej. USD). Si se envía una moneda foránea, el sistema hará la conversión automática usando la tasa oficial.
Idempotencia y Prevención de Pagos Dobles
Este endpoint está diseñado para ser
seguro ante fallas de red.
Utilizamos el parámetro reference_number como clave de idempotencia (Idempotency
Key). Si tu sistema pierde conexión y
reintenta aplicar un pago usando el mismo
número de referencia bancaria, Proyexa
detectará el duplicado, protegerá el saldo
de la factura y devolverá un error 422 Unprocessable Entity.
curl -X POST "https://{tenant}.proyexa.app/m2m/billing/invoices/000-001-01-00000042/payments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"amount": 1500.00,
"reference_number": "TRX-88",
"currency_code": "HNL"
}' {
"status": "success",
"message": "Pago aplicado exitosamente.",
"data": {
"id": "01J2Z...",
"number": "REC-000001",
"date": "2026-07-01T10:00:00.000000Z",
"amount": "1500.00",
"reference": "M2M-TRX-88",
"notes": "M2M: Pago vía [Integración Banco] Transacción: TRX-88 (1500.00 HNL)",
"status": "active",
"invoice": {
"id": "01J2X...",
"number": "000-001-01-00000042",
"balance": "0.00",
"status": "paid"
}
},
"pagination": null,
"errors": null
}