Skip to content

Pagos (Wompi)

Endpoints para gestionar pagos con integración de Wompi Colombia como pasarela de pagos.

Terminal window
# Sandbox (desarrollo)
WOMPI_SANDBOX=true
WOMPI_PUBLIC_KEY=pub_test_xxxx
WOMPI_PRIVATE_KEY=prv_test_xxxx
WOMPI_EVENTS_KEY=test_events_xxxx # Para validar webhooks
WOMPI_INTEGRITY_KEY=test_integrity_xxxx # Para firmar checkouts
# Producción
WOMPI_SANDBOX=false
WOMPI_PUBLIC_KEY=pub_prod_xxxx
WOMPI_PRIVATE_KEY=prv_prod_xxxx
WOMPI_EVENTS_KEY=prod_events_xxxx
WOMPI_INTEGRITY_KEY=prod_integrity_xxxx
  1. Crear cuenta en Wompi Colombia
  2. Ir a Configuración > Llaves API
  3. Copiar las llaves del ambiente correspondiente

model Payment {
id String @id @default(cuid())
userProfileId String @map("user_profile_id")
amount Float // Monto en pesos colombianos
method PaymentMethod
status PaymentStatus @default(PENDING)
description String?
// Campos Wompi
wompiTransactionId String? @unique // ID de transacción en Wompi
wompiReference String? @unique // Referencia única generada
paymentSourceType String? // CARD, PSE, NEQUI, BANCOLOMBIA_TRANSFER
currency String @default("COP")
amountInCents Int? // Monto en centavos para Wompi
metadata Json? // Respuesta completa de Wompi
errorMessage String? // Mensaje de error si falla
membershipId String? // Para activación automática de membresía
userProfile UserProfile @relation(...)
}
EstadoDescripción
PENDINGPago iniciado, esperando confirmación
COMPLETEDPago exitoso (APPROVED en Wompi)
FAILEDPago rechazado o con error
REFUNDEDPago anulado/reembolsado
MétodoDescripción
CREDIT_CARDTarjeta de crédito
DEBIT_CARDTarjeta débito
PSETransferencia bancaria PSE
NEQUIBilletera digital Nequi
BANCOLOMBIATransferencia Bancolombia
CASHEfectivo (registro manual)
BANK_TRANSFEROtra transferencia bancaria

sequenceDiagram
participant U as Usuario
participant F as Frontend
participant A as API
participant W as Wompi
U->>F: Selecciona método de pago
F->>A: POST /payments/checkout
A->>A: Crea Payment (PENDING)
A->>W: Crear transacción
W-->>A: Respuesta con ID
A->>A: Actualiza Payment con wompiTransactionId
A-->>F: { paymentId, asyncPaymentUrl? }
alt PSE/Bancolombia
F->>U: Redirige a banco (asyncPaymentUrl)
end
W->>A: Webhook (transaction.updated)
A->>A: Valida firma
A->>A: Actualiza Payment status
alt Pago exitoso + membershipId
A->>A: Activa/renueva membresía
end

Obtiene los métodos de pago habilitados y token de aceptación.

  • URL: /api/v1/payments/methods
  • Método: GET
  • Autenticación: No requerida
const res = await client.api.v1.payments.methods.$get()
// Respuesta
{
"data": {
"paymentMethods": [...],
"financialInstitutions": [...], // Bancos para PSE
"acceptanceToken": "eyJ...", // Token de aceptación de términos
"acceptancePermalink": "https://wompi.co/..."
}
}

Procesa un pago según el método seleccionado.

  • URL: /api/v1/payments/checkout
  • Método: POST
  • Autenticación:Member+
{
"paymentMethod": "CARD",
"amount": 150000,
"customerEmail": "usuario@email.com",
"token": "tok_test_xxxx", // Generado en frontend con Wompi.js
"installments": 1,
"membershipId": "clxxxx", // Opcional: activa membresía al aprobar
"customerData": {
"fullName": "Juan Pérez",
"phoneNumber": "3001234567",
"legalId": "1234567890",
"legalIdType": "CC"
},
"redirectUrl": "https://app.vitality-gym.com/payment/result"
}
{
"message": "Pago iniciado exitosamente",
"data": {
"paymentId": "clxxxx",
"wompiTransactionId": "1234-5678-abcd",
"status": "PENDING",
"asyncPaymentUrl": "https://..." // Solo para PSE/Bancolombia
}
}

