Inicio / Integraciones / Referencia técnica
Para equipos de TIReferencia técnica

La API de integraciones de PIZ

Común a los 7 sistemas — nunca cambia según tu ERP. Léela una vez; las guías por sistema solo añaden lo específico de tu lado.

← Todos los sistemas

Común a los 7 sistemas — nunca cambia según tu ERP. Léela una vez; las guías por sistema solo añaden lo específico de tu lado.

Cómo funciona

Cada pieza se usa por separado. Puedes conectar solo la entrada de SOLPED (1), solo la salida de facturas (7), que tu ERP reciba a los proveedores homologados (0), que tu ERP emita las órdenes (3 y 4), o el ciclo completo con los avisos de pago (8). Lo que no conectes se hace en las pantallas de PIZ.

Todo es asíncrono. Enviar una SOLPED confirma solo que PIZ la recibió — la RFQ queda en borrador hasta que un comprador la revisa y publica.

La orden de compra: la emite PIZ o tu ERP

En PIZ se decide la compra: convocatoria, comparación de ofertas, adjudicación y firmas. Dónde nace la orden oficial lo elige el administrador en Mi organización → Integraciones API → ¿Quién emite la orden de compra?

OpciónQué pasa al completarse las firmas
PIZPIZ emite la orden con tu numeración (se configura en Mi organización → Nomenclatura de documentos) y se la envía al proveedor. Pasos 5 a 8 del gráfico.
Mi ERPLa orden queda «Esperando al ERP» y el proveedor todavía no la ve. PIZ le envía a tu ERP el evento orden_aprobada (paso 3). Tu ERP emite la orden y responde con POST /purchase_order_erp.php (paso 4): su número pasa a ser el oficial y, si lo envía, su PDF queda adjunto. Recién entonces el proveedor la recibe.

Cambios y anulaciones. Si una orden se modifica, la modificación es una orden nueva: al aprobarse le llega a tu ERP como orden_aprobada con modifica_a = la orden anterior. Si una orden que ya se le pidió a tu ERP se anula, tu ERP recibe el evento orden_anulada con el motivo.

Si tu ERP no puede emitirla (falta el proveedor, un artículo o un centro de costo), responde con error y el motivo: la orden sigue esperando y el comprador lo ve en PIZ, con dos salidas: volver a pedírsela al ERP cuando esté corregido, o emitirla desde PIZ con el número de PIZ.

Recomendaciones

  • La aprobación, en un solo lugar. Si las firmas se hacen en PIZ, tu ERP no debe volver a pedir la aprobación de la misma compra.
  • Una sola numeración. Si tu ERP emite la orden, manda su número. Si la emite PIZ, configura en PIZ el mismo formato que usa tu organización.
  • El proveedor, creado en tu ERP. Si tu ERP emite la orden, el proveedor tiene que existir en él: el evento orden_aprobada trae su RUC para ubicarlo.
  • Cruza por tus propios números. Usa solped_numero y oc_codigo para enlazar en tu ERP la solicitud, la orden y la factura.
  • Los mismos códigos de material. Homologa una vez tus códigos con las categorías de PIZ (ver Tu propio código de material).
  • Cierra el ciclo. Cuando tu ERP pague la factura, avísale a PIZ con invoice_payment: el proveedor ve su pago sin preguntar.

Autenticación

OAuth 2.0 Client Credentials — estándar, sin nada propietario que aprender.

DatoValor
Token endpointPOST /api/v1/oauth_token.php
Grant typeclient_credentials
Vigencia del token3600 s — cachea y renueva
TransporteAuthorization: Bearer <token>, HTTPS obligatorio

Scopes — qué permite pedir cada uno

Al crear tu credencial (Mi organización → Integraciones API) eliges qué scopes lleva. Pide solo los que realmente vas a usar.

ScopeQué permite
solped:writeEnviar una SOLPED (POST /purchase_requisitions.php) — el scope que casi todos necesitan.
status:readConsultar el estado de una RFQ ya enviada (GET /purchase_requisitions_status.php).
payment:writeAvisar a PIZ que una factura aprobada fue pagada (POST /invoice_payment.php).
order:writeResponder con la orden que emitió tu ERP (POST /purchase_order_erp.php). Solo si tu ERP emite las órdenes.
supplier:writeResponder con el código que tu ERP le dio a un proveedor homologado (POST /supplier_erp.php).
curl -X POST https://[ambiente]/api/v1/oauth_token.php \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "TU_CLIENT_ID",
    "client_secret": "TU_CLIENT_SECRET"
  }'
{
  "access_token": "f6d3f1a1df89...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "solped:write,status:read"
}

