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())

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())

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
});