PaymentOrder
Overview
PaymentOrder es el modelo de Mongoose que persiste las órdenes de pago del sistema. Representa pagos asociados a una campaña o a un plan, y almacena el proveedor, el importe, el estado y los datos de redirección. Su definición vive en services/api/src/models/PaymentOrder.js y usa timestamps: true para guardar createdAt y updatedAt automáticamente
Este modelo actúa como el punto de enlace entre la intención de cobro y la confirmación externa del pago. En el contexto disponible, también aparece como referencia en la lógica de pagos y en scripts de migración que reubican o clasifican relaciones de propiedad del usuario
[!IMPORTANT] La orden puede representar dos escenarios:
campaignoplan. Esa decisión cambia qué campos tienen peso operativo, especialmentecampaignIdyplanTarget
How it works
flowchart TB
PO[PaymentOrder]
U[User]
C[Campaign]
PS[payments service]
PW[payments webhooks]
PT[PaymentTransaction]
M1[migrateLegacyAdmin]
M2[migratePublicUsers]
PO --> U
PO --> C
PS --> PO
PS --> PT
PS --> C
PW --> PO
PW --> PT
M1 --> PO
M2 --> PO
PaymentOrder define la estructura base que usan los flujos de pago. La lógica de payments.service.js carga la orden, la marca como pagada y registra la transacción del webhook cuando corresponde
payments.webhooks.js se apoya en esta orden para resolver eventos externos de Stripe y MercadoPago, mientras que los scripts migrateLegacyAdmin.js y migratePublicUsers.js la incluyen entre las referencias de propiedad o identidad que recorren durante sus procesos
Key components
{
"title": "PaymentOrder",
"content": "Modelo de Mongoose que persiste \u00f3rdenes de pago. Centraliza el tipo de orden, el proveedor, el importe, el estado y las referencias a campa\u00f1a o plan.",
"type": "class",
"filePath": "services/api/src/models/PaymentOrder.js",
"badges": [
"public"
]
}
Data & fields
[
{
"name": "type",
"type": "String",
"description": "Tipo de orden. Admite \"campaign\" o \"plan\". Su valor por defecto es \"campaign\"."
},
{
"name": "planTarget",
"type": "String",
"description": "Destino del plan. Admite \"professional\", \"creator\", \"enterprise\" o cadena vacía. Su valor por defecto es \"\" y se recorta con trim."
},
{
"name": "campaignId",
"type": "Schema.Types.ObjectId",
"description": "Referencia a Campaign. Su valor por defecto es null."
},
{
"name": "createdBy",
"type": "Schema.Types.ObjectId",
"required": true,
"description": "Referencia obligatoria al modelo User que creó la orden."
},
{
"name": "provider",
"type": "String",
"required": true,
"description": "Proveedor de pago. Admite \"stripe\" o \"mercadopago\"."
},
{
"name": "amount",
"type": "Number",
"required": true,
"description": "Importe de la orden. Tiene mínimo 0."
},
{
"name": "currency",
"type": "String",
"description": "Moneda de cobro. Su valor por defecto es \"MXN\" y se recorta con trim."
},
{
"name": "status",
"type": "String",
"description": "Estado de la orden. Admite \"pending\", \"paid\", \"failed\", \"refunded\" o \"cancelled\". Su valor por defecto es \"pending\"."
},
{
"name": "externalId",
"type": "String",
"description": "Identificador devuelto por el proveedor, como un Stripe session ID o un Mercado Pago preference ID. Su valor por defecto es \"\"."
},
{
"name": "checkoutUrl",
"type": "String",
"description": "URL de pago a la que se redirige al usuario. Su valor por defecto es \"\"."
},
{
"name": "paidAt",
"type": "Date",
"description": "Fecha en la que se confirmó el pago. Su valor por defecto es null."
},
{
"name": "createdAt",
"type": "Date",
"description": "Marca temporal generada automáticamente por Mongoose."
},
{
"name": "updatedAt",
"type": "Date",
"description": "Marca temporal de actualización generada automáticamente por Mongoose."
}
]
typeadmitecampaignyplanplanTargetadmiteprofessional,creator,enterprisey""provideradmitestripeymercadopagostatusadmitepending,paid,failed,refundedycancelled
Los comentarios del esquema conservan enterprise y mercadopago por compatibilidad con órdenes históricas
Behaviors
PaymentOrderSchema— define la estructura persistente de la orden y sus restricciones de validación.mongoose.model("PaymentOrder", PaymentOrderSchema)— registra el modeloPaymentOrderen Mongoose para consultas y escriturastimestamps: true— agregacreatedAtyupdatedAtautomáticamenteenumen campos clave — restringe valores válidos paratype,planTarget,providerystatusdefaulten varios campos — crea órdenes listas para el flujo inicial de pago sin completar todos los datos de inmediato
Workflows
1. Crear la orden | `payments.service.js` y el área de pagos preparan una `PaymentOrder` con estado `pending` y los datos del contexto de cobro.
2. Enlazar el origen | La orden conserva el tipo, el proveedor, el importe y la referencia a campaña o plan.
3. Completar el checkout | El flujo de pagos completa `externalId` y `checkoutUrl` cuando el proveedor devuelve la información necesaria.
4. Confirmar el pago | `payments.webhooks.js` y `payments.service.js` usan la orden para marcarla como `paid` y fijar `paidAt`.
5. Resolver el destino | El flujo posterior interpreta `campaignId` o `planTarget` según `type`.
Gotchas & edge cases
[!WARNING]
createdByes obligatorio y referencia aUser. El documento no es válido sin ese campo
[!WARNING]
provideryamounttambién son obligatorios.amountademás exige un mínimo de0
[!CAUTION]
campaignIdpuede sernull. Eso encaja con órdenes de tipoplan, donde esa relación no aplica fileciteturn0file6turn0file12
[!NOTE]
externalIdycheckoutUrlempiezan vacíos. El esquema los reserva para la información devuelta por el proveedor externo
[!IMPORTANT]
planTargetpermite cadena vacía. Ese valor existe para mantener compatibilidad con órdenes de campaña, donde el destino del plan no se usa fileciteturn0file6turn0file12
Related
services/api/src/modules/payments/payments.service.jsusaPaymentOrderpara confirmar pagos y activar la campaña vinculada. También creaPaymentTransactiondurante la confirmaciónservices/api/src/modules/payments/payments.webhooks.jsprocesa eventos de Stripe y MercadoPago y sincroniza el estado de la ordenservices/api/src/models/Campaign.jsrecibe la relacióncampaignIdcuando la orden corresponde a una campañaservices/api/src/models/User.jsaporta el modelo referenciado porcreatedByservices/api/src/scripts/migrateLegacyAdmin.jsyservices/api/src/scripts/migratePublicUsers.jsincluyenPaymentOrderentre sus referencias de propiedad e identidad
[!NOTE] Este archivo no define rutas HTTP, controladores ni métodos propios. Su responsabilidad se limita al esquema y al modelo de persistencia de Mongoose