Advanced Features Web SDK
Advanced configuration options and custom integrations for the Yuno Web SDK.
Alternative Mounting Options
The basic flow uses mountCheckout() for automatic payment method display. For more control, use these alternatives:
Custom Payment Method Selection (mountCheckoutLite())
mountCheckoutLite())Control which payment method to display:
// 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 & Apple Pay with Lite:
await yuno.mountExternalButtons([
{
paymentMethodType: 'GOOGLE_PAY',
elementSelector: '#google-pay-button'
},
{
paymentMethodType: 'APPLE_PAY',
elementSelector: '#apple-pay-button'
}
]);Simplified Flow (mountSeamlessCheckout())
mountSeamlessCheckout())Similar to mountCheckoutLite() but with automatic payment creation:
// 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();
});Enrollment (Save Cards)
Save During Payment
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();
}
});Separate Enrollment
// 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();Vaulted Token Payments
// Use saved card
yuno.mountCheckout({
vaultedToken: 'vtok_saved_card_123'
});
// Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
yuno.startPayment();
});Custom UI (Headless Integration)
Build completely custom payment forms with full UI control when you need complete control over every UI element, building highly custom checkout experiences, or have development resources for custom UI. Yuno handles only tokenization.
Implementation
1. Initialize Headless Client
const yuno = await Yuno.initialize('your-public-key');
const apiClientPayment = yuno.apiClientPayment({
country_code: "US",
checkout_session: "checkout_session_id"
});2. Build Your Custom Form
<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. Generate 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. Handle 3DS & Redirects
const continueResult = await yuno.continuePayment({ showPaymentStatus: false });
if (continueResult?.action === 'REDIRECT_URL') {
window.location.href = continueResult.redirect.init_url;
}With 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"
}
}
}
});Secure Fields (Custom Card Forms)
Build custom card forms while maintaining PCI compliance using secure iframe fields. Ideal when you want custom card form design, need specific field layouts, or require iframe-based security for cards.
Implementation
1. Install & Initialize
const yuno = await Yuno.initialize('your-public-key');2. Create Secure Fields
<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. Custom Styling
fields: {
cardNumber: {
elementSelector: '#card-number-field',
style: {
base: {
color: '#333',
fontSize: '16px',
fontFamily: 'Arial, sans-serif'
},
invalid: {
color: '#ff0000'
}
}
}
}Multiple Currencies
Handle multi-currency payments with automatic conversion.
// 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',
// ...
});Styling & Themes
Custom CSS
yuno.startCheckout({
// ... other config
cssCustomization: {
primaryColor: '#007bff',
errorColor: '#dc3545',
fontFamily: 'Inter, sans-serif'
}
});Custom Button Text
yuno.startCheckout({
// ... other config
texts: {
pay: 'Complete Purchase',
processing: 'Processing...',
error: 'Payment Failed'
}
});Render Modes
Modal Display
yuno.startCheckout({
renderMode: 'modal',
elementSelector: '#payment-container'
});Inline Display
yuno.startCheckout({
renderMode: 'element',
elementSelector: '#payment-container'
});Fraud Prevention
Device Fingerprinting
Automatically collected by SDK for configured fraud providers (ClearSale, etc.).
Custom Fraud Data
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
})
});
}
});Installments
Enable Installments
yuno.startCheckout({
// ... other config
card: {
installments: {
enabled: true,
defaultValue: 1
}
}
});Custom Installment Plans
Configured in Yuno dashboard per payment method.
Loader Control
Hide Yuno Loader
yuno.startCheckout({
showLoading: false, // Use your own loader
onLoading: (isLoading) => {
document.getElementById('custom-loader').style.display =
isLoading ? 'block' : 'none';
}
});Custom Loader
yuno.startCheckout({
// ... other config
onLoading: (isLoading) => {
if (isLoading) {
showCustomSpinner();
} else {
hideCustomSpinner();
}
}
});Card Form Types
Extended Form (Separate Fields)
yuno.startCheckout({
card: {
type: 'extends' // Shows separate fields for all card details
}
});Compact Form (Single Field)
yuno.startCheckout({
card: {
type: 'only' // Shows single combined field
}
});Issuer Selection
Enable/Disable Issuer Form
yuno.startCheckout({
issuersFormEnable: true // Show issuer selection for bank transfers
});Payment Status Page
Custom Status Handling
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}`;
}
});Event Callbacks
All Available Callbacks
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);
}
}
}
});Browser Compatibility
SDK supports:
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Polyfills for Older Browsers
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<script src="https://sdk-web.y.uno/v1.5/main.js"></script>Performance Optimization
Lazy Load SDK
// 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();
});Preconnect to Yuno Servers
<link rel="preconnect" href="https://api.y.uno">
<link rel="preconnect" href="https://sdk-web.y.uno">Testing in Sandbox
Test Mode Configuration
// Use test keys (pk_test_*)
const yuno = await Yuno.initialize('pk_test_your_key_here');Simulate Payment Scenarios
// Backend: Create session with test data
{
amount: { currency: 'USD', value: 1000 },
metadata: {
test_scenario: 'success' // 'success', 'decline', '3ds_required'
}
}Error Handling
Common Error Codes
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.');
}
}Webhooks Integration
Verify payment status on backend via 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);
});Environment Configuration
Development
const yuno = await Yuno.initialize('pk_test_dev_key', {
environment: 'sandbox',
debug: true // Enable console logs
});Production
const yuno = await Yuno.initialize('pk_live_prod_key', {
environment: 'production',
debug: false
});Updated about 18 hours ago