Obtiene el estado actualizado de un pago desde Wompi.

  • URL: /api/v1/payments/:id/status
  • Método: GET
  • Autenticación:
const res = await client.api.v1.payments[":id"].status.$get({
param: { id: "payment_id" }
})

Anula/reembolsa un pago completado.

  • URL: /api/v1/payments/:id/refund
  • Método: POST
  • Autenticación:Admin
const res = await client.api.v1.payments[":id"].refund.$post({
param: { id: "payment_id" }
})

Para usar el Checkout Widget de Wompi en el frontend.

  • URL: /api/v1/payments/signature
  • Método: POST
  • Autenticación:
{
"reference": "VG-1234567890-ABC",
"amountInCents": 15000000,
"currency": "COP"
}

  1. Ir a Configuración > Webhooks en el panel de Wompi
  2. Agregar URL del webhook:
    • Sandbox: https://api-staging.vitality-gym.com/api/v1/payments/webhook
    • Producción: https://api.vitality-gym.com/api/v1/payments/webhook
  3. Seleccionar evento: transaction.updated
  4. Copiar la Events Key y configurarla en WOMPI_EVENTS_KEY
  • URL: /api/v1/payments/webhook
  • Método: POST
  • Autenticación: No (validación por firma)

El webhook realiza:

  1. Validación de firma usando SHA256 y la Events Key
  2. Búsqueda del pago por wompiTransactionId o wompiReference
  3. Actualización de estado si cambió
  4. Activación de membresía si el pago tiene membershipId y estado APPROVED
{
"event": "transaction.updated",
"data": {
"transaction": {
"id": "1234-5678-abcd",
"reference": "VG-CARD-1703721234-XYZ",
"status": "APPROVED",
"amount_in_cents": 15000000,
"customer_email": "usuario@email.com",
"payment_method_type": "CARD"
}
},
"signature": {
"properties": ["transaction.id", "transaction.status"],
"checksum": "abc123..."
},
"timestamp": 1703721300,
"environment": "test"
}

  • Crear cuenta en Wompi y verificar comercio
  • Obtener llaves de producción del panel de Wompi
  • Configurar variables de entorno:
    Terminal window
    WOMPI_SANDBOX=false
    WOMPI_PUBLIC_KEY=pub_prod_xxxx
    WOMPI_PRIVATE_KEY=prv_prod_xxxx
    WOMPI_EVENTS_KEY=prod_events_xxxx
    WOMPI_INTEGRITY_KEY=prod_integrity_xxxx
  • Configurar webhook en panel de Wompi (URL de producción)
  • Probar flujo completo con tarjeta de prueba de Wompi
  • Verificar que la URL del webhook sea accesible públicamente (HTTPS)
  • Configurar redirectUrl a la URL de producción del frontend
TarjetaNúmeroResultado
Visa4242 4242 4242 4242Aprobada
Mastercard5555 5555 5555 4444Aprobada
Visa4111 1111 1111 1111Rechazada

CVV: cualquier 3 dígitos. Fecha: cualquier fecha futura.


  • URL: /api/v1/payments
  • Método: POST
  • Autenticación:Admin Staff

Para registrar pagos en efectivo o externos.

{
"userProfileId": "user_id",
"amount": 150000,
"method": "CASH",
"status": "COMPLETED",
"description": "Pago en efectivo - Membresía mensual"
}

  • URL: /api/v1/payments
  • Método: GET
  • Autenticación:

Members ven solo sus pagos. Admin/Staff ven todos.

Filtros disponibles:

  • status: PENDING, COMPLETED, FAILED, REFUNDED
  • method: CREDIT_CARD, NEQUI, PSE, etc.
  • userProfileId: ID del usuario
  • startDate / endDate: Rango de fechas
  • minAmount / maxAmount: Rango de montos

  • URL: /api/v1/payments/:id
  • Método: PATCH
  • Autenticación:Admin Staff
{
"status": "COMPLETED",
"description": "Actualización manual"
}

  • URL: /api/v1/payments/:id
  • Método: DELETE
  • Autenticación:Admin