PIX
This page will help you get started with the PIX checkout (pago instantáneo brasileño vía QR / copy & paste).
Changelog
| Fecha | Versión | Breaking changes | Cambios |
|---|---|---|---|
| 05 oct 2026 | 1.1.0 | NO | initialize acepta showQR opcional para mostrar el QR en el SDK mobile. |
| 11 may 2026 | 1.0.0 | NO | Primera versión |
V1.1.0
Integración
Agregar el script de checkout de Koin.
- Producción: https://payments.koin.com.br/checkout/sdk/v1/methods.js
- Sandbox: https://portal-dev.koin.com.br/checkout/sdk/v1/methods.js
API
- Luego de agregar el script de checkout de Koin a tu página tendrás disponible dentro de window un objeto llamado KoinPayments.
- Crear una instancia de la clase order para el método de pago PIX de la siguiente manera (se espera un string con el orderId generado en Koin):
// PIX - Initialization method
// Initialize PIX by Order
const pix = await window.KoinPayments.order(orderId);- Una vez hecho esto, tendremos un objeto creado con los siguientes métodos:
-
initialize(afterInitializedCallback, options?): El método afterInitializedCallback se va a ejecutar solo cuando se haya podido inicializar el SDK de PIX con éxito. Caso contrario se puede recibir el error utilizando onError. Opcionalmente podés pasar options:
{ language?: 'es' | 'en' | 'pt'; showQR?: boolean }.- language: fuerza el idioma del checkout.
- showQR: con
true, el SDK mobile muestra el QR. Si se omite o esfalse, en mobile solo se muestra la acción de copiar el código. En desktop el QR se muestra siempre.
-
mount(containerCssSelector): Monta el checkout de PIX en el contenedor indicado. Los errores relacionados a esta función se devuelven en el onError. Parámetros:
- containerCssSelector: Selector CSS que apunte a un <div> donde se va a colocar el checkout de Koin.
A diferencia de Card, PIX no expone
hidePaymentButtonnihidePaymentSummary: el resumen de pago en contexto SDK se oculta siempre. En desktop el checkout muestra el QR. En mobile, el QR depende deshowQR: si se omite o esfalse, el usuario confirma copiando el código. -
onError({code, origin, message}): Manejo de errores de Koin. Siempre siguen el mismo formato.
-
onEvent(code, payload): Eventos para comunicar el estado del proceso. El payload es opcional.
-
onFinish(data): Callback que se ejecuta cuando la orden está finalizada o su estado se actualizó (por ejemplo ya cobrada, cancelada o expirada). El
datacontiene{ status, message }.statusesCollected,CancelledoFailed(PascalCase; no es el código deonEvent). Si la orden ya estaba terminada al llamar a initialize, el mensaje esOrder already finished. Si el iframe informa un estado final, el mensaje esOrder status updated. -
destroy(): Elimina la instancia existente del SDK de PIX si hay una.
-
Eventos
| Code | Description | Origen |
|---|---|---|
| CONFIGURATION_SET | Ocurre cuando la configuración del SDK fue aplicada correctamente. | Koin |
| MOUNT_STARTED | Ocurre cuando se inicia el montaje del checkout. | Koin |
| CHECKOUT_LOADED | Ocurre cuando el iframe del checkout terminó de cargar. | Koin |
| PUBLISHED | Ocurre cuando el QR de PIX fue publicado y está listo para ser escaneado. | Koin |
| WALLET_DESTROYED | Ocurre cuando se llamó a destroy() y la instancia fue eliminada. | Koin |
Errores
| Code | Description | Origen |
|---|---|---|
| INIT_MISSING_WISH_ID | Ocurre cuando la consulta interna por order_id que fue usado en KoinPayments.order() no retorna ningún wish_id. | Koin |
| INIT_MISSING_ORDER_ID | Ocurre cuando el order_id que fue usado en KoinPayments.order() es undefined o null. | Koin |
| INITIALIZATION_ERROR | Ocurre cuando la configuración no es válida. | Koin |
| MOUNT_ERROR | Ocurre cuando no se pudo encontrar el contenedor especificado para montar el checkout u ocurrió un error interno al crear el mismo. | Koin |
| CONFIGURATION_ERROR | Ocurre cuando existe un error de configuración del listener de comunicación. | Koin |
Estados de onFinish
data.status es el estado de la orden en PascalCase. No es el código de onEvent. PUBLISHED no llama a onFinish.
| status | Description |
|---|---|
| Collected | Ocurre cuando el pago fue cobrado. |
| Cancelled | Ocurre cuando el usuario canceló el flujo o el QR fue cancelado. |
| Failed | Ocurre cuando el pago falló o el caso es irrecuperable. |
FAQ
¿onFinish se dispara siempre con la orden en un estado final?
onFinish se dispara siempre con la orden en un estado final?Sí. onFinish se dispara solo con un estado final de la tabla de arriba. No se dispara con eventos intermedios, una revisión de antifraude, una autenticación 3DS ni un pago pendiente.
¿Qué pasa si hay timeout, error de red, o el usuario cierra la pestaña?
Si el usuario cierra la pestaña, el SDK no lo informa por ningún evento. Timeout y error de red tampoco disparan onFinish. En esos casos el estado de la orden se toma de la notificación por webhook y del GET /v1/payment/orders/{id}. onError no es ese estado: aunque un fallo del SDK pueda llegar por ahí, no reemplaza a la notificación por webhook ni al GET.
Si la orden expira, onFinish sí se dispara, con status Cancelled.
¿El status de onFinish puede diferir del GET o del webhook?
onFinish puede diferir del GET o del webhook?No. El status de onFinish sale del mismo GET /v1/payment/orders/{id} y es un estado final. Consultar ese GET en ese momento devuelve la misma respuesta.
La fuente de verdad es siempre la notificación por webhook y ese GET. No recomendamos, bajo ningún término, reemplazar la notificación por webhook o el GET Status por el onFinish del SDK.
Cuando se dispara onFinish, ¿el estado ya está en la API?
onFinish, ¿el estado ya está en la API?Sí. Como el status sale de ese mismo GET, no hay demora. El estado ya está reflejado en la API.
Ejemplo
1 - Crear una instancia de checkout
Solo deberán pasar el orderId generado en Koin.
// PIX - Initialization method
// Initialize PIX by Order
const pix = await window.KoinPayments.order(orderId);2 - Agregar listeners
Sólo se puede usar una sola vez cada método, onError, onEvent y onFinish.
pix.onError((error) => {
console.log("Error from callback: ", error.code, error.message, error.origin);
});
pix.onEvent((event, payload) => {
console.log("Event from callback: ", event, payload);
switch (event) {
case "PUBLISHED":
// El QR ya está visible y listo para ser escaneado
break;
default:
break;
}
});
pix.onFinish((data) => {
console.log("Finish from callback: ", data.status, data.message);
switch (data.status) {
case "Collected":
// El pago fue cobrado
break;
case "Cancelled":
// El usuario canceló o el QR fue cancelado
break;
case "Failed":
// El caso es irrecuperable
break;
}
});3 - Iniciar flujo y montar el checkout
El método initialize se puede usar la cantidad de veces que se necesite. El método mount se debe usar dentro del callback del initialize:
async function onClick() {
pix.initialize(
() => {
console.log("Initialized");
// #checkout-container es la div donde se montará la experiencia de checkout
pix.mount("#checkout-container");
},
{
showQR: true,
}
);
}4 - Código completo
const pix = await window.KoinPayments.order(orderId);
pix.onError((error) => {
console.log("Error: ", error.code, error.message, error.origin);
});
pix.onEvent((event, payload) => {
console.log("Event: ", event, payload);
});
pix.onFinish((data) => {
console.log("Finish from callback: ", data.status, data.message);
switch (data.status) {
case "Collected":
// El pago fue cobrado
break;
case "Cancelled":
// El usuario canceló o el QR fue cancelado
break;
case "Failed":
// El caso es irrecuperable
break;
}
});
async function onClick() {
pix.initialize(
() => {
console.log("Initialized");
pix.mount("#checkout-container");
},
{
showQR: true,
}
);
}Updated 17 days ago
