Saltar al contenido

    Clientes y reportes de cobros

    Un mismo cliente sirve para identificar a un comprador y, si le habilitas credenciales, para operar como cliente B2B2B. No necesitas otra tabla ni otro tipo de cliente.

    1. Crear el cliente sin acceso de inicio de sesión

    Usa POST /v1/clients/create con el header appKey del comercio o su token Bearer. Omite nickname y usa generate_nick: false para registrar solo al comprador. Guarda el id de la respuesta y reutilízalo en todos sus cobros.

    Cuerpo de creación del comprador
    {
      "name": "Ana Pérez",
      "type": "user",
      "phone": "584121234567",
      "email": "[email protected]",
      "generate_nick": false
    }

    Si después le asignas credenciales mediante la API de clientes, sigue siendo el mismo registro y conserva sus métricas. Ver creación, actualización y credenciales de clientes.

    2. Verificar un pago de ese cliente con Betaserio

    POST /userbankpayment/BANK_ID/betaserio acepta client_id y items opcionales. client_id es el cliente al que se le cobró. No reemplaza al usuario, empleado o API key que ejecutó la llamada, ni cambia el cupo que corresponde a la cuenta bancaria.

    Pago asociado al cliente
    {
      "bank_reference": "123456789",
      "amount": 1500,
      "movement_type": "GENERIC",
      "client_id": "CLIENT_ID"
    }

    Los campos bancarios dependen del proveedor: consulta los campos de verificación. El monto de Betaserio está en la moneda de liquidación del banco (normalmente VEF; Binance, USDT).

    Pago con productos del catálogo
    {
      "bank_reference": "123456789",
      "movement_type": "GENERIC",
      "client_id": "CLIENT_ID",
      "items": [
        {
          "product_id": "PRODUCT_ID",
          "quantity": 2
        }
      ]
    }

    Con items, Pabilo resuelve el precio del catálogo y lo convierte a la moneda del banco. Puedes omitir amount; si lo envías, debe coincidir con el total. También puedes enviar líneas manuales con name, unit_price, currency y quantity. Se validan la pertenencia del cliente y de los productos antes de consultar el banco.

    En /betaserio/batch, cada elemento del arreglo items puede incluir su propio client_id y su propio arreglo items de productos. Un cliente o producto ajeno al comercio rechaza el lote antes de la verificación.

    Fragmento de respuesta de verificación individual
    {
      "message": "payment confirmed",
      "sale_recorded": true,
      "data": {
        "is_new": true,
        "credit_cost": 2
      }
    }

    La respuesta conserva los datos completos del pago. sale_recorded indica si esta llamada guardó el detalle comercial; en batch aparece en results[].data. Los duplicados (is_new: false) no crean otro cobro ni permiten reasignar un pago viejo a otro cliente. Los bancos de prueba no generan ventas. Un fallo al guardar el reporte no anula un pago bancario confirmado: sale_recorded será false; revisa ese resultado al conciliar.

    3. Enlaces de pago con cliente y productos

    En POST /v1/paymentlink, asigna client_id al crear el enlace. El pagador no puede cambiarlo al confirmar el pago. Cada pago nuevo de un enlace reutilizable se registra por separado.

    Crear enlace de venta
    {
      "name": "Pedido 1042",
      "user_bank_id": "BANK_ID",
      "type": "default",
      "currency": "USD",
      "client_id": "CLIENT_ID",
      "items": [
        {
          "product_id": "PRODUCT_ID",
          "quantity": 2
        }
      ],
      "webhook_url": "https://tienda.example/webhooks/pabilo"
    }

    El desglose y sus precios quedan congelados en el enlace. Generarlo no cuenta como venta: se incluye al confirmar el pago. Contrato completo de enlaces.

    4. Suscripciones del mismo cliente

    POST /v1/subscription/make acepta client_id junto con items. branchClientId sigue disponible por compatibilidad; si envías ambos deben coincidir. Usa un cliente del catálogo para acumular métricas sobre su id, en lugar de un uniqueClient escrito a mano.

    Suscripción asociada al comprador
    {
      "name": "Servicio de Ana",
      "user_bank_id": "BANK_ID",
      "client_id": "CLIENT_ID",
      "currency": "USD",
      "pay_first": true,
      "notificationMedium": "email",
      "items": [
        {
          "product_id": "PRODUCT_ID",
          "quantity": 1
        }
      ]
    }

    El cliente debe tener el destino requerido por el canal de notificación. Cada renovación hereda client_id y congela los productos en su enlace de cobro. Los productos del catálogo se cotizan de nuevo al generar la renovación; cambiar el catálogo no altera los cobros anteriores.

    5. Consultar lo cobrado a un cliente

    GET: JSON de ventas de un cliente
    curl "https://api.pabilo.app/me/stats/sales?from=2026-09-01&to=2026-09-30&client_id=CLIENT_ID" -H "appKey: API_KEY_DEL_COMERCIO"
    ParámetroDescripción
    from / toFechas YYYY-MM-DD, ambos días incluidos en America/Caracas. Por defecto los últimos 31 días; máximo 366 días.
    client_idOpcional: solo cobros de ese cliente del mismo comercio. Omitirlo devuelve todos los clientes.
    formatjson (predeterminado) o csv.
    groupPara CSV: payments (predeterminado), clients, products, daily, sources o summary.
    Estructura resumida de la respuesta
    {
      "from": "2026-09-01",
      "to": "2026-09-30",
      "report": {
        "totals": [
          {
            "id": "total",
            "name": "Total",
            "currency": "USD",
            "orders": 2,
            "units": 0,
            "revenue": 60,
            "average": 30
          }
        ],
        "clients": [],
        "products": [],
        "sources": [],
        "daily": [],
        "payments": [],
        "legacy_orders": 0,
        "unattributed_orders": 0
      }
    }

    totals, clients, products, sources y daily contienen orders, units, revenue y average por moneda. units corresponde al desglose de productos; average es el importe medio por cobro. payments contiene id, client_id cuando existe, client_name, source, currency, amount, paid_at, bank_reference cuando existe, items y legacy. source identifica verification, default, subscription, fixed o donation. En verificación directa no hay enlace asociado.

    La consulta requiere credenciales del comercio. Las sesiones y API keys de clientes B2B2B y las sesiones de empleados no pueden consultar estos reportes generales. Un client_id de otro comercio se rechaza. Si hay más de 50.000 pagos en el rango, reduce el período.

    6. Descargar CSV por API

    Descargar cada cobro del cliente
    curl "https://api.pabilo.app/me/stats/sales?from=2026-09-01&to=2026-09-30&client_id=CLIENT_ID&format=csv&group=payments" -H "appKey: API_KEY_DEL_COMERCIO" -o cobros-cliente.csv
    Descargar ranking de productos
    curl "https://api.pabilo.app/me/stats/sales?from=2026-09-01&to=2026-09-30&format=csv&group=products" -H "appKey: API_KEY_DEL_COMERCIO" -o productos.csv

    CSV usa UTF-8 con BOM, cabecera y protección de fórmulas en textos. La web ofrece los mismos rankings y descargas en Estadísticas → Ventas y clientes.

    Cómo interpretar los datos

    Se muestran ingresos cobrados, no utilidad neta: el catálogo no registra costos de compra. Cada moneda conserva sus importes originales; no se suman dólares y bolívares. Los descuentos de una factura se reparten proporcionalmente entre sus líneas positivas.

    Las verificaciones directas se incluyen cuando envías client_id o items. Los enlaces antiguos pagados sin comprobante comercial usan su última actualización como fecha estimada (legacy: true); no se inventan productos o clientes que no estaban asociados. Los pagos de enlaces reutilizables y donaciones tienen detalle desde esta actualización.

    Los cupos y el consumo de créditos B2B2B se consultan por separado en /v1/clients/CLIENT_ID/credit-consumption. El propio cliente ve su cupo en /me/client-credit-consumption, sin acceso al saldo del comercio. Ambos usos mantienen el mismo registro de cliente.