#

API M2Mv1.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
EntornoURL 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

PropiedadTipoDescripción
idstring (ULID)Identificador único de la factura.
numberstringNúmero fiscal (CAI) o correlativo de la factura.
payment_codestring | nullCódigo de pago rápido asociado.
datestring (datetime)Fecha de emisión de la factura (ISO 8601).
due_datestring (date) | nullFecha de vencimiento para pago.
subtotalstring (decimal)Monto antes de impuestos y descuentos (2 decimales).
discountstring (decimal)Monto total de descuentos (2 decimales).
tax_amountstring (decimal)Monto total de impuestos (2 decimales).
totalstring (decimal)Monto total original (2 decimales).
balancestring (decimal)Saldo pendiente actual (varía según pagos aplicados) (2 decimales).
statusstringEstado actual. active, partially_paid, paid.
customerobject (Customer)Información básica del cliente.
currencyobjectMoneda aplicada. (Solo retorna: code, symbol y exchange_rate).
itemsarray (InvoiceItem) | nullLista de productos o servicios (Sólo en Detalle).

Customer Object

PropiedadTipoDescripción
namestring | nullRazón social o nombre completo del cliente.
rtnstring | nullRegistro Tributario Nacional (DNI / NIT) del cliente.

Currency Object

PropiedadTipoDescripción
idstring (ULID)ID interno de la moneda.
codestringCódigo ISO de la moneda (ej. HNL, USD).
namestringNombre comercial (ej. Lempiras).
symbolstringSímbolo (ej. $, L).
purchase_ratestring (decimal)Tasa de compra oficial del ERP (4 decimales).
sale_ratestring (decimal)Tasa de venta oficial del ERP (4 decimales).
is_defaultbooleanVerdadero si es la moneda base del tenant.

InvoiceItem Object

PropiedadTipoDescripción
descriptionstringNombre o detalle del producto/servicio.
quantitynumberCantidad facturada.
pricestring (decimal)Precio unitario base (2 decimales).
subtotalstring (decimal)Total de la línea sin impuestos (2 decimales).
discount_amountstring (decimal)Descuento aplicado en la línea (2 decimales).
tax_ratestring (decimal)Porcentaje de impuesto.
tax_amountstring (decimal)Impuesto por la línea (2 decimales).
totalstring (decimal)Total de la línea con impuestos y descuentos (2 decimales).

Receipt Object (Recibo de Pago)

PropiedadTipoDescripción
idstring (ULID)Identificador único del recibo generado.
numberstringCorrelativo interno del recibo (ej. REC-000001).
datestring (datetime)Fecha de generación.
amountstring (decimal)Monto total abonado (2 decimales).
referencestringReferencia bancaria proporcionada.
notesstringNota autogenerada con el rastro del pago bancario (útil para auditoría).
statusstringEstado del recibo.
invoiceobjectEstado 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)

statusSTRING

Siempre devolverá "error".

messageSTRING

Descripción humana del error (ej. "No tienes permisos").

errorsOBJECT | NULL

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

POST/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:
  1. Solicita el token y almacénalo temporalmente en la memoria o caché de tu sistema.
  2. Reutiliza el mismo token para todas tus operaciones continuas.
  3. 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)

grant_typeREQUERIDO

Fijo: client_credentials

client_idREQUERIDO

UUID de tu credencial M2M.

client_secretREQUERIDO

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

GET/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

AuthorizationREQUERIDO

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

GET/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

customer_idOPCIONAL

Filtro por ID interno del cliente.

rtnOPCIONAL

Búsqueda exacta por RTN/DNI del cliente.

pageOPCIONAL

Número de página a consultar (Defecto: 1).

per_pageOPCIONAL

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

GET/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

idOrCodeREQUERIDO

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

POST/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)

amountREQUERIDO

Monto depositado. Será rechazado si es superior al saldo pendiente.

reference_numberREQUERIDO

Número de comprobante bancario único.

currency_codeOPCIONAL

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
}