PayBoom API Reference v1.0

Unified REST API for payment processing in Mexico. Integrates multiple payment processors under a single technical interface: bank transfers, cash and in-store payments, referenced deposits, and credit/debit cards with 3D Secure support.

API REST unificada para procesamiento de pagos en Mexico. Integra multiples procesadores de pago bajo una sola interfaz tecnica: transferencias bancarias, pagos en efectivo y ventanilla, depositos referenciados, y tarjetas de credito/debito con soporte para 3D Secure.

Django 5.1 REST API MySQL Bearer Auth

Base URL

https://api.payboom.io

Quick Start

  1. Get your API Key
    Request your integration credentials. You will receive an api_key with format pb_ak_... and a MID (Merchant ID).
    Obtener tu API Key
    Solicita tus credenciales de integracion. Recibiras un api_key con formato pb_ak_... y un MID (Merchant ID).
  2. Choose a payment method
    Use POST /directbank for transfers and cash, or POST /directcard for credit/debit cards.
    Elegir metodo de pago
    Usa POST /directbank para transferencias y efectivo, o POST /directcard para tarjetas de credito/debito.
  3. Redirect the payer
    For DirectBank, redirect the user to the URL received in bank_response.url. For DirectCard, process the response or redirect to the 3DS challenge.
    Redirigir al pagador
    Para DirectBank, redirige al usuario a la URL recibida en bank_response.url. Para DirectCard, procesa la respuesta o redirige al challenge 3DS.
  4. Receive notification
    PayBoom will send a POST to your notifyUrl when the payment changes state.
    Recibir notificacion
    PayBoom enviara un POST a tu notifyUrl cuando el pago cambie de estado.

Architecture

Arquitectura

Your MerchantTu Comercio
PayBoom API
Bank TransferTransferencia Bancaria
In-Store PaymentPago en Ventanilla
Cash PaymentPago en Efectivo
Credit/Debit CardTarjeta de Credito/Debito

Your merchant integrates a single API. PayBoom routes to the corresponding processor based on the bank_code. Check the bank directory for available codes.

Tu comercio integra una sola API. PayBoom enruta al procesador correspondiente segun el bank_code. Consulta el directorio de bancos para obtener los codigos disponibles.

Authentication

Autenticacion

All endpoints require authentication via a Bearer Token in the Authorization header.

Todos los endpoints requieren autenticacion via Bearer Token en el header Authorization.

HTTP Header
Authorization: Bearer pb_ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API Key FormatFormato del API Key PayBoom API Keys follow the format pb_ak_ followed by 48 URL-safe alphanumeric characters. The API Key must have Active status to be valid. Las API Keys de PayBoom siguen el formato pb_ak_ seguido de 48 caracteres alfanumericos URL-safe. El API Key debe tener estado Activo para ser valido.

Permissions per Bank

Permisos por Banco

Each API Key has specific permissions per payment processor (bank_code). If you try to use a processor without permission, you will receive a 403 error.

Cada API Key tiene permisos especificos por procesador de pago (bank_code). Si intentas usar un procesador sin permiso, recibiras un error 403.

JSON — 403 Forbidden
{
  "error": "Unauthorized for this bank code",
  "status": 403
}
JSON — 401 Unauthorized
{
  "error": "Invalid or missing API key"
}
Exception: POST /payment requires no authenticationExcepcion: POST /payment no requiere autenticacion Unlike every other endpoint on this page, POST /payment does not check the Authorization header at all. Do not send your API Key expecting it to scope the request — it is ignored. See the endpoint's own page for details. A diferencia de cualquier otro endpoint de esta pagina, POST /payment no valida el header Authorization en absoluto. No envies tu API Key esperando que acote el request — se ignora. Ver la pagina propia del endpoint para mas detalle.

Direct Bank — Transfers & Cash

Direct Bank — Transferencias y Efectivo

The /directbank endpoint allows creating payments through methods other than card: bank transfers, in-store payments, referenced deposits, and cash payments. Each service is activated with a different bank_code.

El endpoint /directbank permite crear pagos a traves de metodos alternativos a la tarjeta: transferencias bancarias, pagos en ventanilla, depositos referenciados y pagos en efectivo. Cada servicio se activa con un bank_code diferente.

Payment Channels

Canales de Pago

PayBoom supports several payment channels through /directbank. The channel is determined by the bank_code you send in the request.

PayBoom soporta diversos canales de pago a traves de /directbank. El canal se determina por el bank_code que envies en el request.

ChannelCanalDescriptionDescripcionUser experienceExperiencia del usuario
Bank TransferTransferencia bancariaPayment via interbank transfer. Available 24/7.Pago via transferencia interbancaria. Disponible 24/7.The user receives a CLABE and bank details to transfer from their online banking or mobile app.El usuario recibe una CLABE y datos bancarios para transferir desde su banca en linea o app movil.
In-Store / Cash PaymentPago en ventanilla / efectivoCash payment at authorized physical points (convenience stores, retail chains).Pago en efectivo en puntos fisicos autorizados (tiendas de conveniencia, cadenas comerciales).The user receives a barcode or payment reference to present at the store.El usuario recibe un codigo de barras o referencia de pago que presenta en la tienda.
Referenced DepositDeposito referenciadoBank deposit with a unique assigned reference.Deposito bancario con referencia unica asignada.The user makes a deposit at a bank counter or transfer using the provided reference.El usuario realiza un deposito en ventanilla bancaria o transferencia con la referencia proporcionada.
Bank DirectoryDirectorio de bancos Check the GET /banks endpoint to get the full list of bank_code values available to your merchant, with their channels and description. Each code activates a specific rule engine and user flow. Consulta el endpoint GET /banks para obtener el listado completo de bank_code disponibles para tu comercio, con sus canales y descripcion. Cada codigo activa un motor de reglas y flujo de usuario especifico.
POST /directbank Create payment by transfer or cashCrear pago por transferencia o efectivo
Auth: Authorization: Bearer {api_key}

Request Body

Request Body

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
bank_codestring*Payment service code. Check the bank directory (GET /banks) for available codes.Codigo del servicio de pago. Consulta el directorio de bancos (GET /banks) para obtener los codigos disponibles.
amountnumber*Total transaction amountMonto total de la transaccion
mchOrderNostring*Your merchant's unique order IDID unico de orden de tu comercio
currencystring*Currency. Must be "MXN"Moneda. Debe ser "MXN"
notifyUrlstring*URL where PayBoom will send the payment status notificationURL donde PayBoom enviara la notificacion del estado del pago
shopperobject*Payer information (see shopper object below)Informacion del pagador (ver objeto shopper abajo)

shopper object

Objeto shopper

FieldCampoTypeTipoDescriptionDescripcion
first_namestringBuyer's first name(s)Nombre(s) del comprador
last_namesstringBuyer's last namesApellidos del comprador
phone_numberstringPhone numberNumero de telefono
tax_id_typestringTax ID type (e.g. CURP, RFC)Tipo de identificacion fiscal (e.g. CURP, RFC)
tax_idstringBuyer's tax IDIdentificacion fiscal del comprador

Additional optional fields

Campos opcionales adicionales

Some processors may require additional fields. Check the bank directory for the specific fields of each bank_code.

Algunos procesadores pueden requerir campos adicionales. Consulta el directorio de bancos para conocer los campos especificos de cada bank_code.

FieldCampoTypeTipoDescriptionDescripcion
emailstringBuyer's emailEmail del comprador
country_codestringCountry code (e.g. "MX")Codigo de pais (e.g. "MX")
bank_idstringDestination bank ID (when applicable)ID del banco destino (cuando aplica)
payment_ok_urlstringRedirect URL on successURL de redireccion en caso de exito
payment_error_urlstringRedirect URL on errorURL de redireccion en caso de error
expiration_time_minutesnumberExpiration time in minutes (default: 2880)Tiempo de expiracion en minutos (default: 2880)
JSON
{
  "bank_code": "1001",
  "amount": 500.00,
  "mchOrderNo": "ORD-2026-00123",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/payboom",
  "shopper": {
    "first_name": "Juan",
    "last_names": "Perez Lopez",
    "phone_number": "5551234567",
    "tax_id_type": "CURP",
    "tax_id": "PELJ900101HDFRPN09"
  }
}
JSON — 200 OK
{
  "success": true,
  "payboom_reference": "pb_20260415120530123_93dfbb",
  "mchOrderNo": "ORD-2026-00123",
  "amount": 500.00,
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/payboom",
  "bank_response": {
    "resCode": "SUCCESS",
    "url": "https://payment.sipelatam.mx/pay/order/12345"
  }
}
cURL
curl -X POST https://api.payboom.io/directbank \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "bank_code": "1001",
    "amount": 500.00,
    "mchOrderNo": "ORD-2026-00123",
    "currency": "MXN",
    "notifyUrl": "https://mi-sitio.com/webhook/payboom",
    "shopper": {
      "first_name": "Juan",
      "last_names": "Perez Lopez",
      "phone_number": "5551234567",
      "tax_id_type": "CURP",
      "tax_id": "PELJ900101HDFRPN09"
    }
  }'
Key field: bank_response.urlCampo clave: bank_response.url Redirect the user to this URL to complete the payment. Depending on the channel, they will see bank transfer details, a barcode for cash payment, or referenced deposit instructions. Redirige al usuario a esta URL para que complete el pago. Segun el canal, vera datos de transferencia bancaria, un codigo de barras para pago en efectivo, o instrucciones de deposito referenciado.

Cobre SPEI MXN response (bank_code 1025)

Respuesta SPEI MXN de Cobre (bank_code 1025)

When bank_code points to a Cobre SPEI MXN bank (currently 1025), bank_response has a different shape: instead of resCode/url, PayBoom returns a one-time CLABE generated for that charge.

Cuando el bank_code apunta a un banco SPEI MXN de Cobre (actualmente 1025), bank_response tiene una forma distinta: en vez de resCode/url, PayBoom retorna una CLABE generada especificamente para ese cobro.

JSON — 200 OK (Cobre SPEI MXN)
{
  "success": true,
  "payboom_reference": "pb_20260827120530123_93dfbb",
  "mchOrderNo": "ORD-2026-00456",
  "amount": 500.00,
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/payboom",
  "bank_response": {
    "clabe": "703010520043000151",
    "bank_name": "TESORED",
    "beneficiary": "PAYBOOM",
    "expires_at": "2026-08-29T05:57:52Z",
    "provider_reference": "mm_gOSG3A5yEPKuP1",
    "raw": { "...": "..." }
  }
}
FieldCampoTypeTipoAlways presentSiempre presenteDescriptionDescripcion
clabestringyessiOne-time 18-digit CLABE generated for this charge. Do not reuse it for other orders.CLABE de 18 digitos generada para este cobro. No la reutilices para otras ordenes.
bank_namestringoptionalopcionalDestination bank name. Configured per bank — omitted entirely when not configured, never sent as an empty string.Nombre del banco destino. Se configura por banco — se omite por completo cuando no esta configurado, nunca se manda como cadena vacia.
beneficiarystringoptionalopcionalBeneficiary name. Same rule as bank_name: configured per bank, omitted entirely when not configured.Nombre del beneficiario. Misma regla que bank_name: se configura por banco, se omite por completo cuando no esta configurado.
expires_atstring (ISO 8601 UTC)yessiDeadline to complete the SPEI transfer to this CLABE.Fecha limite para completar la transferencia SPEI a esta CLABE.
provider_referencestringyessiCobre's money movement ID for this charge.ID del money movement de Cobre para este cobro.
rawobjectyessiRaw response from the provider. Its shape is not part of the contract — use it for debugging only.Respuesta cruda del proveedor. Su forma no es parte del contrato — usala solo para depuracion.
Do not assume bank_name and beneficiary are presentNo asumas que bank_name y beneficiary estan presentes Both fields are optional and configured per bank — a bank without them configured simply omits them from the response. A SPEI transfer needs more than a CLABE: the payer's banking app also asks for the destination bank and the beneficiary name, so display these two fields alongside the CLABE whenever they are present, but never assume they will be. Ambos campos son opcionales y se configuran por banco — un banco sin configurarlos simplemente los omite de la respuesta. Una transferencia SPEI necesita mas que una CLABE: la app bancaria del pagador tambien pide el banco destino y el nombre del beneficiario, asi que muestra estos dos campos junto a la CLABE cuando esten presentes, pero nunca asumas que lo estaran.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Missing required fields, invalid currency, or inactive bankCampos requeridos faltantes, moneda invalida o banco inactivo
401Invalid or missing API KeyAPI Key invalida o ausente
403No permission for the requested bank_codeSin permiso para el bank_code solicitado
500Payment provider errorError del proveedor de pago
501Bank integration not implementedIntegracion del banco no implementada

Payment Flow

Flujo de Pago

Regardless of the payment channel, the flow always follows the same pattern:

Independientemente del canal de pago, el flujo siempre sigue el mismo patron:

1. Your backend makes POST /directbank with the corresponding bank_codeTu backend hace POST /directbank con el bank_code correspondiente
2. PayBoom returns bank_response.url with the payment page for the selected channelPayBoom retorna bank_response.url con la pagina de pago del canal seleccionado
3. Redirect the user to the URL → depending on the channel, they will see transfer details, a barcode, a deposit reference, etc.Redirige al usuario a la URL → segun el canal, vera datos de transferencia, un codigo de barras, una referencia de deposito, etc.
4. When the payment is confirmed, PayBoom sends a POST to your notifyUrl with status depositCuando el pago es confirmado, PayBoom envia POST a tu notifyUrl con status deposit
Bank DirectoryDirectorio de bancos Check GET /banks to get the full list of bank_code values available to your merchant. The directory includes the channel, service name, and status of each processor. Consulta GET /banks para obtener la lista completa de bank_code disponibles para tu comercio. El directorio incluye el canal, nombre del servicio y estado de cada procesador.

Webhooks — Payment Notifications

Webhooks — Notificaciones de Pago

When a payment's status changes, PayBoom sends a POST to the URL you specified in notifyUrl. Never assume a payment was successful based on the redirect; always wait for the webhook confirmation.

Cuando el estado de un pago cambia, PayBoom envia un POST a la URL que especificaste en notifyUrl. Nunca asumas que un pago fue exitoso por la redireccion; espera siempre la confirmacion del webhook.

