Checkout.js
Checkout.js es la forma mas rapida de aceptar pagos QR en tu sitio web. Muestra un modal con el codigo QR que tus clientes pueden escanear con Yape, Plin o cualquier app bancaria.
Instalacion
Agrega el script en tu pagina HTML, antes de cerrar </body>:
<script src="https://app.taypi.pe/v1/checkout.js"></script>IMPORTANTE
Siempre carga el script desde https://app.taypi.pe. No lo descargues ni lo alojes en tu servidor, ya que se actualiza automaticamente con mejoras y parches de seguridad.
Flujo de integracion
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Frontend │ │ Backend │ │ TAYPI │
│ (Browser) │ │ (Tu server) │ │ (API) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. Click "Pagar" │ │
│────────────────────>│ │
│ │ │
│ │ 2. POST /payments │
│ │────────────────────>│
│ │ │
│ │ 3. checkout_token │
│ │<────────────────────│
│ │ │
│ 4. sessionToken │ │
│<────────────────────│ │
│ │ │
│ 5. Taypi.open() │ │
│ Modal QR visible │ │
│ │ │
│ 6. Cliente escanea │ │
│ con Yape/Plin │ │
│ │ │
│ 7. onSuccess() │ Webhook: │
│<─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ payment.completed │
│ │<────────────────────│Paso 1: Crear el pago en tu backend
Tu backend debe crear el pago via API o SDK y obtener el checkout_token.
TIP
El checkout_token es diferente a tus API keys. Es un token de uso unico que identifica la sesion de pago. Expira junto con el pago (15 minutos).
Paso 2: Abrir el modal en el frontend
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Mi Tienda</title>
</head>
<body>
<button id="btn-pagar">Pagar S/ 50.00</button>
<script src="https://app.taypi.pe/v1/checkout.js"></script>
<script>
Taypi.publicKey = 'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';
document.getElementById('btn-pagar').addEventListener('click', async () => {
// 1. Tu backend crea el pago y devuelve el token
const response = await fetch('/api/crear-pago', { method: 'POST' });
const { checkout_token } = await response.json();
// 2. Abre el modal de pago
Taypi.open({
sessionToken: checkout_token,
onSuccess: (result) => {
console.log('Pago completado:', result.payment_id);
window.location.href = '/gracias';
},
onExpired: () => {
alert('El QR ha expirado. Intenta de nuevo.');
},
onClose: () => {
console.log('El usuario cerro el modal.');
},
onError: (error) => {
console.error('Error:', error.message);
alert('Ocurrio un error. Intenta de nuevo.');
},
});
});
</script>
</body>
</html>Ejemplo completo con PHP
Backend (PHP)
<?php
// crear-pago.php
require 'vendor/autoload.php';
use Taypi\Taypi;
$taypi = new Taypi(
publicKey: 'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
secretKey: 'taypi_sk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
);
$payment = $taypi->createCheckoutSession([
'amount' => '50.00',
'currency' => 'PEN',
'reference' => 'ORD-' . uniqid(),
'description' => 'Compra en Mi Tienda',
]);
header('Content-Type: application/json');
echo json_encode([
'checkout_token' => $payment['checkout_token'],
]);Frontend (HTML)
<button id="btn-pagar">Pagar S/ 50.00</button>
<script src="https://app.taypi.pe/v1/checkout.js"></script>
<script>
Taypi.publicKey = 'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';
document.getElementById('btn-pagar').addEventListener('click', async () => {
const res = await fetch('/crear-pago.php', { method: 'POST' });
const { checkout_token } = await res.json();
Taypi.open({
sessionToken: checkout_token,
onSuccess: (result) => {
window.location.href = '/gracias.php?payment=' + result.payment_id;
},
onExpired: () => {
alert('El codigo QR expiro. Intenta de nuevo.');
},
onClose: () => {
console.log('Modal cerrado');
},
onError: (error) => {
alert('Error: ' + error.message);
},
});
});
</script>Ejemplo completo con Node.js
Backend (Express)
// server.js
import express from 'express';
import Taypi from 'taypi.pe';
const app = express();
const taypi = new Taypi(
'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
'taypi_sk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
);
app.post('/api/crear-pago', async (req, res) => {
const payment = await taypi.createCheckoutSession({
amount: '50.00',
currency: 'PEN',
reference: `ORD-${Date.now()}`,
description: 'Compra en Mi Tienda',
});
res.json({ checkout_token: payment.checkout_token });
});
app.listen(3000);Frontend (HTML)
<button id="btn-pagar">Pagar S/ 50.00</button>
<script src="https://app.taypi.pe/v1/checkout.js"></script>
<script>
Taypi.publicKey = 'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';
document.getElementById('btn-pagar').addEventListener('click', async () => {
const res = await fetch('/api/crear-pago', { method: 'POST' });
const { checkout_token } = await res.json();
Taypi.open({
sessionToken: checkout_token,
onSuccess: (result) => {
window.location.href = '/gracias?payment=' + result.payment_id;
},
onExpired: () => alert('El QR expiro.'),
onClose: () => console.log('Cerrado'),
onError: (error) => alert(error.message),
});
});
</script>Referencia de metodos
Taypi.publicKey
Establece tu clave publica. Requerido antes de llamar a Taypi.open().
Taypi.publicKey = 'taypi_pk_test_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';Taypi.open(options)
Abre el modal de pago con el codigo QR.
| Parametro | Tipo | Requerido | Descripcion |
|---|---|---|---|
sessionToken | string | Si | Token de la sesion de pago (obtenido de tu backend) |
onSuccess | function | No | Se ejecuta cuando el pago se completa |
onExpired | function | No | Se ejecuta cuando el QR expira (15 minutos) |
onClose | function | No | Se ejecuta cuando el usuario cierra el modal |
onError | function | No | Se ejecuta si ocurre un error |
Taypi.close()
Cierra el modal de pago programaticamente.
// Cerrar el modal despues de 30 segundos
setTimeout(() => {
Taypi.close();
}, 30000);Eventos
onSuccess(result)
Se ejecuta cuando el cliente completa el pago exitosamente.
onSuccess: (result) => {
console.log(result.payment_id); // "a14dfb8e-d5c2-4a69-bae4-4688fef5eac2"
console.log(result.status); // "completed"
console.log(result.amount); // "50.00"
console.log(result.reference); // "ORD-12345"
}IMPORTANTE
onSuccess solo indica que el frontend detecto el pago. Siempre verifica el pago en tu backend via webhook antes de entregar productos o servicios. Nunca confies unicamente en el frontend.
onExpired()
Se ejecuta cuando el codigo QR expira (15 minutos desde la creacion del pago).
onExpired: () => {
// Puedes crear un nuevo pago y volver a abrir el modal
alert('El codigo QR ha expirado. Intenta de nuevo.');
}onClose()
Se ejecuta cuando el usuario cierra el modal sin completar el pago (click en X o fuera del modal).
onClose: () => {
// El pago sigue pendiente hasta que expire
console.log('El usuario cerro el modal');
}onError(error)
Se ejecuta si ocurre un error al cargar el modal o durante el proceso de pago.
onError: (error) => {
console.error(error.code); // "PAYMENT_EXPIRED"
console.error(error.message); // "El pago ha expirado"
}Preguntas frecuentes
¿Puedo usar Checkout.js con React, Vue o Angular?
Si. Checkout.js funciona en cualquier framework frontend. Carga el script y llama a Taypi.open() desde el event handler de tu componente.
¿Que pasa si el usuario cierra el modal?
El pago permanece en estado pending hasta que expire (15 minutos). El usuario puede volver a escanear el QR mientras no haya expirado.
¿Necesito verificar el pago en mi backend?
Si, siempre. El callback onSuccess es solo una notificacion del frontend. La confirmacion definitiva llega via webhook. Procesa la entrega del producto o servicio solo cuando recibas el webhook payment.completed y verifiques su firma.