Embedded Checkout
Slide-In
A slide-in panel that appears from the right side of the screen. Great for mobile-friendly experiences and when you want to keep the main content visible.
Live Demo
See the Side Sheet in action at embedcheckout.payonify.com.
Complete Integration
HTML Structure
Code<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Checkout - Side Sheet</title> <link rel="stylesheet" href="styles.css"> </head> <body> <!-- Your main content --> <div class="main-content"> <h1>Your Store</h1> <button id="checkout-button" class="checkout-btn">Checkout</button> </div> <!-- Sheet overlay (backdrop) --> <div id="sheet-overlay" class="sheet-overlay hidden"></div> <!-- Sheet panel --> <div id="checkout-sheet" class="sheet-panel"> <div class="sheet-header"> <h2>Checkout</h2> <button id="close-sheet" class="close-btn">×</button> </div> <div class="sheet-content"> <div id="checkout-container"></div> </div> </div> <script src="https://js.payonify.com/payonify.umd.js"></script> <script src="checkout.js"></script> </body> </html>
CSS Styles
Code/* Sheet overlay (backdrop) */ .sheet-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); z-index: 200; opacity: 0; transition: opacity 0.3s ease; pointer-events: none; } .sheet-overlay.visible { opacity: 1; pointer-events: auto; } .sheet-overlay.hidden { display: none; } /* Sheet panel - slides in from right */ .sheet-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 420px; max-width: 100%; background: white; box-shadow: -10px 0 40px rgba(0, 0, 0, 0.15); z-index: 300; transform: translateX(100%); transition: transform 0.3s ease; display: flex; flex-direction: column; } .sheet-panel.open { transform: translateX(0); } /* Full width on mobile */ @media (max-width: 480px) { .sheet-panel { width: 100%; } } /* Sheet header */ .sheet-header { display: flex; justify-content: space-between; align-items: center; padding: 1.5rem; border-bottom: 1px solid #e5e7eb; } .close-btn { background: none; border: none; font-size: 1.5rem; color: #6b7280; cursor: pointer; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: background 0.2s; } .close-btn:hover { background: #f3f4f6; } /* Sheet content */ .sheet-content { flex: 1; overflow-y: auto; padding: 1.5rem; } #checkout-container { min-height: 400px; }
JavaScript
Production Note
Remove all console.log and console.error statements before deploying to production.
Code// Configuration const PUBLISHABLE_KEY = 'pk_test_abc123...'; // Your publishable key // DOM elements const checkoutButton = document.getElementById('checkout-button'); const sheet = document.getElementById('checkout-sheet'); const overlay = document.getElementById('sheet-overlay'); const closeButton = document.getElementById('close-sheet'); const container = document.getElementById('checkout-container'); let payonify = null; let isSheetOpen = false; // Initialize Payonify SDK function initPayonify() { payonify = new Payonify({ publishableKey: PUBLISHABLE_KEY }); payonify.onSuccess = (data) => { console.log('Payment successful!', data); // Remove in production closeSheet(); window.location.href = '/success?session_id=' + data.session_id; }; payonify.onError = (error) => { console.error('Payment error:', error); // Remove in production alert('Payment failed: ' + error.message); }; payonify.onClose = () => { console.log('Payment form closed'); // Remove in production }; } // Create checkout session (call your backend) async function createCheckoutSession() { const response = await fetch('/api/create-checkout-session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ line_items: [ { unit_amount: 1500, name: 'Premium Subscription', quantity: 1 } ], currency: 'usd' }) }); if (!response.ok) { throw new Error('Failed to create checkout session'); } return response.json(); } // Load and mount checkout async function loadCheckout() { container.innerHTML = '<p>Loading payment form...</p>'; try { const session = await createCheckoutSession(); container.innerHTML = ''; payonify.mount({ container: container, clientSecret: session.client_secret }); } catch (error) { console.error('Error:', error); // Remove in production container.innerHTML = '<p style="color: red;">Failed to load. Please try again.</p>'; } } // Open sheet function openSheet() { if (isSheetOpen) return; isSheetOpen = true; overlay.classList.remove('hidden'); overlay.offsetHeight; // Trigger reflow for animation overlay.classList.add('visible'); sheet.classList.add('open'); loadCheckout(); } // Close sheet function closeSheet() { if (!isSheetOpen) return; isSheetOpen = false; overlay.classList.remove('visible'); sheet.classList.remove('open'); setTimeout(() => { overlay.classList.add('hidden'); }, 300); if (payonify) { payonify.unmount(); } } // Event listeners checkoutButton.addEventListener('click', openSheet); closeButton.addEventListener('click', closeSheet); overlay.addEventListener('click', closeSheet); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && isSheetOpen) { closeSheet(); } }); // Initialize on page load initPayonify();
Backend API Example
See the Drop-In guide for complete backend examples in Node.js, Python, Ruby, Java, C#, Elixir, Swift, and Kotlin.
Next Steps
- Drop-In Integration - Overlay modal for checkout
- Sidebar Integration - Payment form next to your product
- Webhooks Guide - Handle payment events server-side
Last modified on