Cómo obtener acceso

En sandbox, cualquier administrador de tu organización puede generar credenciales de inmediato desde Mi organización → Integraciones API — sin pedirlo a nadie; si todavía no tienes cuenta, contacta a tu contraparte comercial para que te creen una organización de prueba ahí. En producción, Integraciones API es un add-on que primero debe activar tu contraparte comercial para tu organización — una vez activo, la generación de credenciales es igual de inmediata desde el mismo panel.

Enviar una SOLPED

POST /api/v1/purchase_requisitions.php — crea una RFQ en PIZ en estado "borrador". Un comprador la revisa y la publica.

CampoTipoOblig.
solped_numerostringsí
titulostringsí
tipo_comprabienes·serviciossí
categoria_codigostringsí
centro_costostringno
presupuesto_referencialdecimalno
monedaPEN·USDno
itemsarray de objetossí, si tipo_compra=bienes
items[].codigo_erpstring, hasta 40 caracteres — el código del artículo en tu ERP (en SAP Business One, su ItemCode)no

Si tipo_compra es bienes, items es obligatorio — un arreglo con al menos un artículo, porque una sola SOLPED puede traer varios distintos (ej. cascos + arneses). Cada ítem: descripcion (string, obligatorio), cantidad (decimal, obligatorio, mayor a 0), unidad_medida (string, opcional), presupuesto_referencial (decimal, opcional, por ítem) y codigo_erp (string, opcional). codigo_erp es el código del artículo en tu ERP: PIZ lo guarda en el ítem y te lo devuelve en orden_aprobada y factura_conforme. El proveedor no lo ve. Si tipo_compra es servicios, items no aplica — usa descripcion como hasta ahora.

{
  "solped_numero": "4500128394",
  "titulo": "Compra de EPP para cuadrilla de mina",
  "tipo_compra": "bienes",
  "categoria_codigo": "MIN-014",
  "items": [
    { "codigo_erp": "EPP-0101", "descripcion": "Casco de seguridad", "unidad_medida": "unidad", "cantidad": 10 },
    { "descripcion": "Arnés de seguridad", "unidad_medida": "unidad", "cantidad": 5, "presupuesto_referencial": 175.00 }
  ]
}

El header Idempotency-Key es obligatorio — un reintento con la misma key nunca duplica la RFQ.

Recibir la factura

PIZ hace POST a tu URL de callback en cuanto una factura queda con conformidad, firmado con X-PIZ-Signature (HMAC-SHA256 con tu webhook_secret). Si tu endpoint no responde 2xx, reintentamos con backoff (1 min, 5 min, 30 min, 3 h, 24 h) hasta 5 veces.

Además de la factura, el aviso trae lo necesario para registrar el ingreso al almacén (o la recepción del servicio): tipo (bien o servicio), proveedor (RUC, razón social y tu erp_codigo) y recepcion, con quién dio la conformidad, el número de guía, el de la HES y los ítems con su cantidad. Cada ítem trae su codigo_erp: el código del artículo en tu ERP, o null si no se puso.

Los avisos que recibe tu ERP

Todos llegan a tu URL de callback, firmados con X-PIZ-Signature y con reintentos. El encabezado X-PIZ-Event y el campo evento dicen cuál es. Ignora los que no uses.

EventoCuándo llega
proveedor_homologadoUn proveedor queda homologado (también al renovarse). Solo si activaste «Avisar a mi ERP cada proveedor homologado».
orden_aprobadaUna orden completa sus firmas. Solo si tu ERP emite las órdenes.
orden_anuladaSe anula una orden que ya se le había pedido a tu ERP.
factura_conformeUna factura recibe la conformidad del comprador.

Dar de alta al proveedor en tu ERP

Con «Avisar a mi ERP cada proveedor homologado» activado (Mi organización → Integraciones API), tu ERP recibe al proveedor apenas queda homologado, antes de que gane una compra. Así, cuando llegue la primera orden, ya existe en tu ERP.

