Recursos avançados SDK da Web

Opções de configuração avançadas e integrações personalizadas para o Yuno Web SDK.

Opções alternativas de montagem

O fluxo básico utiliza mountCheckout() para exibição automática do método de pagamento. Para maior controle, use estas alternativas:

Seleção de método de pagamento personalizado (mountCheckoutLite())

Controle qual método de pagamento exibir:

// 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 e Apple Pay com Lite:

await yuno.mountExternalButtons([
  {
    paymentMethodType: 'GOOGLE_PAY',
    elementSelector: '#google-pay-button'
  },
  {
    paymentMethodType: 'APPLE_PAY',
    elementSelector: '#apple-pay-button'
  }
]);

Fluxo simplificado (mountSeamlessCheckout())

Semelhante a mountCheckoutLite() mas com criação automática de pagamentos:

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

Inscrição (Salvar cartões)

Salvar durante o pagamento

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

Inscrição separada

// 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 armazenados

// Use saved card
yuno.mountCheckout({
  vaultedToken: 'vtok_saved_card_123'
});

// Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
  yuno.startPayment();
});

IU personalizada (integração sem interface gráfica)

Crie formulários de pagamento totalmente personalizados com controle total da interface do usuário quando precisar de controle total sobre todos os elementos da interface, criando experiências de checkout altamente personalizadas ou tiver recursos de desenvolvimento para interfaces personalizadas. O Yuno lida apenas com a tokenização.

Implementação

1. Initialize o cliente Initialize

const yuno = await Yuno.initialize('your-public-key');

const apiClientPayment = yuno.apiClientPayment({
  country_code: "US",
  checkout_session: "checkout_session_id"
});

2. Crie seu formulário 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. Gerar 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. Lidar com 3DS e redirecionamentos

const continueResult = await yuno.continuePayment({ showPaymentStatus: false });

if (continueResult?.action === 'REDIRECT_URL') {
  window.location.href = continueResult.redirect.init_url;
}

Com Token Vaulted Token

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 (formulários de cartão personalizados)

Crie formulários de cartão personalizados mantendo a conformidade com PCI usando campos iframe seguros. Ideal quando você deseja um design personalizado para o formulário do cartão, precisa de layouts de campo específicos ou requer segurança baseada em iframe para cartões.

Implementação

1. Instalar e Initialize

const yuno = aguardar Yuno.initialize('sua-chave-pública');

2. Criar 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'
      }
    }
  }
}

Várias moedas

Lide com pagamentos em várias moedas com conversão 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 e temas

CSS personalizado

yuno.startCheckout({
  // ... other config
  cssCustomization: {
    primaryColor: '#007bff',
    errorColor: '#dc3545',
    fontFamily: 'Inter, sans-serif'
  }
});

Texto personalizado do botão

yuno.startCheckout({
  // ... other config
  texts: {
    pay: 'Complete Purchase',
    processing: 'Processing...',
    error: 'Payment Failed'
  }
});

Modos de renderização

Exibição modal

yuno.startCheckout({
  renderMode: 'modal',
  elementSelector: '#payment-container'
});

Exibição em linha

yuno.startCheckout({
  renderMode: 'element',
  elementSelector: '#payment-container'
});

Prevenção de fraudes

Impressão digital do dispositivo

Coletados automaticamente pelo SDK para provedores de fraude configurados (ClearSale, etc.).

Dados personalizados sobre fraudes

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

Parcelas

Ativar parcelamento

yuno.startCheckout({
  // ... other config
  card: {
    installments: {
      enabled: true,
      defaultValue: 1
    }
  }
});

Planos de parcelamento personalizados

Configurado no painel do Yuno por método de pagamento.

Controle do carregador

Ocultar Yuno Loader

yuno.startCheckout({
  showLoading: false, // Use your own loader
  onLoading: (isLoading) => {
    document.getElementById('custom-loader').style.display = 
      isLoading ? 'block' : 'none';
  }
});

Carregador personalizado

yuno.startCheckout({
  // ... other config
  onLoading: (isLoading) => {
    if (isLoading) {
      showCustomSpinner();
    } else {
      hideCustomSpinner();
    }
  }
});

Tipos de formulários de cartão

Formulário ampliado (campos separados)

yuno.startCheckout({
  card: {
    type: 'extends' // Shows separate fields for all card details
  }
});

Formulário compacto (campo único)

yuno.startCheckout({
  card: {
    type: 'only' // Shows single combined field
  }
});

Seleção do emissor

Formulário para ativar/desativar emissor

yuno.startCheckout({
  issuersFormEnable: true // Show issuer selection for bank transfers
});

Página de status do pagamento

Tratamento personalizado de status

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

Retornos de chamada de eventos

Todas as chamadas de retorno disponíveis

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

Compatibilidade com navegadores

O SDK suporta:

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Borda 90+

Polyfills para navegadores mais antigos

<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<script src="https://sdk-web.y.uno/v1.5/main.js"></script>

Otimização de desempenho

SDK de carregamento lento

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

Pré-conecte-se aos servidores Yuno

<link rel="preconnect" href="https://api.y.uno">
<link rel="preconnect" href="https://sdk-web.y.uno">

Testes na área restrita

Configuração do modo de teste

// Use test keys (pk_test_*)
const yuno = await Yuno.initialize('pk_test_your_key_here');

Simule cenários de pagamento

// Backend: Create session with test data
{
  amount: { currency: 'USD', value: 1000 },
  metadata: {
    test_scenario: 'success' // 'success', 'decline', '3ds_required'
  }
}

Tratamento de erros

Códigos de erro comuns

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

Integração com Webhooks

Verifique o status do pagamento no backend por meio de 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);
});

Configuração do ambiente

Desenvolvimento

const yuno = await Yuno.initialize('pk_test_dev_key', {
  environment: 'sandbox',
  debug: true // Enable console logs
});

Produção

const yuno = await Yuno.initialize('pk_live_prod_key', {
  environment: 'production',
  debug: false
});