JSON — Notification to merchantJSON — Notificacion al comercio
{
  "api_key_id": 2007,
  "payboom_reference": "pb_20260415120530123_93dfbb",
  "provider_reference": "PROVIDER-TX-789456",
  "reference": "ORD-2026-00123",
  "bank_code": "1001",
  "amount": 500.00,
  "currency": "MXN",
  "status": "deposit"
}
Payload fieldsCampos del payload For cash/transfer channels (SPEI, ENEFEVO, OXXO), the confirmation status is deposit, reference echoes your order ID, and amount is a number. Card and recurring channels send a different shape (they include authorization and use APPROVED/DECLINED). Para canales de efectivo/transferencia (SPEI, ENEFEVO, OXXO), el status de confirmacion es deposit, reference refleja tu ID de orden y amount es numerico. Los canales de tarjeta y recurrentes envian un formato distinto (incluyen authorization y usan APPROVED/DECLINED).
Signature verificationVerificacion de firmas PayBoom validates the cryptographic signature of each provider notification before processing it. Your notifyUrl endpoint must respond with HTTP 200 to confirm receipt. PayBoom valida la firma criptografica de cada notificacion del proveedor antes de procesarla. Tu endpoint notifyUrl debe responder con HTTP 200 para confirmar recepcion.

Direct Card — Card Payments

Direct Card — Pagos con Tarjeta

The /directcard endpoint allows processing credit and debit card payments. There are two possible payment flows:

El endpoint /directcard permite procesar pagos con tarjeta de credito y debito. Existen dos flujos de pago posibles:

FlowFlujoDescriptionDescripcionResponseRespuesta
Authorization & CaptureAutorizacion y CapturaTraditional payment where authorization and capture happen in the same request. Immediate response.Pago tradicional donde la autorizacion y captura se realizan en el mismo request. Respuesta inmediata.APPROVED oro DECLINED
3D Secure (3DS)Payment with issuer-bank authentication. Requires user redirect to complete a challenge (OTP, biometrics, etc.).Pago con autenticacion del banco emisor. Requiere redireccion del usuario para completar un challenge (OTP, biometria, etc.).PENDING + redirect_url
Bank DirectoryDirectorio de bancos Check GET /banks for the bank_code values available for card payments in your merchant. The flow type (traditional or 3DS) depends on the processor assigned to each bank_code.Consulta GET /banks para obtener los bank_code disponibles para pagos con tarjeta en tu comercio. El tipo de flujo (tradicional o 3DS) depende del procesador asignado a cada bank_code.
Restricted hoursHorario restringido Card transactions are blocked between 1:00 AM and 5:59 AM (CDMX time). Payments sent during that window are automatically rejected with code P07.Las transacciones con tarjeta se bloquean entre 1:00 AM y 5:59 AM (hora CDMX). Pagos enviados en ese horario seran rechazados automaticamente con codigo P07.
POST /directcard Create payment with credit/debit cardCrear pago con tarjeta de credito/debito
Auth: Authorization: Bearer {api_key}

Request Body

Request Body

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
bank_codestring*Card processor code. Check the bank directory (GET /banks).Codigo del procesador de tarjetas. Consulta el directorio de bancos (GET /banks).
amountnumber*Total transaction amountMonto total de la transaccion
idstring*Your merchant's unique order ID (returned as mchOrderNo)ID unico de orden de tu comercio (se devuelve como mchOrderNo)
currencystring*ISO 4217 currency (e.g. "MXN"). Supported currency depends on the bank_code.Moneda ISO 4217 (e.g. "MXN"). La moneda soportada depende del bank_code.
notifyUrlstring*URL to receive the result notificationURL para recibir la notificacion del resultado
emailstring*Cardholder emailEmail del tarjetahabiente
cardobject*Card data (see card object)Datos de la tarjeta (ver objeto card)
shopperobject*Buyer data (see shopper object)Datos del comprador (ver objeto shopper)
descriptionstringoptionalopcionalTransaction descriptionDescripcion de la transaccion
successUrlstringoptionalopcionalRedirect URL after successful payment (required for 3DS)URL de redireccion tras pago exitoso (necesaria para 3DS)
errorUrlstringoptionalopcionalRedirect URL after failed payment (required for 3DS)URL de redireccion tras pago fallido (necesaria para 3DS)
term_url_3dsstringoptionalopcional3DS terminal URL (overrides successUrl for 3DS redirects)URL terminal 3DS (sobreescribe successUrl para redirects 3DS)

card object

Objeto card

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
holderNamestring*Cardholder name as it appears on the cardNombre del tarjetahabiente tal como aparece en la tarjeta
cardNumberstring*Full card number (PAN)Numero completo de la tarjeta (PAN)
expiryYearstring*Expiration year (4 digits, e.g. "2028")Ano de expiracion (4 digitos, e.g. "2028")
expiryMonthstring*Expiration month (1-12, e.g. "12")Mes de expiracion (1-12, e.g. "12")
cvvstring*Security code (CVV/CVC)Codigo de seguridad (CVV/CVC)

shopper object

Objeto shopper

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
first_namestring*Buyer's first nameNombre del comprador
last_namestring*Buyer's last nameApellido del comprador
phonestring*Buyer's phoneTelefono del comprador
statestring*State/provinceEstado/provincia
citystring*CityCiudad
addressstring*Full addressDireccion completa
postal_codestring*Postal codeCodigo postal
customer_ipstring*Buyer's IP addressDireccion IP del comprador
countrystringoptionalopcionalCountry code (e.g. "MX")Codigo de pais (e.g. "MX")
CurrencyMoneda The accepted currency depends on the processor assigned to the bank_code. Check the bank directory for the supported currency. If you send an incorrect currency you will receive a 400 error.La moneda aceptada depende del procesador asignado al bank_code. Consulta el directorio de bancos para verificar la moneda soportada. Si envias una moneda incorrecta recibiras un error 400.

Authorization & Capture (Traditional Payment)

Autorizacion y Captura (Pago Tradicional)

In the traditional flow, authorization and capture are done in a single request. The response is immediate: APPROVED or DECLINED. No user redirect required.

En el flujo tradicional, la autorizacion y captura se realizan en un solo request. La respuesta es inmediata: APPROVED o DECLINED. No requiere redireccion del usuario.

1. Your backend makes POST /directcard with card and buyer dataTu backend hace POST /directcard con datos de tarjeta y comprador
2. PayBoom validates the card, verifies permissions, and runs velocity checksPayBoom valida la tarjeta, verifica permisos y ejecuta chequeos de velocidad
3. Returns an immediate response with status: "APPROVED" or "DECLINED"Retorna respuesta inmediata con status: "APPROVED" o "DECLINED"
JSON — Authorization & CaptureJSON — Autorizacion y Captura
{
  "bank_code": "{bank_code}",
  "amount": 299.99,
  "id": "ORD-CARD-001",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/card",
  "email": "juan@email.com",
  "card": {
    "holderName": "JUAN PEREZ LOPEZ",
    "cardNumber": "4111111111111111",
    "expiryYear": "2028",
    "expiryMonth": "12",
    "cvv": "123"
  },
  "shopper": {
    "first_name": "Juan",
    "last_name": "Perez",
    "phone": "5551234567",
    "state": "CDMX",
    "city": "Ciudad de Mexico",
    "address": "Av. Reforma 222, Col. Juarez",
    "postal_code": "06600",
    "customer_ip": "189.203.45.67",
    "country": "MX"
  }
}
JSON — 200 OK (Approved)JSON — 200 OK (Aprobada)
{
  "success": true,
  "status": "APPROVED",
  "authorization": "AUTH789456",
  "payboom_reference": "pb_20260415130045789_a1b2c3",
  "mchOrderNo": "ORD-CARD-001",
  "provider_reference": "PROVIDER-TX-123456",
  "amount": "299.99",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/card",
  "redirect_url": "",
  "bank_response": {
    "resp_code": "00",
    "description": "Transaccion aprobada"
  }
}
JSON — 200 (Declined)JSON — 200 (Rechazada)
{
  "success": false,
  "status": "DECLINED",
  "authorization": "",
  "payboom_reference": "pb_20260415130050123_d4e5f6",
  "mchOrderNo": "ORD-CARD-002",
  "provider_reference": "",
  "amount": "299.99",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/card",
  "redirect_url": "",
  "bank_response": {
    "resp_code": "51",
    "description": "Fondos insuficientes"
  }
}

3D Secure (3DS) Payment

Pago con 3D Secure (3DS)

Some processors require 3D Secure authentication. When the processor determines issuer-bank verification is needed, the response includes a redirect_url where you must redirect the user to complete the challenge.

Algunos procesadores requieren autenticacion 3D Secure. Cuando el procesador determina que se necesita verificacion del banco emisor, la respuesta incluye un redirect_url al que debes redirigir al usuario para completar el challenge.

Required fields for 3DSCampos requeridos para 3DS When using 3DS processors, it's important to include successUrl and errorUrl in the request. These URLs are used to redirect the user after the 3DS challenge.Cuando uses procesadores con 3DS, es importante incluir successUrl y errorUrl en el request. Estas URLs se usan para redirigir al usuario despues del challenge 3DS.
1. Your backend makes POST /directcard with card data + successUrl + errorUrlTu backend hace POST /directcard con datos de tarjeta + successUrl + errorUrl
2. PayBoom returns status: "PENDING" and a redirect_url → redirect the user therePayBoom retorna status: "PENDING" y un redirect_url → redirige al usuario ahi
3. The user completes the 3DS challenge on the issuer bank's page (OTP, biometrics, etc.)El usuario completa el challenge 3DS en la pagina del banco emisor (OTP, biometria, etc.)
4. The bank redirects to PayBoom's callback, which verifies the result and updates the transactionEl banco redirige al callback de PayBoom, que verifica el resultado y actualiza la transaccion
5. PayBoom redirects the user to your successUrl or errorUrl and sends POST to notifyUrlPayBoom redirige al usuario a tu successUrl o errorUrl y envia POST a notifyUrl
JSON — 3DS RequestJSON — Request 3DS
{
  "bank_code": "{bank_code}",
  "amount": 1500.00,
  "id": "ORD-3DS-001",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/card",
  "email": "cliente@email.com",
  "successUrl": "https://mi-sitio.com/pago-exitoso",
  "errorUrl": "https://mi-sitio.com/pago-error",
  "card": {
    "holderName": "CARLOS RODRIGUEZ",
    "cardNumber": "5500000000000004",
    "expiryYear": "2027",
    "expiryMonth": "06",
    "cvv": "456"
  },
  "shopper": {
    "first_name": "Carlos",
    "last_name": "Rodriguez",
    "phone": "5559876543",
    "state": "Jalisco",
    "city": "Guadalajara",
    "address": "Av. Vallarta 1234",
    "postal_code": "44100",
    "customer_ip": "201.141.78.90",
    "country": "MX"
  }
}
JSON — 200 (Redirect to 3DS)JSON — 200 (Redirect a 3DS)
{
  "success": true,
  "status": "PENDING",
  "authorization": "",
  "payboom_reference": "pb_20260415140012345_x1y2z3",
  "mchOrderNo": "ORD-3DS-001",
  "provider_reference": "PROVIDER-EXT-789",
  "amount": "1500.00",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/card",
  "redirect_url": "https://procesador.com/3ds/challenge/PROVIDER-EXT-789",
  "bank_response": {
    "status": "REDIRECT",
    "external_id": "PROVIDER-EXT-789",
    "redirection_url": "https://procesador.com/3ds/challenge/PROVIDER-EXT-789"
  }
}
Action requiredAccion requerida When status is "PENDING" and there is a redirect_url, you must redirect the user to that URL to complete the 3DS challenge. Do not consider the payment approved until you receive the notification at notifyUrl.Cuando status es "PENDING" y hay un redirect_url, debes redirigir al usuario a esa URL para que complete el challenge 3DS. No consideres el pago como aprobado hasta recibir la notificacion en notifyUrl.
JSON — Webhook notifyUrl (POST)
{
  "payboom_reference": "pb_20260415140012345_x1y2z3",
  "mchOrderNo": "ORD-3DS-001",
  "status": "APPROVED",
  "amount": "1500.00",
  "currency": "MXN",
  "provider_reference": "PROVIDER-EXT-789",
  "bank_code": "{bank_code}",
  "authorization": "AUTH-3DS-456"
}

State Flow — 3DS

Flujo de estados — 3DS

POST /directcard
PENDING + redirect_url
User completes 3DS challengeUsuario completa challenge 3DS
successexito
APPROVED
→ successUrl
failurefallo
DECLINED
→ errorUrl

Webhooks & Callbacks (Cards)

Webhooks y Callbacks (Tarjetas)

PayBoom handles two notification mechanisms for card payments:

PayBoom maneja dos mecanismos de notificacion para pagos con tarjeta:

MechanismMecanismoDescriptionDescripcionUseUso
notifyUrl (Webhook)Async POST to merchant backend with the final resultPOST asincrono al backend del comercio con el resultado finalUpdate the order status in your databaseActualizar el estado de la orden en tu base de datos
successUrl / errorUrl (Callback)User browser redirect after 3DSRedireccion del navegador del usuario tras el 3DSShow a confirmation or error page to the userMostrar al usuario una pagina de confirmacion o error
Critical securitySeguridad critica Never rely solely on the redirect to successUrl to confirm a payment. A malicious user could manually navigate to that URL. Always verify the real payment status using the notifyUrl webhook.Nunca confies solo en la redireccion a successUrl para confirmar un pago. Un usuario malintencionado podria navegar manualmente a esa URL. Siempre verifica el estado real del pago usando el webhook notifyUrl.

/directcard endpoint errors

Errores del endpoint /directcard

HTTP CodeCodigo HTTPDescriptionDescripcion
400Missing required fields, expired card, invalid JSON, or wrong currency for the processorCampos requeridos faltantes, tarjeta expirada, JSON invalido o moneda incorrecta para el procesador
401Invalid or missing API KeyAPI Key invalida o ausente
403No permission for the requested bank_codeSin permiso para el bank_code solicitado
429Velocity check failed (too many attempts with the same card)Chequeo de velocidad fallido (demasiados intentos con la misma tarjeta)
500Payment provider errorError del proveedor de pago
501Bank integration not implementedIntegracion del banco no implementada

Recurring Card Plans (UNLIMIT)

Planes de Tarjeta Recurrente (UNLIMIT)

