Funciones avanzadas SDK web
Opciones de configuración avanzadas e integraciones personalizadas para el SDK web de Yuno.
Opciones de montaje alternativas
El flujo básico utiliza mountCheckout() para mostrar automáticamente pago . Para tener más control, utiliza estas alternativas:
Selección de pago personalizado (mountCheckoutLite())
mountCheckoutLite())Controla qué pago mostrar:
// 1. Fetch available methods from backend
const methods = await fetch('/api/payment-methods').then(r => r.json());
// 2. Display methods in your custom UI
// 3. Mount selected payment method
yuno.mountCheckoutLite({
paymentMethodType: selectedMethod, // 'CARD', 'PIX', etc.
vaultedToken: null // or saved token
});
// 4. Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
yuno.startPayment();
});Google Pay y Apple Pay con Lite:
await yuno.mountExternalButtons([
{
paymentMethodType: 'GOOGLE_PAY',
elementSelector: '#google-pay-button'
},
{
paymentMethodType: 'APPLE_PAY',
elementSelector: '#apple-pay-button'
}
]);Flujo simplificado (mountSeamlessCheckout())
mountSeamlessCheckout())Similar a mountCheckoutLite() pero con pago automática pago :
// Use startSeamlessCheckout instead of startCheckout
yuno.startSeamlessCheckout({
// Same configuration
});
// Mount
yuno.mountSeamlessCheckout({
paymentMethodType: 'CARD'
});
// Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
yuno.startPayment();
});Inscripción (Guardar tarjetas)
Ahorra durante pago
yuno.startCheckout({
checkoutSession: session.id,
elementSelector: '#payment-container',
countryCode: 'US',
card: {
cardSaveEnable: true // Shows "Save card" checkbox
},
async yunoCreatePayment(token) {
await fetch('/api/payment/create', {
method: 'POST',
body: JSON.stringify({
token,
vault_on_success: true // Save card after successful payment
})
});
yuno.continuePayment();
}
});Inscripción por separado
// Create customer session on backend
const customerSession = await fetch('/api/customer/session', {
method: 'POST',
body: JSON.stringify({ customer_id: 'cus_123' })
}).then(r => r.json());
// Initialize enrollment
yuno.startEnrollment({
customerSession: customerSession.id,
countryCode: 'US',
async yunoEnrolled(vaultedToken) {
console.log('Card saved:', vaultedToken);
}
});
// Mount enrollment form
yuno.mountEnrollment();Token almacenados
// Use saved card
yuno.mountCheckout({
vaultedToken: 'vtok_saved_card_123'
});
// Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
yuno.startPayment();
});Interfaz de usuario personalizada (integración sin interfaz gráfica)
Crea pago totalmente personalizados con control total de la interfaz de usuario cuando necesites controlar cada elemento de la interfaz, crear experiencias de pago altamente personalizadas o dispongas de recursos de desarrollo para una interfaz de usuario personalizada. Yuno solo se encarga de la tokenización.
Implementación
1. Initialize el cliente Initialize
const yuno = await Yuno.initialize('your-public-key');
const apiClientPayment = yuno.apiClientPayment({
country_code: "US",
checkout_session: "checkout_session_id"
});2. Crea tu formulario personalizado
<form id="custom-payment-form">
<input id="card-number" placeholder="Card Number" />
<input id="expiry" placeholder="MM/YY" />
<input id="cvv" placeholder="CVV" />
<input id="cardholder" placeholder="Cardholder Name" />
<button type="submit">Pay</button>
</form>3. Generar Token
document.getElementById('custom-payment-form').addEventListener('submit', async (e) => {
e.preventDefault();
try {
const result = await apiClientPayment.generateToken({
checkout_session: "checkout_session_id",
payment_method: {
type: "CARD",
vaulted_token: null,
card: {
save: false,
detail: {
number: document.getElementById('card-number').value,
expiration_month: 12,
expiration_year: 25,
security_code: document.getElementById('cvv').value,
holder_name: document.getElementById('cardholder').value,
type: "CREDIT"
}
}
}
});
// Create payment with token
await createPayment(result.token);
} catch (error) {
console.error('Token generation failed:', error);
}
});4. Manejar 3DS y redireccionamientos
const continueResult = await yuno.continuePayment({ showPaymentStatus: false });
if (continueResult?.action === 'REDIRECT_URL') {
window.location.href = continueResult.redirect.init_url;
}Con Token almacenado
const result = await apiClientPayment.generateToken({
checkout_session: "checkout_session_id",
payment_method: {
type: "CARD",
vaulted_token: "saved_token_id",
card: {
detail: {
security_code: "123"
}
}
}
});Campos seguros (formularios de tarjetas personalizados)
Crea formularios de tarjetas personalizados sin dejar de cumplir con la normativa PCI utilizando campos iframe seguros. Ideal cuando deseas un diseño de formulario de tarjeta personalizado, necesitas diseños de campos específicos o requieres seguridad basada en iframe para las tarjetas.
Implementación
1. Instalar e Initialize
const yuno = await Yuno.initialize('tu-clave-pública');2. Crear campos seguros
<div id="card-number-field"></div>
<div id="cvv-field"></div>
<div id="expiry-field"></div>yuno.secureFields({
checkoutSession: 'session_id',
countryCode: 'US',
fields: {
cardNumber: {
elementSelector: '#card-number-field',
placeholder: '1234 5678 9012 3456'
},
cvv: {
elementSelector: '#cvv-field',
placeholder: 'CVV'
},
expiry: {
elementSelector: '#expiry-field',
placeholder: 'MM/YY'
}
},
onFieldChange: (field, isValid) => {
console.log(`${field} valid:`, isValid);
},
async onSubmit(token) {
await createPayment(token);
}
});3. Estilo personalizado
fields: {
cardNumber: {
elementSelector: '#card-number-field',
style: {
base: {
color: '#333',
fontSize: '16px',
fontFamily: 'Arial, sans-serif'
},
invalid: {
color: '#ff0000'
}
}
}
}Múltiples divisas
Gestiona pagos en varias divisas con conversión automática.
// Create session with alternative amount
const session = await fetch('/api/checkout/session', {
method: 'POST',
body: JSON.stringify({
amount: { currency: 'USD', value: 1000 },
alternative_amount: { currency: 'BRL', value: 5000 }, // Display price
country: 'BR'
})
}).then(r => r.json());
// SDK automatically displays both currencies
yuno.startCheckout({
checkoutSession: session.id,
countryCode: 'BR',
// ...
});Estilo y temas
CSS personalizado
yuno.startCheckout({
// ... other config
cssCustomization: {
primaryColor: '#007bff',
errorColor: '#dc3545',
fontFamily: 'Inter, sans-serif'
}
});Texto personalizado del botón
yuno.startCheckout({
// ... other config
texts: {
pay: 'Complete Purchase',
processing: 'Processing...',
error: 'Payment Failed'
}
});Modos de renderizado
Visualización modal
yuno.startCheckout({
renderMode: 'modal',
elementSelector: '#payment-container'
});Pantalla en línea
yuno.startCheckout({
renderMode: 'element',
elementSelector: '#payment-container'
});Prevención del Fraude
Huella digital del dispositivo
Recopilados automáticamente por SDK para proveedores de fraude configurados (ClearSale, etc.).
Datos personalizados sobre fraude
yuno.startCheckout({
// ... other config
async yunoCreatePayment(token, tokenWithInformation) {
// tokenWithInformation includes fraud data
await fetch('/api/payment/create', {
method: 'POST',
body: JSON.stringify({
token,
device_fingerprint: tokenWithInformation.device_fingerprint,
customer_browser_info: tokenWithInformation.customer.browser_info
})
});
}
});Cuotas
Habilitar pagos a plazos
yuno.startCheckout({
// ... other config
card: {
installments: {
enabled: true,
defaultValue: 1
}
}
});Planes de pago personalizados
Configurado en el panel de control de Yuno por pago .
Control del cargador
Ocultar Yuno Loader
yuno.startCheckout({
showLoading: false, // Use your own loader
onLoading: (isLoading) => {
document.getElementById('custom-loader').style.display =
isLoading ? 'block' : 'none';
}
});Cargador personalizado
yuno.startCheckout({
// ... other config
onLoading: (isLoading) => {
if (isLoading) {
showCustomSpinner();
} else {
hideCustomSpinner();
}
}
});Tipos de formularios de tarjetas
Formulario ampliado (campos separados)
yuno.startCheckout({
card: {
type: 'extends' // Shows separate fields for all card details
}
});Formulario compacto (campo único)
yuno.startCheckout({
card: {
type: 'only' // Shows single combined field
}
});Selección del emisor
Formulario para habilitar/deshabilitar emisores
yuno.startCheckout({
issuersFormEnable: true // Show issuer selection for bank transfers
});Página pago
Gestión personalizada del estado
yuno.startCheckout({
showPaymentStatus: false, // Handle status yourself
yunoPaymentResult: (data) => {
// Redirect to custom status page
window.location.href = `/payment-status?id=${data.payment_id}&status=${data.status}`;
}
});Devoluciones de llamada de eventos
Todas las devoluciones de llamada disponibles
yuno.startCheckout({
// ... other config
// Payment method selected
yunoPaymentMethodSelected: (data) => {
console.log('Selected:', data.type);
analytics.track('payment_method_selected', { type: data.type });
},
// Payment created (before processing)
async yunoCreatePayment(token, tokenInfo) {
console.log('Creating payment with token:', token);
await processPayment(token);
yuno.continuePayment();
},
// Payment completed
yunoPaymentResult: (data) => {
console.log('Payment result:', data.status);
if (data.status === 'SUCCEEDED') {
gtag('event', 'purchase', { value: data.amount });
}
},
// Error occurred
yunoError: (error, data) => {
console.error('Error:', error, data);
Sentry.captureException(error);
},
// Loading state changed
onLoading: (isLoading) => {
console.log('Loading:', isLoading);
},
// Card form changed
card: {
onChange: ({ error, data }) => {
if (error) {
console.log('Card validation error:', error);
} else {
console.log('Card data:', data);
}
}
}
});Compatibilidad con navegadores
El SDK es compatible con:
- Chrome 90+
- Firefox 88+
- Safari 14+
- Borde 90+
Polyfills para navegadores antiguos
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<script src="https://sdk-web.y.uno/v1.5/main.js"></script>Optimización del rendimiento
SDK de carga diferida
// Load SDK only when needed
async function loadYunoSDK() {
if (typeof Yuno !== 'undefined') return;
return new Promise((resolve) => {
const script = document.createElement('script');
script.src = 'https://sdk-web.y.uno/v1.5/main.js';
script.onload = resolve;
document.head.appendChild(script);
});
}
// Use when payment page loads
document.getElementById('checkout-btn').addEventListener('click', async () => {
await loadYunoSDK();
initPayment();
});Conéctate previamente a los servidores de Yuno.
<link rel="preconnect" href="https://api.y.uno">
<link rel="preconnect" href="https://sdk-web.y.uno">Pruebas en Sandbox
Configuración del modo de prueba
// Use test keys (pk_test_*)
const yuno = await Yuno.initialize('pk_test_your_key_here');Simular pago
// Backend: Create session with test data
{
amount: { currency: 'USD', value: 1000 },
metadata: {
test_scenario: 'success' // 'success', 'decline', '3ds_required'
}
}Gestión de errores
Códigos de error comunes
yunoError: (error, data) => {
switch(error.code) {
case 'SESSION_EXPIRED':
// Recreate session
refreshSession();
break;
case 'INVALID_CARD':
showError('Please check your card details');
break;
case 'INSUFFICIENT_FUNDS':
showError('Insufficient funds');
break;
case 'NETWORK_ERROR':
showError('Connection error. Please try again.');
break;
default:
showError('An error occurred. Please try again.');
}
}Integración de webhooks
Verifica pago en el backend mediante webhooks:
// Backend webhook handler
app.post('/webhooks/yuno', (req, res) => {
const event = req.body;
switch(event.type) {
case 'payment.succeeded':
fulfillOrder(event.data.payment_id);
break;
case 'payment.failed':
cancelOrder(event.data.payment_id);
break;
}
res.sendStatus(200);
});Configuración del entorno
Desarrollo
const yuno = await Yuno.initialize('pk_test_dev_key', {
environment: 'sandbox',
debug: true // Enable console logs
});Producción
const yuno = await Yuno.initialize('pk_live_prod_key', {
environment: 'production',
debug: false
});Actualizado hace 2 días