#

Widget de pago

El Widget embebe el checkout de Chytapay directamente en tu sitio: tu comprador paga por transferencia sin salir de tu página. Lo integrás con unas pocas líneas de JavaScript.

  • El SDK corre en el navegador y se autentica con tu clave pública (pk).
  • El pago lo creás en tu servidor con la API de integración; el Widget solo lo muestra.
  • La UI del checkout vive en un iframe de Chytapay: no manejás datos sensibles.
Ver el Widget en acción →
#

Cómo funciona

El Widget se apoya en un par de claves a nivel de tu integración (mismo modelo que Stripe o Mercado Pago): una mitad pública para el navegador y una mitad secreta para tu servidor.

pk (publishable key)Va en el navegador, dentro de tu HTML/JS. Identifica tu integración. Es pública por diseño: no da acceso a nada sensible.
sk (secret key)Va solo en tu servidor. Es la mitad secreta del par, para llamadas server-to-server. Nunca la pongas en el frontend.
iframeLa pantalla de pago la renderiza Chytapay dentro de un iframe. Tu página nunca toca CBU, importes ni el estado del pago: solo pasa el id.
Una integración tiene un solo par pk/sk, compartido por todos los comercios que cobra. El comercio cobrador se identifica del lado del servidor cuando creás el pago — no en el navegador.
#

Qué ve el pagador

El checkout se maneja solo: pasás el paymentId y no volvés a intervenir hasta el callback. Estas son las pantallas que ve tu comprador.

  1. Ingresa su documento. CUIL, CUIT o DNI. El pago se concilia por ese documento, no por el CVU.
  2. Recibe la cuenta. El CVU al que transferir, con botón para copiar y una cuenta regresiva hasta el vencimiento del cobro.
  3. Ve a nombre de quién. En esa misma pantalla le mostramos el nombre que ARCA tiene registrado para su documento, porque la transferencia tiene que salir de una cuenta a ese nombre.
  4. Transfiere. Desde su propia cuenta. Si sale de otra, puede no acreditarse.
  5. Ve el resultado. Si entró todo, se dispara onSuccess. Si entró de menos, ve cuánto falta y el mismo CVU para completar.
El nombre es una advertencia, no una validación: no hay un paso donde el pagador tenga que confirmarlo. Si ARCA no responde, o no hay titular para ese documento, el flujo sigue igual y el cobro se adjunta con lo que escribió.
Si la transferencia igual sale de otra cuenta, el pago no se imputa al cobro: te llega como no conciliado y el cobro sigue pendiente hasta vencer. Vas a recibir el vencimiento por una orden que en realidad se pagó, así que conviene contemplar ese caso en tu conciliación.
#

Paso 1: Obtener tus claves

Generás el par pk/sk desde el Portal de integración, en My Integration → Credenciales → Claves del Widget.

  1. Entrá al Portal y abrí la sección Credenciales.
  2. Generá las claves del Widget. La pk queda visible siempre; la sk se muestra una única vez.
  3. Guardá la sk en un lugar seguro (un secret manager, variables de entorno). Si la perdés, rotála desde el mismo lugar.
La sk se muestra una sola vez, al generarla o rotarla. No queda guardada en claro en ningún lado — si no la copiaste, rotála para obtener una nueva.
Abrir Portal de integración →
#

Paso 2: Crear el pago en tu servidor

El Widget no crea pagos: muestra uno que ya existe. Desde tu servidor creás el cobro con type: "checkout" y te quedás con el paymentRequestId. Ese id es lo único que le pasás al Widget.

Para crear el cobro, seguí la guía de Crear cobros. El paymentId del Widget es el id del payment request que te devuelve la API.

En modo checkout el cobro nace sin CVU. La cuenta se asigna cuando el pagador se identifica adentro del widget, y ahí se la mostramos a él. Tu servidor no la necesita.
Creá el pago server-to-server, nunca desde el navegador: ahí es donde vive tu sk / token de integración.
#

Paso 3: Instalar el SDK

Sumás el SDK de dos maneras: por CDN con una etiqueta script, o instalándolo desde npm si usás un bundler.

html — vía CDN (unpkg)
<script src="https://unpkg.com/@chytapay/integration-widget@1"></script>
bash — vía npm
npm i @chytapay/integration-widget
javascript — import (bundler)
import { ChytaPay } from '@chytapay/integration-widget';
Por CDN, el SDK queda disponible como window.ChytaPay. Con un bundler, importás { ChytaPay } del paquete.
Pineá la major, no la versión exacta. Con @1 te siguen llegando los arreglos y las mejoras, y lo que rompe compatibilidad no te puede entrar hasta que cambies ese número a mano. Sin versión en la URL, unpkg sirve siempre la última que publicamos, así que nuestra publicación pasa a ser tu deploy.
#

Paso 4: Mostrar el checkout

Inicializás el SDK con tu pk una sola vez, y después abrís el checkout pasándole el paymentId. El SDK monta el iframe, maneja el flujo de pago y te devuelve un handle para cerrarlo desde tu código.

javascript — init + checkout
// 1. Inicializá el SDK una vez, con tu clave pública.
// Las URLs por defecto ya son las de producción.
ChytaPay.init({ pk: 'pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' });

