Fonctionnalités avancées SDK Web
Options de configuration avancées et intégrations personnalisées pour le SDK Web Yuno.
Options de montage alternatives
Le flux de base utilise mountCheckout() pour l'affichage automatique du mode de paiement. Pour plus de contrôle, utilisez ces alternatives :
Sélection d'un mode de paiement personnalisé (mountCheckoutLite())
mountCheckoutLite())Contrôlez le mode de paiement à afficher :
// 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 et Apple Pay avec Lite :
await yuno.mountExternalButtons([
{
paymentMethodType: 'GOOGLE_PAY',
elementSelector: '#google-pay-button'
},
{
paymentMethodType: 'APPLE_PAY',
elementSelector: '#apple-pay-button'
}
]);Flux simplifié (mountSeamlessCheckout())
mountSeamlessCheckout())Semblable à mountCheckoutLite() mais avec la création automatique des paiements :
// 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();
});Inscription (enregistrer les cartes)
Enregistrer pendant le paiement
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();
}
});Inscription séparée
// 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 voûtés
// Use saved card
yuno.mountCheckout({
vaultedToken: 'vtok_saved_card_123'
});
// Still need startPayment()
document.querySelector('#pay-button').addEventListener('click', () => {
yuno.startPayment();
});Interface utilisateur personnalisée (intégration sans interface graphique)
Créez des formulaires de paiement entièrement personnalisés avec un contrôle total de l'interface utilisateur lorsque vous avez besoin d'un contrôle complet sur chaque élément de l'interface, que vous souhaitez créer des expériences de paiement hautement personnalisées ou que vous disposez de ressources de développement pour une interface utilisateur personnalisée. Yuno ne gère que la tokenisation.
Mise en œuvre
1. Initialize le client Initialize
const yuno = await Yuno.initialize('your-public-key');
const apiClientPayment = yuno.apiClientPayment({
country_code: "US",
checkout_session: "checkout_session_id"
});2. Créez votre formulaire personnalisé
<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. Générer 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. Gestion des 3DS et des redirections
const continueResult = await yuno.continuePayment({ showPaymentStatus: false });
if (continueResult?.action === 'REDIRECT_URL') {
window.location.href = continueResult.redirect.init_url;
}Avec Token voûté
const result = await apiClientPayment.generateToken({
checkout_session: "checkout_session_id",
payment_method: {
type: "CARD",
vaulted_token: "saved_token_id",
card: {
detail: {
security_code: "123"
}
}
}
});Champs sécurisés (formulaires de carte personnalisés)
Créez des formulaires de carte personnalisés tout en respectant la conformité PCI grâce à des champs iframe sécurisés. Idéal lorsque vous souhaitez personnaliser la conception de vos formulaires de carte, que vous avez besoin de dispositions de champs spécifiques ou que vous exigez une sécurité basée sur iframe pour les cartes.
Mise en œuvre
1. Installation et Initialize
const yuno = await Yuno.initialize('votre-clé-publique');2. Créer des champs sécurisés
<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. Style personnalisé
fields: {
cardNumber: {
elementSelector: '#card-number-field',
style: {
base: {
color: '#333',
fontSize: '16px',
fontFamily: 'Arial, sans-serif'
},
invalid: {
color: '#ff0000'
}
}
}
}Devises multiples
Gérez les paiements multidevises grâce à la conversion automatique.
// 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',
// ...
});Style et thèmes
CSS personnalisé
yuno.startCheckout({
// ... other config
cssCustomization: {
primaryColor: '#007bff',
errorColor: '#dc3545',
fontFamily: 'Inter, sans-serif'
}
});Texte du bouton personnalisé
yuno.startCheckout({
// ... other config
texts: {
pay: 'Complete Purchase',
processing: 'Processing...',
error: 'Payment Failed'
}
});Modes de rendu
Affichage modal
yuno.startCheckout({
renderMode: 'modal',
elementSelector: '#payment-container'
});Affichage en ligne
yuno.startCheckout({
renderMode: 'element',
elementSelector: '#payment-container'
});Prévention de la Fraude
Empreinte digitale de l'appareil
Collectées automatiquement par le SDK pour les fournisseurs de services anti-fraude configurés (ClearSale, etc.).
Données personnalisées sur la 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
})
});
}
});Paiements échelonnés
Activer les paiements échelonnés
yuno.startCheckout({
// ... other config
card: {
installments: {
enabled: true,
defaultValue: 1
}
}
});Plans de paiement personnalisés
Configuré dans le tableau de bord Yuno par mode de paiement.
Commande du chargeur
Masquer Yuno Loader
yuno.startCheckout({
showLoading: false, // Use your own loader
onLoading: (isLoading) => {
document.getElementById('custom-loader').style.display =
isLoading ? 'block' : 'none';
}
});Chargeur personnalisé
yuno.startCheckout({
// ... other config
onLoading: (isLoading) => {
if (isLoading) {
showCustomSpinner();
} else {
hideCustomSpinner();
}
}
});Types de formulaires de carte
Formulaire détaillé (champs séparés)
yuno.startCheckout({
card: {
type: 'extends' // Shows separate fields for all card details
}
});Formulaire compact (champ unique)
yuno.startCheckout({
card: {
type: 'only' // Shows single combined field
}
});Sélection de l'émetteur
Activer/désactiver le formulaire d'émetteur
yuno.startCheckout({
issuersFormEnable: true // Show issuer selection for bank transfers
});Page d'état des paiements
Gestion personnalisée des statuts
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}`;
}
});Rappels d'événements
Tous les rappels 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);
}
}
}
});Compatibilité avec les navigateurs
Le SDK prend en charge :
- Chrome 90+
- Firefox 88+
- Safari 14+
- Bord 90+
Polyfills pour les navigateurs plus anciens
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<script src="https://sdk-web.y.uno/v1.5/main.js"></script>Optimisation des performances
SDK Lazy Load
// 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éconnectez-vous aux serveurs Yuno
<link rel="preconnect" href="https://api.y.uno">
<link rel="preconnect" href="https://sdk-web.y.uno">Test dans le bac à sable
Configuration du mode test
// Use test keys (pk_test_*)
const yuno = await Yuno.initialize('pk_test_your_key_here');Simuler des scénarios de paiement
// Backend: Create session with test data
{
amount: { currency: 'USD', value: 1000 },
metadata: {
test_scenario: 'success' // 'success', 'decline', '3ds_required'
}
}Gestion des erreurs
Codes d'erreur courants
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.');
}
}Intégration des webhooks
Vérifier le statut du paiement sur le backend via des 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);
});Configuration de l'environnement
Développement
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
});Mise à jour il y a 1 jour