Skip to content

Migracion: portal_payments

Informacion

  • Database: {tenant} (cada DB de tenant)
  • Schema: Dinamico — mismo schema que ordcon
  • Level: LEVEL_SUCURSAL o LEVEL_EMPRESA segun configuracion del tenant

Proposito

Tabla de pagos online realizados a traves del portal. Registra el estado completo del pago, la respuesta del gateway, y la vinculacion automatica con el recibo generado en el ERP.

Regla de Nivel de Migracion

Misma regla que portal_users: la migracion debe ejecutarse en el mismo nivel que ordcon para el tenant.

php
public function getLevel(): array
{
    $ordconLevel = $this->getTableLevel('ordcon');
    return [$ordconLevel];
}

Definicion DDL

sql
CREATE TABLE portal_payments (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cliente_id          INTEGER NOT NULL,
    tenant_id           INTEGER NOT NULL,
    sucursal_id         INTEGER NOT NULL,
    gateway             VARCHAR(50) NOT NULL,
    payment_method      VARCHAR(50) NOT NULL,
    amount              NUMERIC(15,2) NOT NULL,
    status              VARCHAR(20) NOT NULL DEFAULT 'pending',
    external_id         VARCHAR(255),
    external_response   JSONB,
    facturas_pagadas    JSONB NOT NULL,
    recibo_id           INTEGER NULL,
    payment_date        TIMESTAMP NOT NULL,
    created_at          TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at          TIMESTAMP NOT NULL DEFAULT NOW(),

    CONSTRAINT fk_portal_payments_ordcon
        FOREIGN KEY (cliente_id)
        REFERENCES ordcon(cnro)
        ON DELETE RESTRICT,

    CONSTRAINT chk_portal_payments_status
        CHECK (status IN ('pending', 'approved', 'rejected', 'refunded', 'cancelled'))
);

Indices

sql
-- Idempotencia: evita procesar el mismo pago del gateway dos veces
CREATE UNIQUE INDEX uq_portal_payments_external_id
    ON portal_payments (external_id)
    WHERE external_id IS NOT NULL;

-- Pagos de un cliente
CREATE INDEX idx_portal_payments_cliente_id
    ON portal_payments (cliente_id);

-- Filtrado por estado
CREATE INDEX idx_portal_payments_status
    ON portal_payments (status);

-- Filtrado por gateway (reportes, estadisticas por proveedor)
CREATE INDEX idx_portal_payments_gateway
    ON portal_payments (gateway);

Campos

CampoTipoRestriccionesDescripcion
idUUIDPK, default gen_random_uuid()Identificador unico del pago
cliente_idintegerFK → ordcon.cnro, NOT NULLCliente que realizo el pago
tenant_idintegerNOT NULLID del tenant (para resolucion de contexto en webhook)
sucursal_idintegerNOT NULLID de la sucursal (para resolucion de schema en webhook)
gatewayvarchar(50)NOT NULLAdapter de gateway usado (paypertic, mercadopago). Para webhook routing y reportes
payment_methodvarchar(50)NOT NULLMetodo: mercadopago, pagotic, etc.
amountnumeric(15,2)NOT NULLMonto total del pago
statusvarchar(20)NOT NULL, CHECK, default 'pending'Estado del pago
external_idvarchar(255)UNIQUE (parcial, WHERE NOT NULL)ID del pago en el gateway externo
external_responsejsonbnullableRespuesta completa del gateway (para debug/auditoria)
facturas_pagadasjsonbNOT NULLArray de {id, tipo, numero, monto} de facturas pagadas
recibo_idintegerFK → recibo, nullableRecibo generado automaticamente tras aprobacion
payment_datetimestampNOT NULLFecha/hora en que se realizo el pago
created_attimestampNOT NULL, default now()Fecha de creacion del registro
updated_attimestampNOT NULL, default now()Ultima modificacion

Restricciones

  • FK a ordcon: cliente_id referencia ordcon.cnro con RESTRICT (no CASCADE). Un cliente con pagos registrados no puede eliminarse del ERP sin resolver primero los pagos.
  • UNIQUE external_id (parcial): Solo aplica cuando external_id no es NULL. Esto permite registros sin external_id (pagos manuales o en proceso de creacion) pero garantiza que los IDs del gateway no se dupliquen.
  • CHECK status: Solo acepta valores validos: pending, approved, rejected, refunded, cancelled.
  • recibo_id nullable: Es NULL cuando el pago esta pendiente o fue rechazado. Se llena automaticamente cuando el webhook confirma la aprobacion y el sistema genera el recibo.

Flujo de Estados

mermaid
stateDiagram-v2
    [*] --> pending : Pago iniciado
    pending --> approved : Webhook approved
    pending --> rejected : Webhook rejected
    pending --> cancelled : Cancelado por usuario
    approved --> refunded : Reembolso procesado
    rejected --> [*]
    cancelled --> [*]
    refunded --> [*]
    approved --> [*]
  • pending → Se crea al iniciar el pago, antes de redirigir al gateway
  • approved → El webhook del gateway confirma la aprobacion. Se genera recibo automaticamente.
  • rejected → El gateway rechazo el pago. No se genera recibo.
  • cancelled → El usuario cancelo el pago antes de que fuera aprobado.
  • refunded → Reembolso posterior a una aprobacion.

Rollback

sql
DROP TABLE IF EXISTS portal_payments CASCADE;