The /recurrenceplan endpoint creates a recurring billing plan and subscribes a card to it via UNLIMIT. The first charge happens immediately as part of this call; UNLIMIT executes every following charge on its own schedule and notifies each result via notifyUrl, the same way Direct Card webhooks work.

El endpoint /recurrenceplan crea un plan de cobro recurrente y suscribe una tarjeta via UNLIMIT. El primer cobro ocurre de inmediato como parte de este mismo llamado; UNLIMIT ejecuta cada cobro siguiente segun su propio calendario y notifica cada resultado via notifyUrl, igual que los webhooks de Direct Card.

Only UNLIMIT bank codesSolo bank_codes de UNLIMIT The bank_code must belong to an active bank whose provider is UNLIMIT. Check the bank directory (GET /banks, providername) for which codes qualify. Sending any other bank_code returns 400. El bank_code debe pertenecer a un banco activo cuyo proveedor sea UNLIMIT. Consulta el directorio de bancos (GET /banks, providername) para saber que codigos califican. Enviar cualquier otro bank_code retorna 400.
POST /recurrenceplan Create a recurring plan and charge the first installmentCrear un plan recurrente y cobrar la primera cuota
Auth: Authorization: Bearer {api_key}

Request Body

Request Body

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
bank_codestring*UNLIMIT processor code (see callout above)Codigo del procesador UNLIMIT (ver aviso arriba)
amountnumber*Amount charged on every occurrence, including the first one made in this callMonto cobrado en cada ocurrencia, incluida la primera hecha en este llamado
idstring*Your merchant's unique order ID for the first charge (returned as mchOrderNo)ID unico de orden de tu comercio para el primer cobro (se devuelve como mchOrderNo)
currencystring*Must be "MXN" — UNLIMIT recurrence plans support no other currencyDebe ser "MXN" — los planes recurrentes de UNLIMIT no soportan otra moneda
recurrencestring*One of daily, biweekly, monthly, quarterly, biannual, annualUno de daily, biweekly, monthly, quarterly, biannual, annual
plan_namestring*Name of the plan, as it will be created on UNLIMITNombre del plan, tal como se creara en UNLIMIT
notifyUrlstring*URL where PayBoom / UNLIMIT will send each occurrence's result notificationURL donde PayBoom / UNLIMIT enviara la notificacion del resultado de cada ocurrencia
emailstring*Cardholder emailEmail del tarjetahabiente
cardobject*Card data to subscribe (see card object)Datos de la tarjeta a suscribir (ver objeto card)
shopperobject*Buyer data (see shopper object)Datos del comprador (ver objeto shopper)
descriptionstringoptionalopcionalMerchant description sent to UNLIMIT for the first chargeDescripcion del comercio enviada a UNLIMIT para el primer cobro
successUrlstringoptionalopcionalRedirect URL after a successful first charge (also used as the 3DS return URL when term_url_3ds is not sent)URL de redireccion tras un primer cobro exitoso (tambien usada como return URL de 3DS cuando no se envia term_url_3ds)
errorUrlstringoptionalopcionalRedirect URL after a failed first chargeURL de redireccion tras un primer cobro fallido
term_url_3dsstringoptionalopcional3DS return URL for the first charge. Falls back to successUrl, then to notifyUrl, when omitted. Same mechanics as Direct Card 3DS.URL de retorno 3DS para el primer cobro. Si se omite, usa successUrl y luego notifyUrl. Misma mecanica que 3DS de Direct Card.
localestringoptionalopcionalLocale passed to UNLIMIT for the 3DS challenge UI. Default "es".Locale enviado a UNLIMIT para la interfaz de reto 3DS. Default "es".
user_agentstringoptionalopcionalCardholder's browser user agent, forwarded to UNLIMIT for 3DS device dataUser agent del navegador del tarjetahabiente, reenviado a UNLIMIT para los datos de dispositivo 3DS

card object

Objeto card

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
holderNamestring*Cardholder name as it appears on the cardNombre del tarjetahabiente tal como aparece en la tarjeta
cardNumberstring*Full card number (PAN)Numero completo de la tarjeta (PAN)
expiryYearstring*Expiration year (4 digits, e.g. "2028")Ano de expiracion (4 digitos, e.g. "2028")
expiryMonthstring*Expiration month (1-12, e.g. "12")Mes de expiracion (1-12, e.g. "12")
cvvstring*Security code (CVV/CVC)Codigo de seguridad (CVV/CVC)

shopper object

Objeto shopper

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
first_namestring*Buyer's first nameNombre del comprador
last_namestring*Buyer's last nameApellido del comprador
phonestring*Buyer's phoneTelefono del comprador
statestring*State/provinceEstado/provincia
citystring*CityCiudad
addressstring*Full addressDireccion completa
postal_codestring*Postal codeCodigo postal
customer_ipstring*Buyer's IP addressDireccion IP del comprador
countrystringoptionalopcionalCountry code (e.g. "MX")Codigo de pais (e.g. "MX")
JSON
{
  "bank_code": "1021",
  "amount": 199.00,
  "id": "SUB-2026-00042",
  "currency": "MXN",
  "recurrence": "monthly",
  "plan_name": "Plan Premium Mensual",
  "notifyUrl": "https://mi-sitio.com/webhook/payboom",
  "successUrl": "https://mi-sitio.com/suscripcion/exito",
  "errorUrl": "https://mi-sitio.com/suscripcion/error",
  "email": "cliente@example.com",
  "shopper": {
    "first_name": "Juan",
    "last_name": "Perez",
    "phone": "5551234567",
    "state": "CDMX",
    "city": "CDMX",
    "address": "Av. Reforma 1",
    "postal_code": "06000",
    "customer_ip": "201.100.10.5"
  },
  "card": {
    "holderName": "JUAN PEREZ",
    "cardNumber": "4111111111111111",
    "expiryYear": "2028",
    "expiryMonth": "12",
    "cvv": "123"
  }
}
JSON — 200 OK (frictionless)
{
  "success": true,
  "status": "APPROVED",
  "authorization": "",
  "payboom_reference": "pb_20260827120530123_93dfbb",
  "mchOrderNo": "SUB-2026-00042",
  "provider_reference": "REC-9001",
  "plan_id": "PLAN-4521",
  "subscription_id": "SUB-3312",
  "recurrence": "monthly",
  "amount": "199.00",
  "currency": "MXN",
  "notifyUrl": "https://mi-sitio.com/webhook/payboom",
  "redirect_url": "",
  "bank_response": { "...": "..." }
}
cURL
curl -X POST https://api.payboom.io/recurrenceplan \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "bank_code": "1021",
    "amount": 199.00,
    "id": "SUB-2026-00042",
    "currency": "MXN",
    "recurrence": "monthly",
    "plan_name": "Plan Premium Mensual",
    "notifyUrl": "https://mi-sitio.com/webhook/payboom",
    "email": "cliente@example.com",
    "shopper": { "...": "..." },
    "card": { "...": "..." }
  }'
FieldCampoTypeTipoDescriptionDescripcion
successbooleantrue only when status is APPROVED or PENDING (3DS challenge)true solo cuando status es APPROVED o PENDING (reto 3DS)
statusstringResult of the first charge: APPROVED, PENDING (3DS challenge pending), or DECLINEDResultado del primer cobro: APPROVED, PENDING (reto 3DS pendiente), o DECLINED
payboom_referencestringPayBoom's internal reference for the first chargeReferencia interna de PayBoom para el primer cobro
mchOrderNostringEchoes the id you sentRepite el id que enviaste
provider_referencestringUNLIMIT's recurring/subscription charge IDID del cobro recurrente/suscripcion de UNLIMIT
plan_idstringUNLIMIT plan ID created for this callID del plan de UNLIMIT creado en este llamado
subscription_idstringUNLIMIT subscription ID. May be an empty string when a 3DS challenge is still pending.ID de suscripcion de UNLIMIT. Puede ser cadena vacia mientras un reto 3DS esta pendiente.
redirect_urlstring3DS challenge URL. Empty string when the first charge was frictionless (no challenge needed).URL del reto 3DS. Cadena vacia cuando el primer cobro fue frictionless (sin reto necesario).
bank_responseobjectRaw UNLIMIT response for the first charge. Not part of the contract — use for debugging only.Respuesta cruda de UNLIMIT para el primer cobro. No es parte del contrato — usala solo para depuracion.
Only the first charge is synchronousSolo el primer cobro es sincrono This call's response only reflects the outcome of the first charge. Every following occurrence is executed by UNLIMIT on its own schedule, off this request, and is reported exclusively via a notification to notifyUrl — there is no endpoint on this page to list or poll subsequent occurrences of a plan. La respuesta de este llamado solo refleja el resultado del primer cobro. Cada ocurrencia siguiente la ejecuta UNLIMIT segun su propio calendario, fuera de este request, y se reporta exclusivamente via una notificacion a notifyUrl — no hay un endpoint en esta pagina para listar o consultar las ocurrencias siguientes de un plan.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Missing required field, unsupported recurrence, expired card, currency other than MXN, or bank_code not an active UNLIMIT bankCampo requerido faltante, recurrence no soportada, tarjeta expirada, moneda distinta de MXN, o bank_code que no es un banco UNLIMIT activo
401Invalid or missing API KeyAPI Key invalida o ausente
403No permission for the requested bank_codeSin permiso para el bank_code solicitado
500UNLIMIT provider error while creating the plan or the first chargeError del proveedor UNLIMIT al crear el plan o el primer cobro

Direct Link — Colombia Payins (Cobre)

Direct Link — Payins Colombia (Cobre)

The /directlink endpoint creates payins in Colombia through Cobre Direct Link. Unlike /directbank, the merchant sends a payment type (slug) instead of a bank_code.

El endpoint /directlink crea payins en Colombia a traves de Cobre Direct Link. A diferencia de /directbank, el comercio envia un type (slug) de metodo de pago en lugar de un bank_code.

typeDescriptionDescripcion
psePSE bank redirect. The payer is redirected to select and authenticate with their bank.Redireccion bancaria PSE. El pagador es redirigido para seleccionar y autenticarse con su banco.
bancolombiaBancolombia app/web redirect payment.Pago con redireccion a la app/web de Bancolombia.
nequiPush payment request sent directly to the payer's Nequi app.Solicitud de pago push enviada directamente a la app Nequi del pagador.
breb_qrBre-B QR code payment.Pago con codigo QR Bre-B.
breb_keyBre-B Key (Llave) transfer payment.Pago por transferencia con Llave Bre-B.
POST /directlink Create a Colombia payin (PSE, Bancolombia, Nequi, Bre-B)Crear un payin Colombia (PSE, Bancolombia, Nequi, Bre-B)
Auth: Authorization: Bearer {api_key}

Request Body (common fields)

Request Body (campos comunes)

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
typestring*Payment type: pse, bancolombia, nequi, breb_qr, or breb_keyTipo de pago: pse, bancolombia, nequi, breb_qr o breb_key
amountnumber*Amount in major units (COP), must be > 0 (e.g. 50000 = $50,000 COP)Monto en unidades mayores (COP), debe ser > 0 (e.g. 50000 = $50,000 COP)
currencystring*Currency. Must be "COP"Moneda. Debe ser "COP"
mchOrderNostring*Your merchant's unique order IDID unico de orden de tu comercio
notifyUrlstring*Webhook URL where PayBoom will notify the resultURL del webhook donde PayBoom notificara el resultado
descriptionstringoptionalopcionalDescription shown to the payerDescripcion mostrada al pagador
payer_namestringoptionalopcionalPayer's nameNombre del pagador

Fields required per type

Campos requeridos por type

typeRequired fieldsCampos requeridosNotesNotas
pseemail, financial_institution_code, redirect_urlemail and financial_institution_code belong to the payer. Get the code from GET /directlink/banks.email y financial_institution_code son del pagador. Obten el codigo desde GET /directlink/banks.
bancolombiaredirect_url
nequiphone, redirect_urlphone is the payer's phone number registered with Nequiphone es el numero de telefono del pagador registrado en Nequi
breb_qrnoneningunoOptional valid_until (ISO date; default 5 minutes)Opcional valid_until (fecha ISO; default 5 minutos)
breb_keynoneningunoOptional key_config (name|random|id) and valid_untilOpcional key_config (name|random|id) y valid_until
JSON — pse exampleJSON — ejemplo pse
{
  "type": "pse",
  "amount": 50000,
  "currency": "COP",
  "mchOrderNo": "ORD-1",
  "notifyUrl": "https://tu-sitio/webhook",
  "email": "pagador@x.com",
  "financial_institution_code": "1070",
  "redirect_url": "https://tu-sitio/ok"
}
JSON — 201
{
  "success": true,
  "payboom_reference": "pb_20260720120000000_ab12cd",
  "provider_reference": "mm_bNCf3W9mdA062D",
  "type": "pse",
  "status": "PENDING",
  "instruction": {
    "type": "payment_link",
    "url": "https://registro.pse.com.co/PSENF/index.html?enc=_XXXX",
    "qr_value": null,
    "key_value": null,
    "expires_at": "2026-07-20T12:10:00Z"
  }
}
cURL
curl -X POST https://api.payboom.io/directlink \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "pse",
    "amount": 50000,
    "currency": "COP",
    "email": "pagador@x.com",
    "financial_institution_code": "1070",
    "redirect_url": "https://tu-sitio/ok",
    "mchOrderNo": "ORD-1",
    "notifyUrl": "https://tu-sitio/webhook"
  }'

instruction.type per rail

instruction.type por rail

typeinstruction.typeHow to use itComo usarlo
pse / bancolombiapayment_linkRedirect the payer to instruction.urlRedirige al pagador a instruction.url
nequipushThe payer receives a push notification in their Nequi app (no url)El pagador recibe una notificacion push en su app Nequi (no hay url)
breb_qrqrRender instruction.qr_value as a Bre-B QR codeRenderiza instruction.qr_value como codigo QR Bre-B
breb_keykeyShow instruction.key_value (the Bre-B Key) for the payer to transfer toMuestra instruction.key_value (la Llave Bre-B) para que el pagador transfiera
Status flowFlujo de estados The operation starts as PENDING. Once the payer completes the payment, PayBoom sends a POST to your notifyUrl with status: "deposit" (same format as the cash/transfer webhook — see Webhook Format). If the payment fails or expires, the operation ends as FAILED/EXPIRED, queryable with GET /operations/{reference}. La operacion inicia como PENDING. Cuando el pagador completa el pago, PayBoom envia un POST a tu notifyUrl con status: "deposit" (mismo formato que el webhook de efectivo/transferencia — ver Formato de Webhooks). Si el pago falla o expira, la operacion queda FAILED/EXPIRED, consultable con GET /operations/{reference}.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Invalid type, currency other than COP, missing required field, non-positive amount, or invalid bodyTipo (type) invalido, moneda distinta de COP, campo requerido faltante, amount no positivo, o body invalido
401Invalid or missing API KeyAPI Key invalida o ausente
403The merchant does not have this payment type enabledEl comercio no tiene este type de pago asociado
502Provider (Cobre) errorError del proveedor (Cobre)
GET /directlink/banks List PSE banksListar bancos PSE
Auth: Authorization: Bearer {api_key}