// 2. Abrí el checkout para un pago creado en tu servidor.
const handle = ChytaPay.checkout({
  paymentId: 'PAYMENT_ID_DE_TU_SERVIDOR',
  onSuccess: (paymentId) => {
    // El pago se acreditó: confirmá la compra en tu UI.
    showConfirmation(paymentId);
  },
  onError: (error) => {
    // Falló o venció: mostrale el error a tu comprador.
    showError(error);
  },
  onCancel: () => {
    // El comprador cerró el checkout sin pagar.
  },
});

// 3. Opcional: cerralo desde tu código si navegás a otra pantalla.
handle.close();
Los valores por defecto ya apuntan a producción, así que en el caso normal no pasás ni apiBaseUrl ni iframeUrl. Solo se pasan para apuntar a otro ambiente.
onSuccess se dispara cuando el pago se acredita. Es una señal de UI para tu comprador: la fuente de verdad de que el pago se completó sigue siendo tu webhook server-to-server.
#

Cómo probarlo

El checkout se prueba contra la API de test, con cobros que no mueven plata real. Como el iframe es una vista pura y el SDK es el único que habla con la API, alcanza con apuntar apiBaseUrl a test y dejar iframeUrl en su valor por defecto.

javascript — apuntar el SDK a test
ChytaPay.init({
  pk: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  apiBaseUrl: 'https://integration-api.test.chytapay.com.ar',
});
No hace falta tocar iframeUrl: hoy el iframe existe solo en producción, y es correcto usarlo contra test porque no guarda estado ni habla con la API. Todo lo que ve le llega del SDK.

Los cobros de prueba los creás con el token de test que genera el Portal. Está en la guía de Usar el Portal, en la sección de testing.

#

Cuando algo falla

El checkout le muestra al pagador el mensaje que corresponde y decide solo si lo deja reintentar.

Qué ve el pagadorQué pasóQué hacés vos
“El documento ingresado no es válido.”No tiene forma de CUIL, CUIT ni DNI.Nada: lo corrige ahí mismo y sigue.
“Este cobro ya tiene un pagador asociado.”Se intentó pasar el cobro al documento nuevo y no se pudo: ya hay plata acreditada, o el cobro llegó a un estado final.Generá un cobro nuevo. Con plata adentro, el cobro ya no cambia de dueño.
“No pudimos asignarte una cuenta para transferir. Probá de nuevo en unos minutos.”Tu comercio no tiene ninguna cuenta libre para el documento nuevo en este momento. Es transitorio y es capacidad tuya, no un problema del cobro.No generes un cobro nuevo: este sigue vivo. El pagador puede reintentar en unos minutos. Si se repite seguido, revisá la disponibilidad de cuentas de tu comercio.
“Este cobro ya no admite pagos.”Está pago, vencido o cancelado.Generá un cobro nuevo.
“No pudimos preparar el cobro.”Un problema de configuración de tu integración.Es tuyo, no del pagador. Revisá que el cobro se haya creado con la integración correcta.
Dos de estos se resuelven sin salir del checkout, y por motivos opuestos: el documento inválido lo corrige el pagador ahí mismo, y la falta de cuenta libre se destraba sola cuando se libera una. Ninguno de los dos dispara onError. Los otros tres sí lo disparan y terminan el flujo: esos son los que conviene tratar como cobro muerto.
#

Referencia rápida

ChytaPay.init(config)
pkrequeridoTu clave pública. Identifica la integración.
apiBaseUrlopcionalBase de la API del Widget (/v1). Por defecto https://integration-api.chytapay.com.ar. Pasalo solo para apuntar a otro ambiente.
iframeUrlopcionalURL del iframe del checkout. Por defecto https://widget.chytapay.com.ar/checkout/. Pasalo solo para apuntar a otro ambiente.
requestTimeoutMsopcionalTimeout de las llamadas del SDK, en milisegundos.
ChytaPay.checkout(options)
paymentIdrequeridoEl id del payment request creado en tu servidor.
onSuccessopcionalCallback al acreditarse el pago. Recibe el paymentId.
onErroropcionalCallback ante un fallo o vencimiento. Recibe un Error.
onCancelopcionalCallback cuando el comprador cierra el checkout sin pagar.
containeropcionalDónde montar el checkout. Por defecto el SDK crea un modal que se cierra con Escape, con el fondo o con la X. Si pasás un elemento propio, queda embebido en tu página y el cierre lo manejás vos.
localeopcionalFormato de importes y fechas dentro del checkout. Default es-AR. No cambia el idioma: los textos están en español.
themeopcionalColores y tipografía del checkout. Acepta variables CSS con prefijo --chytapay- (por ejemplo --chytapay-primary). Las claves con otro prefijo se ignoran.
pollScheduleopcionalCada cuánto le preguntamos al backend si el pago entró. Por defecto: cada 1 segundo los primeros 20, cada 2 hasta los 40, y cada 10 de ahí en adelante. Pasá un número para un intervalo fijo, o una función del tiempo transcurrido en ms.
checkout() devuelve un handle con un solo método, close(), que desmonta el widget. No dispara onCancel: si lo cerraste vos, ya sabés qué pasó. El poller se apaga solo al llegar a un estado final, y como techo, dos minutos después del vencimiento del cobro.