{
  "evento": "proveedor_homologado",
  "ruc": "20512345678",
  "razon_social": "SUMINISTROS ANDINOS S.A.C.",
  "erp_codigo": null,
  "direccion_fiscal": "Av. Argentina 1234, Lima",
  "telefono": "+51 1 555 0101",
  "contacto": { "nombre": "Ana Torres", "email": "ana.torres@suministrosandinos.pe" },
  "datos_bancarios": { "banco": "BCP", "tipo_cuenta": "corriente", "numero_cuenta": "193-1234567-0-01", "cci": "00219300123456700112", "cuenta_detracciones": "00-123-456789" },
  "categorias": [ { "nombre": "Equipos de protección personal", "codigo": "SEG-004" } ],
  "homologado_at": "2026-10-13T11:20:00-05:00",
  "es_renovacion": false
}

Cuando lo des de alta, responde con el código que le diste (en SAP Business One, su CardCode): POST /api/v1/supplier_erp.php con { "ruc": "20512345678", "erp_codigo": "P00123" } y el scope supplier:write. Desde entonces ese código viaja en proveedor.erp_codigo de cada orden_aprobada y factura_conforme de ese proveedor.

Recibir la orden aprobada (si tu ERP emite la orden)

A la misma URL de callback, firmado igual (X-PIZ-Signature) y con los mismos reintentos. El encabezado X-PIZ-Event dice qué trae el cuerpo: orden_aprobada o factura_conforme.

{
  "evento": "orden_aprobada",
  "oc_codigo": "OC-2026-00124",
  "solped_numero": "4500128394",
  "rfq_codigo": "RFQ-0123",
  "tipo": "compra",
  "modifica_a": null,
  "contrato_marco": null,
  "proveedor": { "ruc": "20512345678", "razon_social": "SUMINISTROS ANDINOS S.A.C.", "erp_codigo": "P00123" },
  "moneda": "PEN",
  "monto_total": 17500.00,
  "fecha_entrega": "2026-10-20",
  "condiciones_pago": "Crédito 30 días",
  "plazo_entrega": "5 días",
  "items": [
    { "codigo_erp": "A00125", "descripcion": "Reductor 15 HP", "unidad": "Unidad", "cantidad": 1, "monto": 17500.00 }
  ],
  "centros_costo": [ { "nombre": "Mantenimiento", "codigo": "CC-200", "porcentaje": 100 } ],
  "aprobada_at": "2026-10-13T17:05:00-05:00"
}

items[].codigo_erp es el código del artículo en tu ERP (en SAP Business One, su ItemCode), el que el comprador escribió en «Código en tu sistema» o el que llegó con la SOLPED. Es opcional: si no se puso, llega null. Con él tu ERP puede crear una orden de inventario. El proveedor no lo ve.

Responder con la orden emitida por tu ERP

POST /api/v1/purchase_order_erp.php — requiere el scope order:write y el header Idempotency-Key. Envía uno de los dos: erp_numero si la emitiste, o error si no pudiste.

CampoTipoOblig.
oc_codigostring — el que recibiste en orden_aprobadasí
erp_numerostring, hasta 40 caracteres — tu número de ordensí, si la emitiste
pdf_base64string — el PDF de tu orden, hasta 5 MBno
errorstring — por qué no pudiste emitirlasí, si no la emitiste
curl -X POST https://[ambiente]/api/v1/purchase_order_erp.php \
  -H "Authorization: Bearer TU_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: OC-2026-00124-emitida" \
  -d '{ "oc_codigo": "OC-2026-00124", "erp_numero": "4500009871" }'
{ "oc_codigo": "4500009871", "codigo_piz": "OC-2026-00124", "estado": "aprobada", "pdf_adjunto": false }

Desde ese momento la orden se identifica con tu número: oc_codigo en la factura conforme y en invoice_payment es 4500009871. Un número que ya usa otra orden de tu organización se rechaza con 409 numero_repetido; repetir el mismo aviso responde 200 con ya_estaba_registrada: true.

Avisar el pago de una factura

POST /api/v1/invoice_payment.php — cuando tu ERP paga una factura, avísale a PIZ: la factura pasa a pagado y se notifica al proveedor. Requiere el scope payment:write. Es la contraparte entrante del webhook de conformidad: aquel te avisa a ti que la factura quedó conforme; este te deja cerrar el ciclo avisando el pago de vuelta.

Pago programado. Antes del pago puedes avisar para cuándo está programado: envía "estado": "programado" y "fecha_programada": "2026-10-30". La factura sigue aprobada, el proveedor ve «Pago programado para el 30 oct 2026» y recibe el aviso. Cuando pagues, envía el aviso normal (sin estado, o con "estado": "pagado").