Returns the list of PSE banks to populate the payer's bank selector. Use the financial_institution_code value in the type: "pse" request.

Retorna el listado de bancos PSE para poblar el selector de banco del pagador. Usa el valor financial_institution_code en el request con type: "pse".

JSON — 200 OK
{
  "banks": [
    { "financial_institution_code": "1070", "name": "Lulo Bank" },
    { "financial_institution_code": "1007", "name": "Bancolombia" }
  ]
}

Cancel & RefundCancelar y Reembolsar

The cancel and refund endpoints allow reversing approved transactions. Availability of these operations depends on the processor assigned to each bank_code.

Los endpoints de cancelacion y reembolso permiten revertir transacciones aprobadas. La disponibilidad de estas operaciones depende del procesador asignado a cada bank_code.

POST /cancel Cancel an approved transactionCancelar una transaccion aprobada
Auth: Authorization: Bearer {api_key}

Request Body

Request Body

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
payboom_referencestring*PayBoom reference of the original transactionReferencia PayBoom de la transaccion original
amountnumber*Amount to cancelMonto a cancelar
JSON
{
  "payboom_reference": "pb_20260415130045789_a1b2c3",
  "amount": 299.99
}
JSON — 200 OK
{
  "success": true,
  "status": "CANCELLED",
  "payboom_reference": "pb_20260415150012345_new123",
  "original_payboom_reference": "pb_20260415130045789_a1b2c3",
  "provider_reference": "CANCEL-TX-789",
  "amount": 299.99,
  "bank_response": {}
}
ValidationsValidaciones The original transaction must belong to the authenticated merchant, have status APPROVED, SETTLED, or APROBADA, and have a provider reference.La transaccion original debe pertenecer al comercio autenticado, tener status APPROVED, SETTLED o APROBADA, y contar con una referencia del proveedor.
POST /refund Refund an approved transactionReembolsar una transaccion aprobada
Auth: Authorization: Bearer {api_key}

Same format as /cancel. The main difference is that some processors use a dedicated refund endpoint that may be available starting the day after the transaction.

Mismo formato que /cancel. La diferencia principal es que algunos procesadores usan un endpoint dedicado de reembolso que puede estar disponible a partir del dia siguiente a la transaccion.

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
payboom_referencestring*PayBoom reference of the original transactionReferencia PayBoom de la transaccion original
amountnumber*Amount to refundMonto a reembolsar
AvailabilityDisponibilidad Not all processors support cancellation and refund. Some processors only allow same-day cancellations and next-day refunds. Check the bank directory to verify the available operations for each bank_code.No todos los procesadores soportan cancelacion y reembolso. Algunos procesadores solo permiten cancelaciones el mismo dia y reembolsos a partir del dia siguiente. Consulta el directorio de bancos para verificar las operaciones disponibles para cada bank_code.

Withdrawals

Retiros

Six endpoints to check your balance, request a withdrawal to your registered CLABE, list and track withdrawals, manage the destination account, and receive the execution webhook. All require Authorization: Bearer {api_key} and permission on the requested bank_code, same as the rest of this API.

Seis endpoints para consultar tu saldo, solicitar un retiro a tu CLABE registrada, listar y rastrear retiros, administrar la cuenta destino, y recibir el webhook de ejecucion. Todos requieren Authorization: Bearer {api_key} y permiso sobre el bank_code solicitado, igual que el resto de esta API.

MXN only, for nowSolo MXN, por ahora Withdrawals only execute in MXN today. POST /withdrawals checks the currency of the requested bank_code up front and rejects a non-MXN bank with 422 currency_not_supported before anything is reserved — there is no cancel path for a pending withdrawal, so accepting one that could never execute would leave amount + fee + iva stuck against a balance with no way back. This is a known limitation, not a bug in your integration. Los retiros hoy solo se ejecutan en MXN. POST /withdrawals revisa la moneda del bank_code solicitado por adelantado y rechaza un banco que no sea MXN con 422 currency_not_supported antes de reservar nada — no existe forma de cancelar un retiro pendiente, asi que aceptar uno que jamas podria ejecutarse dejaria amount + fee + iva varado contra un saldo sin manera de recuperarlo. Es una limitacion conocida, no un error de tu integracion.
GET /balance Check your bank balanceConsultar el saldo de tu bolsa
Auth: Authorization: Bearer {api_key}

Returns the balance of one of your banks and the largest amount you can withdraw from it right now.

Retorna el saldo de uno de tus bancos y el monto mas grande que puedes retirar de el en este momento.

Query Parameters

Query Parameters

ParameterParametroRequiredRequeridoDescriptionDescripcion
bank_code*One of the bank codes your API Key has permission on. Check the bank directory (GET /banks).Uno de los codigos de banco sobre los que tu API Key tiene permiso. Consulta el directorio de bancos (GET /banks).
cURL
curl "https://api.payboom.io/balance?bank_code=1025" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "bank_code": "1025",
  "bankname": "SPEI MXN",
  "currency": "MXN",
  "available_cents": 500000,
  "withdrawable_cents": 496500
}
available_cents and withdrawable_cents are not "one minus the fee"available_cents y withdrawable_cents no son "uno menos la comision" available_cents is the raw balance of the bank's pool — the same number that authorizes any spend on that bank. withdrawable_cents is the largest amount that POST /withdrawals will accept right now. When your commission is a flat fee, withdrawable_cents = available_cents − fee, but when it is a percentage, the commission itself grows with the amount you request, so there is no subtraction that gives you the right number — PayBoom searches for it. Always read withdrawable_cents from this endpoint instead of computing your own ceiling; requesting exactly this number is guaranteed to be accepted, and requesting one cent more is guaranteed to bounce with 422 insufficient_balance. available_cents es el saldo crudo de la bolsa del banco — el mismo numero que autoriza cualquier gasto sobre ese banco. withdrawable_cents es el monto amount mas grande que POST /withdrawals aceptara en este momento. Cuando tu comision es una tarifa fija, withdrawable_cents = available_cents − comision, pero cuando es un porcentaje, la comision misma crece con el monto que pidas, asi que no hay una resta que de el numero correcto — PayBoom lo busca. Lee siempre withdrawable_cents de este endpoint en vez de calcular tu propio tope; pedir exactamente ese numero esta garantizado a aceptarse, y pedir un centavo mas esta garantizado a rebotar con 422 insufficient_balance.

Errors

Errores

CodeCodigoDescriptionDescripcion
400bank_required
401Missing API Key — {"error": "API key is required."}API Key ausente — {"error": "API key is required."}
403Invalid API Key ({"error": "Invalid API key."}), or the key has no active permission on that bank_code ({"error": "bank_not_allowed"}) — the same code covers a bank_code that does not exist at all, so an unauthorized caller cannot learn which codes are real.API Key invalida ({"error": "Invalid API key."}), o la key no tiene permiso activo sobre ese bank_code ({"error": "bank_not_allowed"}) — el mismo codigo cubre un bank_code que no existe, para que un caller no autorizado no pueda averiguar cuales codigos son reales.
POST /withdrawals Request a withdrawalSolicitar un retiro
Auth: Authorization: Bearer {api_key}

Reserves amount plus commission from the bank's pool and dispatches the SPEI to the CLABE on file (see PUT /withdrawal-account) in the same call: the response comes back executed, not pending. You must register that CLABE before your first withdrawal. If automatic execution is off for your merchant, or the dispatch could not be attempted, the withdrawal stays pending for PayBoom to authorize — read status, never the HTTP code, to know which happened.

Reserva amount mas comision de la bolsa del banco y despacha el SPEI a la CLABE registrada (ver PUT /withdrawal-account) en la misma llamada: la respuesta vuelve executed, no pending. Debes registrar esa CLABE antes de tu primer retiro. Si la ejecucion automatica esta apagada para tu comercio, o el despacho no pudo intentarse, el retiro queda pending para que PayBoom lo autorice — lee status, nunca el codigo HTTP, para saber cual de las dos cosas paso.

Request Body

Request Body

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
amountnumber*Amount in major units (pesos), e.g. 4965.00. Must be positive and parseable as a decimal.Monto en unidades mayores (pesos), e.g. 4965.00. Debe ser positivo y parseable como decimal.
bank_codestring*The bank whose pool to withdraw from. Your API Key must have active permission on it.El banco de cuya bolsa retirar. Tu API Key debe tener permiso activo sobre el.
notify_urlstringoptionalopcionalCalled once, best-effort, when the withdrawal reaches a final state. See Withdrawal webhook.Se llama una vez, best-effort, cuando el retiro llega a un estado final. Ver Webhook de retiro.
referencestring*Required while automatic execution is on for your merchant (400 reference_required without it); optional otherwise. Idempotency key, unique per merchant. Repeat the same POST with the same reference (e.g. after a client-side timeout) and PayBoom returns the existing withdrawal instead of reserving the balance a second time — see the callout below for how to tell the two cases apart. Max 100 characters; longer values are rejected with 400 invalid_reference.Obligatoria mientras la ejecucion automatica este encendida para tu comercio (400 reference_required sin ella); opcional en caso contrario. Llave de idempotencia, unica por comercio. Repite el mismo POST con la misma reference (e.g. tras un timeout del lado del cliente) y PayBoom retorna el retiro existente en vez de reservar el saldo una segunda vez — ver el callout de abajo para distinguir los dos casos. Maximo 100 caracteres; valores mas largos se rechazan con 400 invalid_reference.
JSON
{
  "amount": 4965.00,
  "bank_code": "1025",
  "notify_url": "https://mi-sitio.com/webhook/retiros",
  "reference": "order-8842"
}
JSON — 201 Created (new withdrawal, paid)
{
  "id": 4821,
  "amount_cents": 496500,
  "status": "executed",
  "currency": "MXN",
  "commission_cents": 500,
  "iva_cents": 80,
  "total_debited_cents": 497080,
  "method": "spei",
  "provider_reference": "SP-99213",
  "error_message": null,
  "executed_at": "2026-08-31T10:22:04.881000+00:00",
  "bank_code": "1025",
  "clabe": "012180001234567895",
  "notify_url": "https://mi-sitio.com/webhook/retiros",
  "reference": "order-8842"
}
cURL
curl -X POST https://api.payboom.io/withdrawals \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4965.00,
    "bank_code": "1025",
    "notify_url": "https://mi-sitio.com/webhook/retiros",
    "reference": "order-8842"
  }'
