API de Links de Pago
Genera enlaces de pago dinámicamente desde tu backend.
Crear Link de Pago
Este endpoint te permite crear un enlace de pago configurado específicamente para una orden o cliente.
POST /v1/paymentlink
curl -X POST https://api.pabilo.app/v1/paymentlink \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_API_KEY" \
-d '{
"amount": 50.00,
"currency": "USD",
"description": "Orden #1234 - Pack Premium",
"notification_by_whastapp": false,
"webhook_url": "https://tu-sitio.com/webhook/pabilo",
"user_bank_id": "ID_DE_TU_CUENTA_BANCARIA",
"client_id": "ID_DEL_CLIENTE",
"items": [
{ "product_id": "6a7c...", "quantity": 1 },
{ "name": "Envío", "unit_price": 10, "quantity": 1 }
],
"redirect_url": "https://tu-sitio.com/gracias",
"expiration_time": 1440,
"rate_expiration_time": 120
}'Parámetros
- items (opcional): Desglose de lo que se cobra. Si se envía este campo, el campo
amountes ignorado y el total se calcula sumando el precio de cada ítem. Los ítems pueden referenciar tu catálogo (conproduct_id) o ser líneas ad-hoc (connameyunit_price). - client_id (opcional): ID del cliente al que va dirigido el cobro.
- amount: Monto a cobrar. Se ignora si envías
items. - currency (opcional): Moneda del monto:
VEF(Bolívares, por defecto),USD,EURoUSDT. Para monedas distintas deVEF, el monto se convierte a Bolívares con la tasa vigente al momento de validar el pago. - webhook_url: URL donde enviaremos una notificación POST cuando el pago sea verificado.
- redirect_url: URL a donde redirigiremos al usuario tras un pago exitoso.
- user_bank_id: ID de la cuenta bancaria donde quieres recibir el dinero. Ver cómo copiarlo desde el Dashboard →
- expiration_time (opcional): Tiempo de expiración del enlace en minutos desde su creación. Si no se envía o se envía vacío, el enlace expira en 24 horas (1440 minutos). Envía
-1para que el enlace nunca expire.
Ejemplos:2→ expira en 2 minutos ·60→ expira en 1 hora ·1440→ expira en 24 horas ·-1→ sin expiración. - rate_expiration_time (opcional, solo monedas ≠ VEF): Minutos que la tasa de cambio queda congelada en el enlace. Por defecto 60 (1 hora). Mientras esté vigente, todos pagan con la misma tasa; al vencer se actualiza automáticamente. La respuesta incluye
rate_exchange(tasa Bs por unidad),rate_updated_atyrate_expiration_time; la validez esrate_updated_at + rate_expiration_time.
Respuesta
json
{
"id": "pl_abc123...",
"url": "https://pabilo.app/pay/pl_abc123...",
"amount": 50.00,
"status": "active",
"client_id": "ID_DEL_CLIENTE",
"items": [
{
"product_id": "6a7c...", "name": "Producto Premium",
"quantity": 1, "unit_price": 40, "currency": "USD"
},
{ "name": "Envío", "quantity": 1, "unit_price": 10, "currency": "USD" }
]
}Obtener Link por ID
GET /paymentlink/{id}
curl -X GET https://api.pabilo.app/paymentlink/pl_abc123... \
-H "Authorization: Bearer TU_API_KEY"Webhooks
Cuando un pago es procesado, el sistema envía automáticamente una notificación POST al webhook_url configurado con información detallada de la transacción.
Estructura del Webhook
El webhook envía un objeto JSON con la siguiente estructura:
json
{
"payment_link_id": "675725869e6febc736848bf1",
"status": "paid",
"credit_balance": 150.50,
"payment_link": {
"id": "675725869e6febc736848bf1",
"created_at": "2026-02-12T18:00:00Z",
"updated_at": "2026-02-12T18:05:30Z",
"name": "Pago de Servicio",
"amount": 100.00,
"currency": "VEF",
"description": "Pago mensual de hosting",
"notification_by_whastapp": true,
"webhook_url": "https://myapp.com/webhooks/payment",
"webhook_method": "POST",
"user_bank_id": "675725869e6febc736848bf2",
"user_id": "675725869e6febc736848bf3",
"status": "paid",
"status_detail": "",
"url": "https://pabilo.app/pay/675725869e6febc736848bf1",
"redirect_url": "https://myapp.com/success",
"with_subscription_id": null,
"type": "api",
"client_id": "675725869e6febc736848bf5",
"items": [
{
"name": "Pago mensual de hosting",
"quantity": 1,
"unit_price": 100.00,
"currency": "VEF"
}
]
},
"user_bank_payment": {
"id": "675725869e6febc736848bf4",
"created_at": "2026-02-12T18:05:30Z",
"updated_at": "2026-02-12T18:05:30Z",
"bank_reference_id": "0025513902095",
"user_id": "675725869e6febc736848bf3",
"amount": 100.00,
"user_bank_id": "675725869e6febc736848bf2",
"status": "paid",
"credit_cost": 2.0
}
}Campos Principales
- payment_link_id: ID del link de pago
- status: Estado del pago (
paid,failed,pending,canceled,expired) - credit_balance: Balance de créditos actual del usuario
- payment_link: Objeto completo del link de pago con todos sus detalles
- user_bank_payment: Detalles de la transacción bancaria (null si el pago falló)
Ejemplo de Pago Fallido
json
{
"payment_link_id": "675725869e6febc736848bf1",
"status": "failed",
"credit_balance": 148.50,
"payment_link": {
"id": "675725869e6febc736848bf1",
"status": "failed",
"status_detail": "payment not found: bank API returned status 400",
...
},
"user_bank_payment": null
}Mejores Prácticas
- Idempotencia: Usa
payment_link_idpara evitar procesamiento duplicado - Validación: Siempre verifica el campo
statusantes de procesar - Verificación de Monto: Cruza el monto en
user_bank_payment.amountcon el monto esperado - Respuesta: Tu endpoint debe retornar un código HTTP 2xx para confirmar la recepción
- Errores: Revisa
payment_link.status_detailpara detalles de pagos fallidos
Mensajes de Error Comunes
"payment not found": Transacción no encontrada en el banco"payment already exists": Referencia de pago duplicada"bank not available": API del banco temporalmente no disponible"payment amount not valid": El monto no coincide