Identifica la factura por su factura_codigo (el FA-XXXX que ya recibiste en el webhook) o por el par oc_codigo + numero_factura. La factura debe estar aprobada (con conformidad del comprador); solo entonces corresponde el pago.

CampoTipoOblig.
factura_codigostring (FA-XXXX)sí, si no envías el par
oc_codigostring (OC-XXXX)sí, si no envías factura_codigo
numero_facturastringsí, junto con oc_codigo
fecha_pagostring (ISO 8601)no — por defecto, el momento del aviso
curl -X POST https://[ambiente]/api/v1/invoice_payment.php \
  -H "Authorization: Bearer TU_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: PAGO-FA-0231-2026-09-22" \
  -d '{
    "factura_codigo": "FA-0231",
    "fecha_pago": "2026-09-22T15:30:00-05:00"
  }'
{
  "factura_codigo": "FA-0231",
  "estado_pago": "pagado",
  "pagado_at": "2026-09-22T15:30:00-05:00"
}

El header Idempotency-Key es obligatorio — un reintento con la misma key devuelve la misma respuesta sin volver a notificar al proveedor. Si la factura ya estaba pagada, la respuesta es 200 con ya_estaba_pagada: true (idempotente); si todavía está en trámite, sin conformidad, responde 422 estado_invalido y no se paga.

Puedes consultar el pago después con GET /purchase_requisitions_status.php: cada factura del bloque entregas_factura trae ahora su estado_pago y, si aplica, su pagado_at.

Tu propio código de material

Tu código interno (SAP, UNSPSC u otro propio) no tiene por qué coincidir con el código de categoría de PIZ — la homologación es la tabla de equivalencia entre ambos.

En Mi organización → Integraciones API, sección "Homologación de catálogo": escribes tu código tal cual lo usa tu ERP, y eliges a mano la categoría de PIZ a la que corresponde — el selector muestra el nombre y el código interno de PIZ de cada categoría (ej. Aditivos para concreto — CON-023) para que puedas ubicar la correcta. No hay match automático por texto; es una asociación manual, una vez por código, que después se reutiliza sola en cada SOLPED nueva.

categoria_codigo es obligatorio. PIZ primero busca en tu tabla de homologación; si no está ahí, intenta hacer match directo contra su catálogo global (por si tu código ya coincide con el de PIZ).

Si no hay match, la SOLPED se rechaza — no se crea a medias
La categoría es lo que dispara la invitación automática de proveedores cuando un comprador publica la RFQ, así que PIZ no crea una RFQ sin categoría: si tu categoria_codigo no coincide con ninguna homologación tuya ni con el catálogo global, la API responde 400 categoria_no_encontrada y no se crea nada. Homologa el código primero (sección anterior) y vuelve a intentar.

Errores

CódigoSignificadoQué hacer
400 campo_invalidoFalta un campo obligatorio o el tipo no calza (incluye items faltante o vacío en bienes)El mensaje nombra el campo exacto
400 categoria_no_encontradacategoria_codigo no coincide con tu homologación ni con el catálogo globalHomológalo primero en Mi organización → Integraciones API
401 token_invalidoToken vencido o mal formadoPide uno nuevo
403 scope_insuficienteTu credencial no tiene el scope de este endpointPide que te lo agreguen
404 no_encontradoNo hay ninguna factura (o RFQ) con esa referencia para tu organizaciónRevisa el factura_codigo / oc_codigo — solo ves las de tu organización
409 idempotency_conflictReusaste un Idempotency-Key con un body distintoGenera una key nueva por cada operación real
422 estado_invalidoLa factura todavía no está aprobada (sin conformidad), no se puede pagarReintenta cuando el comprador le dé conformidad
429 rate_limitSuperaste el límite de la sección siguienteReintenta respetando Retry-After

Sandbox, versiones, límites

AspectoRegla
SandboxAmbiente separado, datos de prueba propios — pídelo junto con tus credenciales
VersionadoPrefijo /api/v1/ — un cambio incompatible sale como v2 nuevo, v1 sigue viva con aviso previo
Rate limit60 solicitudes/minuto por credencial y por endpoint (SOLPED, aviso de pago, etc.)

Seguridad

  • TLS 1.2+ obligatorio en ambos sentidos.
  • El client_secret se muestra una sola vez — si se pierde, se rota.
  • Las URL de factura/guía expiran a las 72 horas.

¿Tu equipo de TI tiene dudas específicas?

Cuéntanos qué sistema usan y qué necesitan saber — te respondemos en menos de 1 día hábil.