A 201 does not mean paid — read statusUn 201 no significa pagado — lee status The HTTP code tells you the withdrawal was created; status tells you what happened to the money. Three values are possible on a 201: executed (the SPEI was dispatched — provider_reference is the provider's id for it), failed (the provider rejected it; amount and commission were both refunded to your pool and commission_cents comes back as 0, with the reason in error_message), and pending (nothing was dispatched; the reservation stands and PayBoom will authorize it manually). Treating 201 alone as success will report failed withdrawals as paid. Because this call now waits for the payment provider, it can take up to ~45 seconds — set your client timeout above that, and always send reference so a timeout is safe to retry. El codigo HTTP te dice que el retiro se creo; status te dice que paso con el dinero. Sobre un 201 hay tres valores posibles: executed (el SPEI se despacho — provider_reference es el id del proveedor), failed (el proveedor lo rechazo; monto y comision se reembolsaron a tu bolsa y commission_cents vuelve en 0, con el motivo en error_message) y pending (no se despacho nada; la reserva sigue en pie y PayBoom lo autorizara a mano). Tomar el 201 a secas como exito reportaria como pagados retiros que fallaron. Como esta llamada ahora espera al proveedor de pago, puede tardar hasta ~45 segundos — sube el timeout de tu cliente por encima de eso, y manda siempre reference para que un timeout sea seguro de reintentar.
reference: 200 means it already existed, 201 means you just created itreference: 200 significa que ya existia, 201 significa que acabas de crearlo This is the entire point of reference: when you send one and it collides with a withdrawal already on file for your merchant, PayBoom returns that existing withdrawal — nothing new is created, no balance is reserved a second time. The response body is identical to a fresh create; the only signal that tells the two cases apart is the HTTP status code — 201 means "just created, balance just reserved" and 200 means "already existed, nothing changed." Branch on the status code, never on the body shape. This is what makes a client-side timeout safe to retry: resend the exact same request and you either get your original withdrawal back (200) or, if it never actually reached PayBoom, a new one (201) — either way you never double-reserve. Caveat: the lookup is by (merchant, reference) only, not by amount — reusing a reference with a different amount does not error, it silently returns the original withdrawal with its original amount. Never reuse a reference for a different operation. Ese es todo el proposito de reference: cuando envias una y coincide con un retiro que ya existe para tu comercio, PayBoom retorna ese retiro existente — no se crea nada nuevo, no se reserva el saldo una segunda vez. El body de la respuesta es identico al de una creacion nueva; la unica senal que distingue los dos casos es el codigo HTTP — 201 significa "se acaba de crear, se acaba de reservar el saldo" y 200 significa "ya existia, no cambio nada." Decide segun el codigo de estado, nunca segun la forma del body. Esto es lo que hace seguro reintentar tras un timeout del lado del cliente: reenvia la misma solicitud exacta y o recuperas tu retiro original (200) o, si nunca llego de verdad a PayBoom, se crea uno nuevo (201) — en ambos casos nunca reservas dos veces. Advertencia: la busqueda es solo por (comercio, reference), no por monto — reusar una reference con un amount distinto no da error, retorna en silencio el retiro original con su monto original. Nunca reuses una reference para una operacion distinta.
Validation is against amount + commission, not amount aloneLa validacion es sobre monto + comision, no solo el monto An amount equal to available_cents from GET /balance is normally rejected: the commission has to fit on top of it, not come out of it. Request withdrawable_cents instead — it is already the largest amount that passes this check. When a request is rejected for this reason, the 422 body carries required_cents (amount + commission) and available_cents so you can show the shortfall without a second call. Un amount igual a available_cents de GET /balance normalmente se rechaza: la comision tiene que caber encima, no salir de el. Pide withdrawable_cents en su lugar — ya es el monto mas grande que pasa esta validacion. Cuando una solicitud se rechaza por esto, el body del 422 trae required_cents (monto + comision) y available_cents para que muestres el faltante sin un segundo llamado.
JSON — 422 insufficient_balance
{
  "error": "insufficient_balance",
  "required_cents": 100530,
  "available_cents": 100000
}

Errors

Errores

CodeCodigoDescriptionDescripcion
400bank_required (missing/empty bank_code), invalid_amount (missing, zero, negative, or unparseable amount), or invalid_reference (reference longer than 100 characters), or reference_required (no reference while automatic execution is on for your merchant)bank_required (bank_code faltante/vacio), invalid_amount (amount faltante, cero, negativo o no parseable), o invalid_reference (reference mas larga que 100 caracteres), o reference_required (sin reference mientras la ejecucion automatica este encendida para tu comercio)
401 / 403Same as GET /balanceIgual que GET /balance
409withdrawal_account_missing — register a CLABE first with PUT /withdrawal-accountwithdrawal_account_missing — registra una CLABE primero con PUT /withdrawal-account
422insufficient_balance (see above), or currency_not_supported — the requested bank_code's currency is not MXN; see the callout at the top of this sectioninsufficient_balance (ver arriba), o currency_not_supported — la moneda del bank_code solicitado no es MXN; ver el callout al inicio de esta seccion
GET /withdrawals List your withdrawalsListar tus retiros
Auth: Authorization: Bearer {api_key}

Paginated list of your own withdrawals. This is a separate listing from GET /operations, which already covers paginated payins by status and date and is not duplicated here — this endpoint only ever returns withdrawals.

Listado paginado de tus propios retiros. Es un listado separado de GET /operations, que ya cubre la consulta paginada de payins por estado y fecha y no se duplica aqui — este endpoint solo retorna retiros.

Query Parameters (optional)

Query Parameters (opcionales)

ParameterParametroDescriptionDescripcion
statusFilter by status: pending, executed, or failedFiltrar por estatus: pending, executed o failed
fromStart date YYYY-MM-DDFecha de inicio YYYY-MM-DD
toEnd date YYYY-MM-DD, inclusiveFecha de fin YYYY-MM-DD, inclusiva
pagePage number, default 1, same contract as GET /operations.Numero de pagina, default 1, mismo contrato que GET /operations.
sizeRows per page: 50 or 100. Default 50. Any other value returns 400.Filas por pagina: 50 o 100. Default 50. Cualquier otro valor responde 400.
cURL
curl "https://api.payboom.io/withdrawals?status=executed&from=2026-08-01&page=1" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "page": 1,
  "per_page": 50,
  "total": 1,
  "total_pages": 1,
  "items": [
    {
      "id": 4821,
      "status": "executed",
      "method": "spei",
      "bank_code": "1025",
      "currency": "MXN",
      "amount_cents": 496500,
      "commission_cents": 500,
      "iva_cents": 80,
      "net_cents": 496500,
      "total_debited_cents": 497080,
      "reference": "order-8842",
      "clabe": "012180001234567895",
      "bank_name": "STP",
      "provider_reference": "ORD-2026-00821",
      "error_message": null,
      "created_at": "2026-08-20T10:15:00.123000",
      "executed_at": "2026-08-20T10:15:42.501000"
    }
  ]
}
items shapeForma de items Each entry in items has the exact same fields as GET /withdrawals/{id} — see the field table there. Cada entrada de items tiene los mismos campos que GET /withdrawals/{id} — ver la tabla de campos ahi.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Unparseable from/to ({"error": "Invalid date format, expected YYYY-MM-DD"}), unparseable page ({"error": "Invalid page"}), or invalid size ({"error": "Invalid size", "allowed": [50, 100]}) — note these three use a plain message, not the short error codes used elsewhere on this pagefrom/to no parseables ({"error": "Invalid date format, expected YYYY-MM-DD"}), page no parseable ({"error": "Invalid page"}), o size invalido ({"error": "Invalid size", "allowed": [50, 100]}) — nota que estos tres usan un mensaje plano, no los codigos cortos que usa el resto de esta pagina
401Same as GET /balanceIgual que GET /balance
GET /withdrawals/{id} Get a single withdrawalObtener un retiro
Auth: Authorization: Bearer {api_key}

Returns one withdrawal by its PayBoom id, with the full amount/commission breakdown. This is the source of truth for reconciliation: the execution webhook (below) is best-effort and fires at most once, so poll this endpoint whenever you are not sure a notification arrived.

Retorna un retiro por su id de PayBoom, con el desglose completo de monto y comision. Es la fuente de verdad para conciliar: el webhook de ejecucion (abajo) es best-effort y se dispara a lo mas una vez, asi que consulta este endpoint cuando no estes seguro de que una notificacion llego.

Path Parameters

Path Parameters

ParameterParametroDescriptionDescripcion
idThe id returned by POST /withdrawalsEl id que retorna POST /withdrawals
cURL
curl https://api.payboom.io/withdrawals/4821 \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "id": 4821,
  "status": "executed",
  "method": "spei",
  "bank_code": "1025",
  "currency": "MXN",
  "amount_cents": 496500,
  "commission_cents": 500,
  "iva_cents": 80,
  "net_cents": 496500,
  "total_debited_cents": 497080,
  "reference": "order-8842",
  "clabe": "012180001234567895",
  "bank_name": "STP",
  "provider_reference": "ORD-2026-00821",
  "error_message": null,
  "created_at": "2026-08-20T10:15:00.123000",
  "executed_at": "2026-08-20T10:15:42.501000"
}
FieldCampoDescriptionDescripcion
statuspending, executed, or failedpending, executed o failed
methodnull while pending; spei or usdt once executednull mientras esta pending; spei o usdt una vez ejecutado
commission_centsReserved at request time, not at execution — already reflected here while pending. Goes to 0 if the withdrawal ends up failed (see below).Reservada al solicitar, no al ejecutar — ya se refleja aqui mientras esta pending. Baja a 0 si el retiro termina failed (ver abajo).
total_debited_centsamount_cents + commission_cents + iva_cents — what actually left the bank's poolamount_cents + commission_cents + iva_cents — lo que realmente salio de la bolsa del banco
net_centsCurrently always equal to amount_centsActualmente siempre igual a amount_cents
referenceThe idempotency key you sent in POST /withdrawals, or null if you did not send oneLa llave de idempotencia que enviaste en POST /withdrawals, o null si no enviaste una
error_messageSet only when a spei dispatch fails; null otherwiseSe llena solo cuando falla un despacho spei; null en otro caso
A failed SPEI dispatch refunds amount AND commissionUn despacho SPEI fallido reembolsa monto Y comision If the SPEI dispatch fails, PayBoom refunds amount_cents + commission_cents + iva_cents back to the bank's pool and the withdrawal ends failed with commission_cents/iva_cents reset to 0 — you are never left holding a reserved commission for money that never moved. Si el despacho SPEI falla, PayBoom reembolsa amount_cents + commission_cents + iva_cents de vuelta a la bolsa del banco y el retiro termina failed con commission_cents/iva_cents en 0 — nunca te quedas con una comision reservada por dinero que nunca se movio.

Errors

Errores

CodeCodigoDescriptionDescripcion
401Same as GET /balanceIgual que GET /balance
404{"error": "not_found"} — no such withdrawal, or it belongs to another merchant. Never 403 here: that would confirm the id exists.{"error": "not_found"} — no existe ese retiro, o es de otro comercio. Nunca 403 aqui: eso confirmaria que el id existe.
GETPUT /withdrawal-account Get / set your withdrawal CLABEObtener / fijar tu CLABE de retiro
Auth: Authorization: Bearer {api_key}

GET returns whether you have a CLABE on file. PUT registers or replaces it — there is one CLABE per merchant, valid for withdrawals from any of your banks, Mexico only today.

GET retorna si tienes una CLABE registrada. PUT la registra o la reemplaza — hay una sola CLABE por comercio, valida para retiros de cualquiera de tus bancos, solo Mexico por ahora.

PUT Request Body

Request Body de PUT

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
clabestring*Exactly 18 digits. Not validated against the STP/Banxico check digit — only the shape is checked.Exactamente 18 digitos. No se valida contra el digito verificador de STP/Banxico — solo se valida la forma.
bank_namestringoptionalopcionalA display label for the destination bank (e.g. "STP", "BBVA"). Not validated against a catalog.Una etiqueta para el banco destino (e.g. "STP", "BBVA"). No se valida contra un catalogo.
JSON — PUT
{
  "clabe": "012180001234567895",
  "bank_name": "STP"
}
JSON — GET / PUT 200 OK
{
  "configured": true,
  "clabe": "012180001234567895",
  "bank_name": "STP"
}
cURL
curl -X PUT https://api.payboom.io/withdrawal-account \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"clabe": "012180001234567895", "bank_name": "STP"}'
GET before you have registered oneGET antes de registrar una Returns {"configured": false, "clabe": null, "bank_name": null}. This is also the shape you get if POST /withdrawals is bouncing with 409 withdrawal_account_missing. Retorna {"configured": false, "clabe": null, "bank_name": null}. Es tambien la forma que ves si POST /withdrawals esta rebotando con 409 withdrawal_account_missing.

Errors

Errores

CodeCodigoDescriptionDescripcion
400invalid_clabe
401 / 403Missing/invalid API Key, same as GET /balance. There is no bank_not_allowed case here: this endpoint has no bank_code permission check, since the CLABE is per-merchant, not per-bank.API Key ausente/invalida, igual que GET /balance. No hay caso bank_not_allowed aqui: este endpoint no valida permiso por bank_code, porque la CLABE es por comercio, no por banco.

Withdrawal Webhook

Webhook de Retiro

When a withdrawal you sent a notify_url for reaches executed or failed, PayBoom sends one POST to that URL with the exact same JSON GET /withdrawals/{id} returns.

Cuando un retiro al que le enviaste notify_url llega a executed o failed, PayBoom manda un POST a esa URL con el mismo JSON exacto que retorna GET /withdrawals/{id}.

JSON — Notification to merchantJSON — Notificacion al comercio
{
  "id": 4821,
  "status": "executed",
  "method": "spei",
  "bank_code": "1025",
  "currency": "MXN",
  "amount_cents": 496500,
  "commission_cents": 500,
  "iva_cents": 80,
  "net_cents": 496500,
  "total_debited_cents": 497080,
  "reference": "order-8842",
  "clabe": "012180001234567895",
  "bank_name": "STP",
  "provider_reference": "ORD-2026-00821",
  "error_message": null,
  "created_at": "2026-08-20T10:15:00.123000",
  "executed_at": "2026-08-20T10:15:42.501000"
}
Best-effort, one attempt — poll GET /withdrawals/{id} to reconcileBest-effort, un solo intento — concilia con GET /withdrawals/{id} PayBoom makes exactly one delivery attempt per withdrawal, with a 15s timeout, and never retries — a slow or unreachable endpoint on your side simply means the notification never arrives. This never affects the withdrawal itself: delivery happens after it has already reached its final state, so a failed delivery can neither block nor reverse it. Because of this, do not build reconciliation around the webhook arriving; treat it as a low-latency nudge and use GET /withdrawals/{id} (or the status filter on GET /withdrawals) as the source of truth — that is the reason this endpoint exists. PayBoom hace exactamente un intento de entrega por retiro, con timeout de 15s, y nunca reintenta — un endpoint lento o inalcanzable de tu lado simplemente significa que la notificacion nunca llega. Esto nunca afecta al retiro en si: la entrega ocurre despues de que ya llego a su estado final, asi que una entrega fallida no puede bloquearlo ni revertirlo. Por esto, no construyas tu conciliacion alrededor de que llegue el webhook; tratalo como un aviso de baja latencia y usa GET /withdrawals/{id} (o el filtro status de GET /withdrawals) como fuente de verdad — es la razon por la que existe ese endpoint.
No response code is checkedNo se valida ningun codigo de respuesta Unlike the Direct Bank webhook, PayBoom does not require your endpoint to answer 200. The delivery is marked as attempted as soon as the HTTP request completes, whatever status code your server returns — there is no re-delivery to trigger by returning a non-200 response. A diferencia del webhook de Direct Bank, PayBoom no requiere que tu endpoint responda 200. La entrega se marca como intentada en cuanto la peticion HTTP se completa, sea cual sea el codigo de estado que retorne tu servidor — no hay una re-entrega que disparar devolviendo una respuesta distinta de 200.

Query Endpoints

Endpoints de Consulta

GET /banks List available banksListar bancos disponibles
Auth: Authorization: Bearer {api_key}

Returns the banks/processors your API Key has permission to use.

Retorna los bancos/procesadores que tu API Key tiene permiso para usar.

Query Parameters (optional)

Query Parameters (opcionales)

ParameterParametroDescriptionDescripcion
countryFilter by country (e.g. MX)Filtrar por pais (e.g. MX)
channelFilter by channel (e.g. card, transfer)Filtrar por canal (e.g. card, transfer)
JSON — 200 OK
{
  "data": [
    {
      "code": "XXXX",
      "country": "MX",
      "channel": "transfer",
      "bankname": "Transferencia Bancaria",
      "providername": "Proveedor A",
      "estado": "Activo",
      "type": ""
    },
    {
      "code": "YYYY",
      "country": "MX",
      "channel": "card",
      "bankname": "Tarjeta Credito/Debito",
      "providername": "Proveedor B",
      "estado": "Activo",
      "type": ""
    }
  ]
}
type fieldCampo type Each bank now includes a type field: the payment-method slug used by POST /directlink (e.g. pse, bancolombia, nequi). It is an empty string when the entry does not correspond to a Direct Link method. Cada banco ahora incluye un campo type: el slug del metodo de pago usado por POST /directlink (e.g. pse, bancolombia, nequi). Es una cadena vacia cuando la entrada no corresponde a un metodo de Direct Link.
GET /cashbanks List cash payment banks (PAYSAFE)Listar bancos de pago en efectivo (PAYSAFE)
Auth: Authorization: Bearer {api_key}your API Key must have permission on the requested bank_code (1009 or 1010).tu API Key debe tener permiso sobre el bank_code solicitado (1009 o 1010).

