payin_rate en GET /v1/rates) menos la comisión fija de payin si tu
cuenta la tiene configurada.
Sea cual sea la modalidad, todos los caminos terminan igual — abono
automático + webhook:
1. Descubre los corredores disponibles
Los países, monedas y modalidades disponibles los define CBPay. Consúltalos siempre por catálogo:delivery indica cómo se confirma el pago del lado de CBPay (notificación
del banco, sondeo o ambos) — no cambia nada en tu integración: tú siempre
recibes el webhook payin_credited.
Corredores y modalidades de cobro:
La disponibilidad puede variar; el catálogo (
GET /v1/payins/methods) es
siempre la fuente de verdad. En todos los casos el abono llega igual: se
convierte a USDT a tu payin_rate del momento y se acredita neto de la
comisión fija de payin.
2. Elige la modalidad y crea el cobro
Cada país tiene su propia modalidad de cobro. El request y la respuesta real de cada una:- Chile
- Perú
- México
- Venezuela
- Bolivia
- Paraguay
- Brasil
Página de pago hosted (Respuesta Comparte la Respuesta Cuando la transferencia llega, se matchea por la referencia en la glosa (o
por monto+moneda como respaldo) y tu cuenta se acredita automáticamente.
fintoc) — recomendado: recibes una
payment_url; el pagador la abre y transfiere desde cualquier banco o
billetera chilena (Banco Estado, Santander, Mach, Tenpo, Mercado
Pago…). El pago se detecta y valida automáticamente — sin referencias
manuales.201:payment_url con el pagador (link, redirección o WebView).
Cuando el pago se confirma, tu cuenta se acredita en USDT y recibes el
webhook payin_credited. El monto CLP debe ser entero (el peso chileno no
usa decimales) y la sesión de pago vence en 24 horas por defecto. Un retry
con la misma idempotency_key devuelve el mismo payin y la misma URL —
nunca abre una segunda sesión de pago.Transferencia anunciada (alternativa manual): anuncias el depósito
entrante y compartes la referencia con quien transfiere.201:Link de cobro universal (checkout)
Crea un link de cobro universal: un solo POST /v1/payins con
method: "checkout" devuelve una URL pública brandeada donde el pagador
elige cómo pagar. El cobro se denomina en el saldo virtual que tú
elijas (settlement_asset: USDT, USDC, BTC o GOLD, default
USDT) y todo pago se convierte automáticamente a ese saldo al
acreditarse — salvo que te paguen en el mismo asset, ahí no hay
conversión.
La página organiza el pago en cuatro pestañas:
- CBPay — pago directo con la app: el alias y el QR del comercio; quien escanea con la app paga al instante por transferencia interna, en cualquiera de los 4 saldos.
- Crypto — las monedas disponibles agrupadas por red (hoy USDT en TRON y Ethereum, USDC en Ethereum y BTC; redes nuevas aparecen solas al habilitarse), cada una con una dirección de depósito exclusiva de ese cobro y QR escaneable por wallets externas (Trust Wallet, MetaMask, Binance y similares).
- Fiat — el pagador elige su país entre todos los que tienen corredor de payin vivo y ve los métodos disponibles (QR, transferencia bancaria, pago hosted) con el monto local cotizado al momento.
- Tarjeta — pago con tarjeta de crédito o débito en una página segura, listado por moneda de cargo (hoy BOB y USD; monedas de adquirentes futuros aparecen solas). Cada moneda es una opción de pago independiente con su propio monto cotizado.
amountse denomina en elsettlement_asset:"50"conUSDTson 50 USDT;"0.001"conBTCson 0.001 BTC;"2"conGOLDson 2 gramos de oro. No envíescurrency— es el contrato viejo y responde400(el cobro ya no se ata a una moneda local).countryes opcional y solo preselecciona el país en la página; el pagador puede cambiarlo.GOLDno tiene riel de pago propio: el cobro se alcanza siempre por conversión automática desde lo que pague el cliente.
201:
checkout_url (link, correo, WhatsApp, QR impreso). La página
no exige login, lleva el branding de tu organización y se actualiza sola:
cuando el pago se confirma por cualquiera de los métodos, muestra “pagado”
y redirige a tu success_url si la configuraste.
Cómo paga cada rail
- Fiat multi-país: el pagador elige país y método; el monto local se
cotiza al momento (meta → USD → moneda local con tu
payin_ratedel corredor, redondeado hacia arriba) y queda congelado al elegir el método. El abono acredita con la conversión y comisiones normales de payin y después se convierte alsettlement_asset. Un pago anunciado MENOR a la cotización congelada se acredita igual (la plata es real) pero no marca el link como pagado. Si un país ofrece el mismo método en varias monedas (ej. Bolivia con QR en BOB y en USD), la página lista cada moneda como opción independiente. En transferencias bancarias en México el link genera una CLABE dedicada y exclusiva de ese cobro: el pagador transfiere el monto exacto sin poner referencia — el abono se detecta y liquida automático porque la cuenta identifica al link. Si la cuenta dedicada no puede emitirse en ese momento, la página degrada al camino clásico (cuenta general del comercio + referencia obligatoria en la glosa). - Cobros pull (Venezuela):
c2pydebito_inmediatocobran directo en la cuenta del pagador. La página le pide banco, documento, teléfono (C2P) o cuenta (débito inmediato) y la clave OTP — generada en su app bancaria para C2P, o enviada a demanda para débito inmediato (botón “Solicitar clave”). El monto SIEMPRE es el congelado en la cotización; si el rail confirma síncrono, el link queda pagado al instante. Un rechazo no mata el link: el pagador corrige los datos o elige otro método. - Tarjeta (multi-moneda): la pestaña lista cada moneda de cargo disponible con su monto cotizado; al elegir una se abre la página de pago hosted en esa moneda. Cada moneda es una materialización independiente (puedes cotizar en BOB y en USD sobre el mismo link; paga la primera que complete).
- Crypto (wallet por cobro): al elegir una moneda se genera una
dirección exclusiva con su
qr_payloadyqr_png_base64— el QR lleva SIEMPRE la dirección cruda (BTC bech32, TRON base58, ETH hex) para máxima compatibilidad con wallets y exchanges (Binance y similares rechazan URIs BIP-21/EIP-681); el monto exacto se muestra al lado con botón copiar. Si el asset pagado difiere delsettlement_asset, el due cotizado ya incluye la conversión (la cubre el pagador; tú recibes tu meta exacta). Los pagos parciales se acumulan y la página muestra cuánto falta. Cotizaciones con BTC/GOLD se refrescan cada 15 minutos. - App CBPay: el QR del comercio embebe el link
(
cbpay:pay?to=…&checkout=…). La app paga por transferencia interna en cualquiera de los 4 saldos: mismo asset ⇒ meta exacta; distinto ⇒ due con la conversión incluida. El monto se valida server-side contra una cotización fresca — si no cubre el cobro responde422 checkout_amount_mismatchcon el monto vigente. Integradores:POST /v1/transfersacepta el campo opcionalcheckout_token(o el QR extendido ento_qr_token); el destino se fuerza a la cuenta del link.
Conversión automática al saldo elegido
Todo abono en un asset distinto alsettlement_asset se convierte con el
motor de conversiones de tu cuenta (mismos spreads y límites que
POST /v1/swaps). El estado agregado viaja en conversion_status:
Endpoints públicos del link (sin auth, rate-limited)
GET {checkout_url}/state— estado del link:status,paid_method,settlement_asset,asset_amount, materializaciones fiat congeladas (fiat_methods), progreso crypto (cryptocondue/received) yconversion_status.GET {checkout_url}/quote— cotizaciones ANTES de elegir:countries(catálogo por país; cada país lista sus corredores enoptions[]— una fila por método+moneda, concollect: trueen los métodos pull),cards(opciones de tarjeta por país y moneda con sulocal_amount),crypto(due indicativo por par) ycbpay(alias + dues por asset). Con?country=XXagregacountry_quotecon el monto local por opción de ese país.POST {checkout_url}/methods/{method}— materializa la opción elegida. Métodos fiat exigen?country=XX; si el país ofrece el método en más de una moneda (tarjetas, QR BOB/USD en Bolivia) exige además¤cy=YYY; crypto usacrypto:<chain>:<asset>(ej.crypto:tron:usdt) sin país. Los métodos pull devuelven el formulario del pagador (banks[],requires_otp_request) con la cotización congelada. Re-POST de la misma combinación devuelve la MISMA materialización.POST {checkout_url}/collect/otp— solicita la clave OTP de un cobro pull cuando el rail la envía a demanda (requires_otp_request: true, ej. débito inmediato VE). Devuelve elotp_referenceque acompaña al cobro final. Rate limit estricto (cada llamada es un SMS/push real).POST {checkout_url}/collect— ejecuta el cobro pull con los datos del pagador (banco, documento, teléfono o cuenta, OTP). El monto siempre es el congelado; si el rail confirma síncrono respondepaid: truey el link queda liquidado en la misma llamada.
Reglas del link
- Un link = un cobro: el primer método que completa el pago gana; un pago posterior por otro rail no se acredita (elegir un método NO bloquea los demás mientras nadie pague).
expires_inacepta de 600 a 604800 segundos (10 minutos a 7 días; default 24 horas). Al vencer sin pago el payin pasa aexpiredy recibes el webhookpayin_expired.- El retry con la misma
idempotency_keydevuelve el mismo link (la URL no cambia); jamás se abre un segundo cobro. - El
settlement_assetdebe estar habilitado para tu organización; si está apagado la creación responde422 settlement_asset_disabled.
payin_credited con settled_via
(ej. crypto:tron:usdt, qr, cbpay), settlement_asset y
asset_amount; los pagos crypto agregan crypto_amount y los pagos con
la app CBPay agregan transfer_id, asset y amount.
Errores propios del link (los ve quien abre la página):
3. Recibe el abono
Cuando el pago llega (por cualquiera de las modalidades), tu cuenta se acredita automáticamente y se emite el webhookpayin_credited:
fx_rate es tu payin_rate del momento del abono — la conversión se hace
exactamente a esa tasa: usdt_gross = 700.00 / 6.91.
El objeto payin queda con el detalle completo:
Estados
Los depósitos que llegan por transferencia directa sin referencia clara
quedan
unassigned hasta que el equipo de CBPay los asigna a una cuenta.
Al asignarse, se acreditan con la tasa y comisiones de la cuenta destino.Cuando un cobro activo (QR o checkout) muere sin pago, el payin pasa de
pending a expired (o failed) automáticamente y recibes el webhook
payin_expired. No se mueve dinero: si quieres reintentar
el cobro, crea un payin nuevo.Consulta e historial
from/to van en YYYY-MM-DD (UTC); fecha inválida responde
400 invalid_range.