Returns the list of cash-payment banks available through PAYSAFE (SafetyPay) for a given country, proxied live from the provider. Use the value each bank returns as bank_id in the bank_id field of POST /directbank when bank_code is 1009 or 1010.

Retorna el listado de bancos de pago en efectivo disponibles via PAYSAFE (SafetyPay) para un pais dado, obtenido en vivo del proveedor. Usa el valor que cada banco retorna como bank_id en el campo bank_id de POST /directbank cuando el bank_code es 1009 o 1010.

Query Parameters

Query Parameters

ParameterParametroRequiredRequeridoDescriptionDescripcion
country_code*Country to list cash banks for (e.g. MX)Pais para el cual listar bancos de efectivo (e.g. MX)
bank_codeoptionalopcionalEither "1009" or "1010". Defaults to "1009".Debe ser "1009" o "1010". Por default "1009".
cURL
curl "https://api.payboom.io/cashbanks?country_code=MX&bank_code=1009" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "data": [
    { "bank_id": "...", "...": "..." }
  ]
}
The bank object shape is set by PAYSAFELa forma del objeto banco la define PAYSAFE PayBoom proxies this list live from PAYSAFE's /mpi/api/v1/banks and returns it under data unmodified. The only field PayBoom's own code depends on is bank_id (required back on POST /directbank); PAYSAFE may include additional display fields (name, logo, etc.) that are not part of PayBoom's contract and may change without notice on PAYSAFE's side. PayBoom reenvia este listado en vivo desde /mpi/api/v1/banks de PAYSAFE y lo retorna bajo data sin modificar. El unico campo del que depende el codigo de PayBoom es bank_id (obligatorio de vuelta en POST /directbank); PAYSAFE puede incluir campos adicionales de despliegue (nombre, logo, etc.) que no forman parte del contrato de PayBoom y pueden cambiar sin aviso del lado de PAYSAFE.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Missing country_code, or bank_code is neither 1009 nor 1010Falta country_code, o bank_code no es 1009 ni 1010
401Invalid or missing API KeyAPI Key invalida o ausente
403No permission for the requested bank_codeSin permiso para el bank_code solicitado
500PAYSAFE provider errorError del proveedor PAYSAFE
GET /operations List operationsListar operaciones
Auth: Authorization: Bearer {api_key}

List your operations with their status.

Lista tus operaciones con su estado.

Query Parameters (optional)

Query Parameters (opcionales)

ParameterParametroDescriptionDescripcion
fromStart date YYYY-MM-DDFecha de inicio YYYY-MM-DD
toEnd date YYYY-MM-DD, inclusiveFecha de fin YYYY-MM-DD, inclusiva
statusFilter by status (e.g. pendiente, deposit)Filtrar por estatus (e.g. pendiente, deposit)
typeFilter by implementation: directbank, directcard or directlink. Omit to get every type. Derived from the bank the operation was charged through, at query time. Invalid values return 400 ({"error": "Invalid type", "allowed": ["directbank", "directcard", "directlink"]}).Filtrar por implementacion: directbank, directcard o directlink. Omitelo para recibir todos los tipos. Se deriva del banco por el que se cobro la operacion, al momento de consultar. Valores invalidos responden 400 ({"error": "Invalid type", "allowed": ["directbank", "directcard", "directlink"]}).
pagePage number, default 1Numero de pagina, default 1
sizeRows per page: 50 or 100. Default 50. Any other value returns 400 ({"error": "Invalid size", "allowed": [50, 100]}).Filas por pagina: 50 o 100. Default 50. Cualquier otro valor responde 400 ({"error": "Invalid size", "allowed": [50, 100]}).
cURL
curl "https://api.payboom.io/operations?from=2026-07-01&to=2026-07-17&status=deposit&page=1" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "page": 1,
  "per_page": 50,
  "total": 128,
  "total_pages": 3,
  "items": [
    {
      "payboom_reference": "pb_20260415120530123_93dfbb",
      "reference": "ORD-2026-00123",
      "provider_reference": "PROVIDER-TX-789",
      "bank_code": "1003",
      "type": "directbank",
      "amount": 500.00,
      "currency": "MXN",
      "status": "deposit",
      "settled": true,
      "created_at": "2026-04-15T12:05:30.123000",
      "notification": {
        "api_key_id": 2021,
        "payboom_reference": "pb_20260415120530123_93dfbb",
        "provider_reference": "PROVIDER-TX-789",
        "reference": "ORD-2026-00123",
        "bank_code": "1003",
        "amount": 500.00,
        "currency": "MXN",
        "status": "deposit"
      }
    }
  ]
}
PaginationPaginacion Results are ordered newest first. Use size to choose 50 or 100 rows per page, and page to walk through total_pages. The response field is per_page and echoes the size in effect.Los resultados se ordenan del mas reciente al mas antiguo. Usa size para elegir 50 o 100 filas por pagina, y page para recorrer total_pages. El campo de la respuesta es per_page y refleja el tamano vigente.
GET /operations/{reference} Get the status of a single operationObtener el estado de una operacion
Auth: Authorization: Bearer {api_key}

Get the status of a single operation by payboom_reference or your own reference (mchOrderNo).

Obten el estado de una operacion por payboom_reference o tu propia reference (mchOrderNo).

Path Parameters

Path Parameters

ParameterParametroDescriptionDescripcion
referenceEither the payboom_reference returned by PayBoom or your own reference (mchOrderNo)Puede ser el payboom_reference retornado por PayBoom o tu propia reference (mchOrderNo)
cURL
curl https://api.payboom.io/operations/pb_20260717091000123_ab12cd \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "payboom_reference": "pb_20260415120530123_93dfbb",
  "reference": "ORD-2026-00123",
  "provider_reference": "PROVIDER-TX-789",
  "bank_code": "1003",
  "type": "directbank",
  "amount": 500.00,
  "currency": "MXN",
  "status": "deposit",
  "settled": true,
  "created_at": "2026-04-15T12:05:30.123000",
  "notification": {
    "api_key_id": 2021,
    "payboom_reference": "pb_20260415120530123_93dfbb",
    "provider_reference": "PROVIDER-TX-789",
    "reference": "ORD-2026-00123",
    "bank_code": "1003",
    "amount": 500.00,
    "currency": "MXN",
    "status": "deposit"
  }
}
settled & notificationsettled y notification settled means the order has been approved/settled (true/false). notification mirrors the exact same payload PayBoom sends to your confirmation webhook: it is null while the order is not yet approved, and is only populated for cash channels (SPEI / ENEFEVO / OXXO — bank_code 1001/1002/1003).settled indica que la orden ya fue aprobada/liquidada (true/false). notification es el mismo payload exacto que PayBoom envia en el webhook de confirmacion: es null mientras la orden no este aprobada, y solo se llena para canales de efectivo (SPEI / ENEFEVO / OXXO — bank_code 1001/1002/1003).
typetype Which public API implementation the operation was charged through: directbank, directcard or directlink. Derived from the bank behind bank_code at query time, not stored on the operation. See the type row under GET /operations for the full explanation.Con que implementacion de la API publica se cobro la operacion: directbank, directcard o directlink. Se deriva del banco detras de bank_code al momento de consultar, no se guarda en la operacion. Ver la fila type en GET /operations para la explicacion completa.
POST /payment Query a payment's status directly against SIPEConsultar el estado de un pago directamente contra SIPE
No authentication requiredNo requiere autenticacion This endpoint does not check the Authorization header. Any caller who knows a valid orderId or mchOrderNo can query its status — sending your API Key has no effect and is not required. This is confirmed behavior of the current code, not a documentation gap; it is called out here so the general "all endpoints require Bearer auth" rule elsewhere on this page does not mislead you. See Authentication. Este endpoint no valida el header Authorization. Cualquiera que conozca un orderId o mchOrderNo valido puede consultar su estado — enviar tu API Key no tiene efecto y no es necesario. Este es el comportamiento confirmado del codigo actual, no un vacio de documentacion; se senala aqui para que la regla general de esta pagina ("todos los endpoints requieren Bearer auth") no induzca a error. Ver Autenticacion.

Queries SIPE's own order-status endpoint directly, using PayBoom's global SIPE credentials (not per-merchant). It is a thin passthrough kept for legacy integrations — for new integrations, prefer GET /operations/{reference}, which is scoped to your API Key and works across all channels, not only SIPE.

Consulta directamente el endpoint de estado de orden de SIPE, usando las credenciales globales de SIPE de PayBoom (no las del comercio). Es un passthrough delgado que se mantiene por integraciones heredadas — para integraciones nuevas, prefiere GET /operations/{reference}, que esta acotado a tu API Key y funciona con todos los canales, no solo SIPE.

Request Body

Request Body

FieldCampoTypeTipoDescriptionDescripcion
orderIdstringSIPE order ID. Send exactly one of orderId or mchOrderNo, never both.ID de orden de SIPE. Envia exactamente uno entre orderId y mchOrderNo, nunca ambos.
mchOrderNostringYour merchant order ID, as sent to POST /directbank. Send exactly one of orderId or mchOrderNo, never both.Tu ID de orden de comercio, tal como se envio a POST /directbank. Envia exactamente uno entre orderId y mchOrderNo, nunca ambos.
JSON
{
  "mchOrderNo": "ORD-2026-00123"
}
JSON — 200 OK
{
  "success": true,
  "raw": {
    "resCode": "SUCCESS",
    "...": "..."
  }
}
cURL
curl -X POST https://api.payboom.io/payment \
  -H "Content-Type: application/json" \
  -d '{"mchOrderNo": "ORD-2026-00123"}'
FieldCampoTypeTipoDescriptionDescripcion
successbooleantrue only when SIPE's resCode is exactly "SUCCESS"true solo cuando el resCode de SIPE es exactamente "SUCCESS"
rawobjectSIPE's response body, returned unmodified. Its exact shape beyond resCode is defined by SIPE, not by PayBoom — treat any other field as best-effort.Cuerpo de respuesta de SIPE, retornado sin modificar. Su forma exacta mas alla de resCode la define SIPE, no PayBoom — trata cualquier otro campo como best-effort.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Missing body, or missing/duplicated orderId/mchOrderNo (send exactly one)Body faltante, o orderId/mchOrderNo faltante o duplicado (envia exactamente uno)
500SIPE provider error, or SIPE returned a non-JSON responseError del proveedor SIPE, o SIPE respondio con contenido no-JSON

Crossborder — Global Payment (VelaFi)

Crossborder — Global Payment (VelaFi)

The /crossborder family of endpoints moves money between fiat currencies through VelaFi: you fund a per-currency balance from your PayBoom operations, register a recipient in the destination country, and send a fiat-to-fiat transfer that VelaFi converts and pays out. This is a separate product from Direct Bank / Direct Card and from Cobre's MX↔CO transfer — it does not share endpoints, balances, or references with them.

La familia de endpoints /crossborder mueve dinero entre monedas fiat a traves de VelaFi: fondeas una bolsa por moneda desde tus operaciones en PayBoom, registras un destinatario en el pais destino, y envias una transferencia fiat-a-fiat que VelaFi convierte y paga. Es un producto separado de Direct Bank / Direct Card y del traspaso MX↔CO de Cobre — no comparte endpoints, bolsas ni referencias con ellos.

Auth prerequisite: a Global Payment bank assigned to your keyPrerrequisito de auth: un banco Global Payment asignado a tu key Every endpoint below requires Authorization: Bearer {api_key} and exactly one active ApiKeyPermission on a bank with channel=GLOBALPAYMENT. If your API Key has zero such banks, or more than one, every /crossborder/* call returns 403 — ask PayBoom to assign (or disambiguate) your VelaFi bank code before integrating. Cada endpoint de abajo requiere Authorization: Bearer {api_key} y exactamente un ApiKeyPermission activo sobre un banco con channel=GLOBALPAYMENT. Si tu API Key tiene cero de esos bancos, o mas de uno, cualquier llamado a /crossborder/* retorna 403 — pide a PayBoom que te asigne (o desambigue) tu bank_code de VelaFi antes de integrar.

Supported Corridors

Corredores Soportados

A corridor is a (country, currency) pair on each side. Only the combinations below are accepted — anything else fails with unsupported_corridor.

Un corredor es un par (pais, moneda) de cada lado. Solo se aceptan las combinaciones de abajo — cualquier otra falla con unsupported_corridor.

From (on-ramp)Desde (on-ramp)To (off-ramp)Hacia (off-ramp)
Mexico · MXNArgentina · ARS, Colombia · COP, Hong Kong · USD, United States · USD, Global · USD
United States · USDMexico · MXN, Argentina · ARS
Colombia · COPMexico · MXN
Argentina · ARSMexico · MXN, United States · USD

Transfer Lifecycle

Ciclo de Vida de una Transferencia

A transfer's status is always one of the values below. docs_required/docs_review are compliance holds, not failures: funds stay reserved and no deadline runs while a transfer sits there.

El status de una transferencia siempre es uno de los valores de abajo. docs_required/docs_review son retenciones de cumplimiento, no fallas: los fondos siguen reservados y no corre ningun plazo mientras la transferencia esta ahi.

statusMeaningSignificadoRefundReembolso
createdReserved locally, not yet sent to VelaFiReservada localmente, aun no enviada a VelaFi
pendingAccepted by VelaFi, in flightAceptada por VelaFi, en curso
docs_requiredVelaFi needs supporting documents (RFI)VelaFi requiere documentacion de soporte (RFI)none — not a failureninguno — no es una falla
docs_reviewDocuments uploaded, VelaFi reviewingDocumentos subidos, VelaFi revisandonone — not a failureninguno — no es una falla
executedFunds released to the recipient. Terminal.Fondos liberados al destinatario. Terminal.
rejectedVelaFi canceled the payout leg (funds were already converted). Terminal.VelaFi cancelo la pata de pago (los fondos ya se convirtieron). Terminal.destination currency — retry from there with retrymoneda destino — reintenta desde ahi con retry
expiredPayBoom's own deadline passed while pending. Terminal.Vencio el plazo propio de PayBoom estando en pending. Terminal.destination currency — retry from there with retrymoneda destino — reintenta desde ahi con retry
failedThe payin leg never completed (no conversion happened) — includes network/validation failures and VelaFi payin cancellations. Terminal.La pata de payin nunca se completo (no hubo conversion) — incluye fallas de red/validacion y cancelaciones de payin de VelaFi. Terminal.source currency, automaticmoneda origen, automatico
Your notify_url (if sent when creating or retrying the transfer) is called once the transfer reaches executed, rejected, or expired, with the same JSON body GET /crossborder/{reference} returns. Tu notify_url (si se envio al crear o reintentar la transferencia) se llama cuando la transferencia llega a executed, rejected o expired, con el mismo body JSON que retorna GET /crossborder/{reference}.
GET /crossborder/rails List rails (payment methods) for a corridorListar rieles (metodos de pago) de un corredor
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Lists the on-ramp and off-ramp rails (payment methods, e.g. bank transfer / cash pickup) available for a corridor, as reported live by VelaFi. Pass rail to also fetch that rail's field template — the fields you must collect to register a recipient with POST /crossborder/recipients.

Lista los rieles on-ramp y off-ramp (metodos de pago, e.g. transferencia bancaria / retiro en efectivo) disponibles para un corredor, reportados en vivo por VelaFi. Envia rail para tambien obtener la plantilla de campos de ese riel — los campos que debes recolectar para registrar un destinatario con POST /crossborder/recipients.

Query Parameters (optional)

Query Parameters (opcionales)

ParameterParametroDescriptionDescripcion
fromOn-ramp (source) fiat currency. Default MXN. Also accepted as onRampFiat.Moneda fiat on-ramp (origen). Default MXN. Tambien se acepta como onRampFiat.
toOff-ramp (destination) fiat currency. Also accepted as offRampFiat.Moneda fiat off-ramp (destino). Tambien se acepta como offRampFiat.
countryShorthand: given a destination country name (or its first two letters, e.g. CO), resolves to/offRampCountry automatically from the supported corridors for the from currency. Ignored if to/offRampFiat is already set.Atajo: dado un nombre de pais destino (o sus dos primeras letras, e.g. CO), resuelve to/offRampCountry automaticamente a partir de los corredores soportados para la moneda from. Se ignora si to/offRampFiat ya viene.
onRampCountryOn-ramp country name. Defaults from from's currency (e.g. MXNMexico).Nombre del pais on-ramp. Por default se deriva de la moneda from (e.g. MXNMexico).
offRampCountryOff-ramp country nameNombre del pais off-ramp
railA paymentId from paymentListFrom/paymentListTo. When present, adds template to the response. Also accepted as paymentId.Un paymentId de paymentListFrom/paymentListTo. Si viene, agrega template a la respuesta. Tambien se acepta como paymentId.
cURL
curl "https://api.payboom.io/crossborder/rails?from=MXN&to=COP" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "onRampCountry": "Mexico",
  "onRampFiat": "MXN",
  "offRampCountry": "Colombia",
  "offRampFiat": "COP",
  "paymentListFrom": [ { "paymentId": 105, "...": "..." } ],
  "paymentListTo": [ { "paymentId": 18, "...": "..." } ],
  "corridorSupported": true
}
paymentListFrom / paymentListTo / template are VelaFi passthroughpaymentListFrom / paymentListTo / template son passthrough de VelaFi PayBoom guarantees the envelope fields above and that each rail object carries a paymentId (the value to use as rail elsewhere on this page). Everything else inside paymentListFrom, paymentListTo, and template is returned exactly as VelaFi sends it and is not fixed by PayBoom's contract — inspect a live response for the fields a given rail's template requires before building your recipient form. PayBoom garantiza los campos del sobre de arriba y que cada objeto de riel trae un paymentId (el valor a usar como rail en el resto de esta pagina). Todo lo demas dentro de paymentListFrom, paymentListTo y template se retorna tal cual lo manda VelaFi y no esta fijado por el contrato de PayBoom — inspecciona una respuesta real para saber que campos requiere el template de un riel dado antes de construir tu formulario de destinatario.

Errors

Errores

CodeCodigoDescriptionDescripcion
401Invalid or missing API KeyAPI Key invalida o ausente
403No (or ambiguous) Global Payment bank on your API KeySin (o ambiguo) banco Global Payment en tu API Key
502VelaFi returned a server errorVelaFi retorno un error de servidor
503VelaFi bank misconfigured (missing credentials)Banco VelaFi mal configurado (credenciales faltantes)
GET /crossborder/balances List your per-currency Global Payment balancesListar tus bolsas Global Payment por moneda
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Returns one balance per currency you have moved through Global Payment. A currency only appears once it has at least one movement; there is no zero-balance placeholder row.

Retorna una bolsa por cada moneda que has movido a traves de Global Payment. Una moneda solo aparece una vez que tiene al menos un movimiento; no hay fila de saldo en cero como placeholder.

cURL
curl https://api.payboom.io/crossborder/balances \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "record": [
    {
      "merchantId": 8801,
      "fiat": "MXN",
      "label": "Pesos Mexicanos",
      "balance": "5000.00",
      "status": 2,
      "source": "payin",
      "icon": "account_balance",
      "availableMinor": 500000
    }
  ]
}
FieldCampoTypeTipoDescriptionDescripcion
fiatstringCurrency codeCodigo de moneda
balancestringAvailable balance in major units (e.g. "5000.00" MXN)Saldo disponible en unidades mayores (e.g. "5000.00" MXN)
availableMinorintegerSame balance in minor units (cents)Mismo saldo en unidades menores (centavos)
statusinteger2 when availableMinor > 0, 4 otherwise2 cuando availableMinor > 0, 4 en otro caso
sourcestring"payin" when availableMinor > 0, "incomplete" otherwise"payin" cuando availableMinor > 0, "incomplete" en otro caso
GET /crossborder/quote Get an indicative quote with PayBoom's commissionObtener una cotizacion indicativa con la comision de PayBoom
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Returns an indicative exchange rate plus PayBoom's commission for a given amount. The rate is indicative only — the rate actually applied is captured at transfer creation and may differ; see quotedRate vs appliedRate on GET /crossborder/{reference}.

Retorna una tasa de cambio indicativa mas la comision de PayBoom para un monto dado. La tasa es solo indicativa — la tasa realmente aplicada se captura al crear la transferencia y puede diferir; ver quotedRate vs appliedRate en GET /crossborder/{reference}.

Query Parameters

Query Parameters

ParameterParametroRequiredRequeridoDescriptionDescripcion
fromoptionalopcionalOn-ramp fiat. Default MXN. Also accepted as onRampFiat.Fiat on-ramp. Default MXN. Tambien se acepta como onRampFiat.
tooptionalopcionalOff-ramp fiat. Default ARS. Also accepted as offRampFiat.Fiat off-ramp. Default ARS. Tambien se acepta como offRampFiat.
onRampCountryoptionalopcionalDefaults from from's currencyPor default se deriva de la moneda from
offRampCountryoptionalopcionalDefaults from to's currencyPor default se deriva de la moneda to
amountoptionalopcionalSource amount in major units. When omitted, amount-dependent fields are returned as 0.Monto origen en unidades mayores. Si se omite, los campos que dependen del monto se retornan en 0.
cURL
curl "https://api.payboom.io/crossborder/quote?from=MXN&to=ARS&amount=1000" \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{
  "price": "180",
  "quoteId": "",
  "onRampCountry": "Mexico",
  "onRampFiat": "MXN",
  "offRampCountry": "Argentina",
  "offRampFiat": "ARS",
  "quoted_dest_amount_minor": 18000000,
  "commission_minor": 2500,
  "iva_minor": 400,
  "source_amount_minor": 100000
}
FieldCampoDescriptionDescripcion
priceIndicative exchange rate (destination per unit of source)Tasa de cambio indicativa (destino por unidad de origen)
quoteIdAlways an empty string — VelaFi's short-lived quote IDs are not used for fiat-to-fiat transfersSiempre cadena vacia — los quote IDs de corta vida de VelaFi no se usan para transferencias fiat-a-fiat
quoted_dest_amount_minorEstimated destination amount, in destination currency minor unitsMonto destino estimado, en unidades menores de la moneda destino
commission_minor / iva_minorPayBoom's commission and its tax, in source currency minor unitsComision de PayBoom y su impuesto, en unidades menores de la moneda origen
source_amount_minorEchoes amount in minor unitsRepite amount en unidades menores

Errors

Errores

CodeCodigoDescriptionDescripcion
400Unsupported corridorCorredor no soportado
401 / 403 / 502 / 503Same as GET /crossborder/railsIgual que GET /crossborder/rails
GETPOST /crossborder/recipients List / register recipientsListar / registrar destinatarios
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

GET — list your recipients

GET — listar tus destinatarios

Returns every recipient you have registered, newest first. No pagination.

Retorna todos los destinatarios que has registrado, del mas reciente al mas antiguo. Sin paginacion.

cURL
curl https://api.payboom.io/crossborder/recipients \
  -H "Authorization: Bearer pb_ak_your_api_key_here"
JSON — 200 OK
{ "record": [ { "id": 42, "...": "see the recipient object below" } ] }

POST — register a recipient

POST — registrar un destinatario

Creates the payment method on VelaFi and stores it as a recipient owned by your merchant. A new recipient starts in pending_verification; polling / a webhook moves it to active or rejected. You can only send money to a recipient once it is active (see POST /crossborder).

Crea el metodo de pago en VelaFi y lo guarda como destinatario de tu comercio. Un destinatario nuevo empieza en pending_verification; polling / un webhook lo mueve a active o rejected. Solo puedes enviar dinero a un destinatario una vez que esta active (ver POST /crossborder).

Fields are not locally validatedLos campos no se validan localmente PayBoom does not reject an incomplete body with a clean 400: it forwards whatever you send straight to VelaFi's POST /v2/payments. An incomplete or malformed body typically surfaces as a VelaFi error instead. Fetch the rail's template via GET /crossborder/rails?rail={id} to know what fields that rail actually expects. PayBoom no rechaza un body incompleto con un 400 limpio: reenvia tal cual lo que envies a POST /v2/payments de VelaFi. Un body incompleto o mal formado normalmente se manifiesta como un error de VelaFi. Obten el template del riel via GET /crossborder/rails?rail={id} para saber que fields espera realmente ese riel.
FieldCampoTypeTipoDescriptionDescripcion
aliasstringDisplay name for the recipient. Also accepted as realName.Nombre de despliegue del destinatario. Tambien se acepta como realName.
countrystringDestination country name (e.g. "Colombia"). Also accepted as dest_country.Nombre del pais destino (e.g. "Colombia"). Tambien se acepta como dest_country.
currencystringDestination currency (e.g. "COP"). Also accepted as fiat.Moneda destino (e.g. "COP"). Tambien se acepta como fiat.
railintegerThe paymentId from GET /crossborder/rails. Also accepted as paymentId.El paymentId de GET /crossborder/rails. Tambien se acepta como paymentId.
fieldsobjectKey/value pairs required by that rail's template (e.g. account number, document ID). Also accepted as fieldJson.Pares clave/valor que requiere la plantilla de ese riel (e.g. numero de cuenta, documento). Tambien se acepta como fieldJson.
JSON
{
  "alias": "Proveedor Bogota SAS",
  "country": "Colombia",
  "currency": "COP",
  "rail": 18,
  "fields": { "account_number": "1234567890", "document_id": "900123456" }
}
JSON — 201 Created
{
  "id": 42,
  "merchantId": 8801,
  "country": "Colombia",
  "fiat": "COP",
  "paymentId": 18,
  "paymentMethodName": "Proveedor Bogota SAS",
  "realName": "Proveedor Bogota SAS",
  "status": 2,
  "statusKey": "pending_verification",
  "fieldList": { "account_number": "1234567890", "document_id": "900123456" },
  "failReason": "",
  "maskedAccount": "****7890",
  "providerPaymentId": "228",
  "createTime": "1798564530123"
}
cURL
curl -X POST https://api.payboom.io/crossborder/recipients \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Proveedor Bogota SAS",
    "country": "Colombia",
    "currency": "COP",
    "rail": 18,
    "fields": { "account_number": "1234567890", "document_id": "900123456" }
  }'
FieldCampoDescriptionDescripcion
idPayBoom's internal recipient ID — use this as recipient_id on POST /crossborderID interno de PayBoom del destinatario — usalo como recipient_id en POST /crossborder
statusKeyOne of active, pending_verification, rejected, incomplete. Prefer this over the numeric status.Uno de active, pending_verification, rejected, incomplete. Prefierelo sobre el status numerico.
statusVelaFi-style numeric mirror of statusKey (1=active, 2=pending_verification/incomplete, 3=rejected)Espejo numerico estilo VelaFi de statusKey (1=active, 2=pending_verification/incomplete, 3=rejected)
maskedAccountLast 4 digits found among fields' values, prefixed **** (empty if none had 4+ digits)Ultimos 4 digitos encontrados entre los valores de fields, con prefijo **** (vacio si ninguno tenia 4+ digitos)
providerPaymentIdVelaFi's own ID for this payment methodID propio de VelaFi para este metodo de pago

Errors

Errores

CodeCodigoDescriptionDescripcion
401 / 403 / 502 / 503Same as GET /crossborder/railsIgual que GET /crossborder/rails
GETPATCH /crossborder/recipients/{id} Get / edit a single recipientObtener / editar un destinatario
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Path Parameters

Path Parameters

ParameterParametroDescriptionDescripcion
idPayBoom's internal recipient id, from POST/GET /crossborder/recipientsid interno de PayBoom del destinatario, de POST/GET /crossborder/recipients

GET returns the recipient object (same shape as POST /crossborder/recipients's response). PATCH supports two independent, optional changes in the same body:

GET retorna el objeto destinatario (misma forma que la respuesta de POST /crossborder/recipients). PATCH soporta dos cambios independientes y opcionales en el mismo body:

FieldCampoTypeTipoDescriptionDescripcion
aliasstringRenames the recipient. Also accepted as realName.Renombra al destinatario. Tambien se acepta como realName.
statusstringThe only value the API accepts here is the literal string "incomplete", which deactivates the recipient locally. Any other value is ignored — you cannot set active or rejected directly; those come from VelaFi.El unico valor que acepta la API aqui es la cadena literal "incomplete", que desactiva al destinatario localmente. Cualquier otro valor se ignora — no puedes fijar active o rejected directamente; esos vienen de VelaFi.
JSON
{ "alias": "Proveedor Bogota SAS (nuevo nombre)" }
cURL
curl -X PATCH https://api.payboom.io/crossborder/recipients/42 \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"alias": "Proveedor Bogota SAS (nuevo nombre)"}'

Errors

Errores

CodeCodigoDescriptionDescripcion
401 / 403Same as GET /crossborder/railsIgual que GET /crossborder/rails
404No such recipient for your merchantNo existe ese destinatario para tu comercio
POST /crossborder Create a fiat-to-fiat transferCrear una transferencia fiat-a-fiat
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Reserves the source amount plus commission from your source-currency balance, then sends the order to VelaFi. The recipient must already be active.

Reserva el monto origen mas comision de tu bolsa de la moneda origen, y envia la orden a VelaFi. El destinatario debe estar active.

FieldCampoTypeTipoRequiredRequeridoDescriptionDescripcion
recipient_idinteger*The id from POST /crossborder/recipients. Also accepted as offRampPaymentId (tried first as PayBoom's internal id, then as VelaFi's providerPaymentId).El id de POST /crossborder/recipients. Tambien se acepta como offRampPaymentId (se prueba primero como id interno de PayBoom, luego como providerPaymentId de VelaFi).
amountnumber*Source amount in major units. Also accepted as onRampFiatAmount.Monto origen en unidades mayores. Tambien se acepta como onRampFiatAmount.
source_currencystringoptionalopcionalDefault MXN. Also accepted as onRampFiat.Default MXN. Tambien se acepta como onRampFiat.
onRampCountrystringoptionalopcionalDefaults from source_currencyPor default se deriva de source_currency
notify_urlstringoptionalopcionalCalled once with the transfer's final state (executed/rejected/expired)Se llama una vez con el estado final de la transferencia (executed/rejected/expired)
client_idstringoptionalopcionalIdempotency key: a second call with the same client_id returns the original transfer instead of creating a new one. Auto-generated when omitted. Also accepted as clientId.Llave de idempotencia: un segundo llamado con el mismo client_id retorna la transferencia original en vez de crear una nueva. Se autogenera si se omite. Tambien se acepta como clientId.
JSON
{
  "recipient_id": 42,
  "amount": "1000.00",
  "source_currency": "MXN",
  "onRampCountry": "Mexico",
  "notify_url": "https://mi-sitio.com/webhook/crossborder"
}
JSON — 201 Created
{
  "orderId": "ord-77291",
  "clientId": "payboom-gp-3f7a9c1e2b4d5f60",
  "onRampCountry": "Mexico",
  "onRampFiat": "MXN",
  "onRampFiatAmount": "1000.00",
  "onRampFiatFee": "0",
  "onRampPaymentId": 70,
  "offRampCountry": "Colombia",
  "offRampFiat": "COP",
  "offRampFiatAmount": "180000.00",
  "offArriveRampFiatAmount": "180000.00",
  "offRampFiatFee": "0",
  "offRampPaymentId": 228,
  "orderPrice": "180",
  "orderStatus": 41,
  "failReason": "",
  "failCode": "",
  "status": "pending",
  "recipientName": "Proveedor Bogota SAS",
  "recipientId": 42,
  "createTime": "1798564530123",
  "completedTime": "",
  "mid": 8801,
  "quotedRate": "180",
  "appliedRate": "",
  "commission": "25.00",
  "iva": "4.00",
  "retryOf": null,
  "reference": "payboom-gp-3f7a9c1e2b4d5f60"
}
cURL
curl -X POST https://api.payboom.io/crossborder \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_id": 42,
    "amount": "1000.00",
    "source_currency": "MXN",
    "notify_url": "https://mi-sitio.com/webhook/crossborder"
  }'
reference & onRampPaymentIdreference y onRampPaymentId Use reference (same value as clientId) to look the transfer up later on GET /crossborder/{reference}. onRampPaymentId is always 70, an internal VelaFi placeholder for "pending fund" — it does not identify your funding rail and can be ignored. Usa reference (mismo valor que clientId) para consultar la transferencia despues en GET /crossborder/{reference}. onRampPaymentId siempre es 70, un placeholder interno de VelaFi para "fondo pendiente" — no identifica tu riel de fondeo y puede ignorarse.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Recipient not found, recipient not active, invalid amount, unsupported corridor, or insufficient balanceDestinatario no encontrado, destinatario no active, monto invalido, corredor no soportado, o saldo insuficiente
401 / 403Same as GET /crossborder/railsIgual que GET /crossborder/rails
502VelaFi rejected or failed to create the order (the reservation is automatically refunded to your source balance)VelaFi rechazo o fallo al crear la orden (la reserva se reembolsa automaticamente a tu bolsa origen)
GET /crossborder/{reference} Get the status of a transferObtener el estado de una transferencia
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Path Parameters

Path Parameters

ParameterParametroDescriptionDescripcion
referenceEither the client_id you sent (or received back as reference/clientId) on POST /crossborder, or VelaFi's orderIdEl client_id que enviaste (o recibiste de vuelta como reference/clientId) en POST /crossborder, o el orderId de VelaFi

Returns the same object shape as POST /crossborder's response, reflecting the transfer's current status. See Transfer Lifecycle above for what each status means.

Retorna la misma forma de objeto que la respuesta de POST /crossborder, reflejando el status actual de la transferencia. Ver Ciclo de Vida de una Transferencia arriba para el significado de cada status.

cURL
curl https://api.payboom.io/crossborder/payboom-gp-3f7a9c1e2b4d5f60 \
  -H "Authorization: Bearer pb_ak_your_api_key_here"

Errors

Errores

CodeCodigoDescriptionDescripcion
401 / 403Same as GET /crossborder/railsIgual que GET /crossborder/rails
404No such transfer for your merchantNo existe esa transferencia para tu comercio
POST /crossborder/{reference}/retry Retry a rejected or expired transferReintentar una transferencia rechazada o vencida
Auth: Authorization: Bearer {api_key} + Global Payment bank (see above)

Creates a new transfer that starts from the funds refunded into the destination currency (see Transfer Lifecycle) — it does not re-run the original currency conversion. Only allowed when the original transfer's status is rejected or expired.

Crea una transferencia nueva que parte de los fondos reembolsados en la moneda destino (ver Ciclo de Vida de una Transferencia) — no vuelve a ejecutar la conversion de moneda original. Solo se permite cuando el status de la transferencia original es rejected o expired.

Path Parameters

Path Parameters

ParameterParametroDescriptionDescripcion
referenceSame lookup rule as GET /crossborder/{reference}Misma regla de busqueda que GET /crossborder/{reference}

Request Body (optional)

Request Body (opcional)

FieldCampoDescriptionDescripcion
notify_urlNotification URL for the new transfer. Defaults to the original transfer's notify_url when omitted.URL de notificacion para la nueva transferencia. Por default usa el notify_url de la transferencia original si se omite.
cURL
curl -X POST https://api.payboom.io/crossborder/payboom-gp-3f7a9c1e2b4d5f60/retry \
  -H "Authorization: Bearer pb_ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'

Returns 201 with the new transfer (same shape as POST /crossborder). Its retryOf points to the original transfer.

Retorna 201 con la nueva transferencia (misma forma que POST /crossborder). Su retryOf apunta a la transferencia original.

Errors

Errores

CodeCodigoDescriptionDescripcion
400Original transfer is not rejected or expiredLa transferencia original no esta rejected ni expired
401 / 403Same as GET /crossborder/railsIgual que GET /crossborder/rails
404No such transfer for your merchantNo existe esa transferencia para tu comercio
502VelaFi rejected or failed to create the retry orderVelaFi rechazo o fallo al crear la orden de reintento

Reference — Transaction StatusesReferencia — Estados de Transaccion

StatusEstadoDescriptionDescripcionProcessorsProcesadores
PENDINGTransaction created, waiting for confirmation or 3DS redirectTransaccion creada, esperando confirmacion o redireccion 3DSAll (standard format)Todos (formato estandar)
pendienteEquivalent to PENDING (legacy format from some processors)Equivalente a PENDING (formato legacy de algunos procesadores)Some transfer/cash processorsAlgunos procesadores de transferencia/efectivo
APPROVEDPayment successfully approvedPago aprobado exitosamenteAllTodos
DECLINEDPayment rejected by the processor or issuer bankPago rechazado por el procesador o banco emisorCardsTarjetas
3DSIn progress of 3D Secure authenticationEn proceso de autenticacion 3D SecureSome card processorsAlgunos procesadores de tarjeta
SETTLEDPayment settled (funds transferred)Pago liquidado (fondos transferidos)Some card processorsAlgunos procesadores de tarjeta
CANCELLEDTransaction cancelledTransaccion canceladaCards (with cancel)Tarjetas (con cancel)
REFUNDEDTransaction refundedTransaccion reembolsadaCards (with refund)Tarjetas (con refund)
FAILEDProcessing errorError en el procesamientoAllTodos

HTTP Error CodesCodigos de Error HTTP

CodeCodigoMeaningSignificadoRecommended actionAccion recomendada
400Bad Request — Invalid or incomplete dataBad Request — Datos invalidos o incompletosCheck required fields and formatsVerifica los campos requeridos y formatos
401Unauthorized — Invalid API KeyUnauthorized — API Key invalidaCheck your API Key and that it's activeVerifica tu API Key y que este activa
403Forbidden — No permission for this processorForbidden — Sin permiso para este procesadorRequest activation of the permission for the bank_codeSolicita que se active el permiso para el bank_code
429Too Many Requests — Velocity limit exceededToo Many Requests — Limite de velocidad excedidoWait before retrying. Review velocity rulesEspera antes de reintentar. Revisa reglas de velocidad
500Internal Server Error — Provider errorInternal Server Error — Error del proveedorRetry after a few secondsReintenta despues de unos segundos
501Not Implemented — Processor not availableNot Implemented — Procesador no disponibleUse a supported bank_codeUsa un bank_code soportado

PayBoom Response Codes (P0X)Codigos de Respuesta PayBoom (P0X)

These codes are generated by PayBoom when a transaction is rejected by internal velocity, amount, or schedule rules. They are received in the response_code field of the response.Estos codigos son generados por PayBoom cuando una transaccion es rechazada por reglas internas de velocidad, restricciones de monto u horario. Se reciben en el campo response_code de la respuesta.

CodeCodigoDescriptionDescripcionRecommended actionAccion recomendada
P00Transaction blocked by velocity rules (generic)Transaccion bloqueada por reglas de velocidad (generico)Contact support to review the configured rulesContacta a soporte para revisar las reglas configuradas
P01Merchant daily limit exceededLimite diario del comercio excedidoWait until the next day or request a daily limit increaseEspera al dia siguiente o solicita un aumento de limite diario
P02Merchant monthly limit exceededLimite mensual del comercio excedidoWait until the next month or request a monthly limit increaseEspera al siguiente mes o solicita un aumento de limite mensual
P03Maximum number of transactions per card in 24 hours exceededNumero maximo de transacciones por tarjeta en 24 horas excedidoWait 24 hours to retry with the same cardEspera 24 horas para reintentar con la misma tarjeta
P04Minimum time between successful transactions with the same card has not elapsedTiempo minimo entre transacciones exitosas con la misma tarjeta no ha transcurridoWait for the configured interval before retryingEspera el intervalo configurado antes de reintentar
P05Card temporarily blocked due to multiple failed attemptsTarjeta temporalmente bloqueada por multiples intentos fallidosWait for the cooldown period before retryingEspera el periodo de enfriamiento antes de reintentar
P06Card permanently blockedTarjeta permanentemente bloqueadaThe card has been blocked. Use a different cardLa tarjeta ha sido bloqueada. Usa una tarjeta diferente
P07Transaction amount below the minimum allowed / Transaction outside allowed hoursMonto de transaccion menor al minimo permitido / Transaccion fuera de horarioCheck the minimum amount or allowed hours (1:00 AM - 5:59 AM CDMX is blocked)Verifica el monto minimo o el horario permitido (1:00 AM - 5:59 AM CDMX esta bloqueado)
P08Transaction amount exceeds the maximum allowed per transactionMonto de transaccion excede el maximo permitido por transaccionReduce the amount or request a limit increaseReduce el monto o solicita un aumento de limite
P09Cards with this BIN are not allowedTarjetas con este BIN no estan permitidasThe card BIN is blocked. Use a card from a different bank/issuerEl BIN de la tarjeta esta bloqueado. Usa una tarjeta de otro banco/emisor
P0X Codes and HTTP 429Codigos P0X y HTTP 429 Transactions rejected by velocity rules (P01-P09) return HTTP 429 (Too Many Requests). Out-of-hours transactions (P07) return HTTP 200 with status DECLINED.Las transacciones rechazadas por reglas de velocidad (P01-P09) retornan HTTP 429 (Too Many Requests). Las transacciones fuera de horario (P07) retornan HTTP 200 con status DECLINED.

Merchant Notification Format (Webhook)Formato de Notificacion al Comercio (Webhook)

PayBoom sends a POST to your notifyUrl when the transaction status changes. Your endpoint must respond with HTTP 200.PayBoom envia un POST a tu notifyUrl cuando el estado de la transaccion cambia. Tu endpoint debe responder con HTTP 200.

JSON — Webhook PayloadJSON — Payload del Webhook
{
  "api_key_id": 2007,
  "payboom_reference": "pb_20260415120530123_93dfbb",
  "provider_reference": "PROVIDER-TX-789",
  "reference": "ORD-2026-00123",
  "bank_code": "1001",
  "amount": 500.00,
  "currency": "MXN",
  "status": "deposit"
}
Format varies by channelEl formato varia por canal The example above is the cash/transfer format (SPEI, ENEFEVO, OXXO): status deposit, reference = your order ID, numeric amount, no authorization. Card and recurring (Unlimit) channels send additional fields such as authorization and mchOrderNo and use status APPROVED/DECLINED. El ejemplo de arriba es el formato de efectivo/transferencia (SPEI, ENEFEVO, OXXO): status deposit, reference = tu ID de orden, amount numerico, sin authorization. Los canales de tarjeta y recurrentes (Unlimit) envian campos adicionales como authorization y mchOrderNo y usan status APPROVED/DECLINED.