Display the payment form next to your product information in a side-by-side layout. Ideal for e-commerce product pages where you want to show product details alongside the checkout.
Live Demo See the Sidebar layout in action at embedcheckout.payonify.com .
Complete Integration
HTML Structure
<!DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Checkout - Sidebar </ title >
< link rel = "stylesheet" href = "styles.css" >
</ head >
< body >
< div class = "checkout-layout" >
<!-- Product Information -->
< div class = "product-section" >
< h1 > Premium Subscription </ h1 >
< p class = "price" > $15.00/month </ p >
< p class = "description" > Get unlimited access to all features. </ p >
</ div >
<!-- Payment Sidebar -->
< div class = "payment-section" >
< h2 > Complete your purchase </ h2 >
< 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
/* Side-by-side layout */
. checkout-layout {
display : grid ;
grid-template-columns : 1 fr 1 fr ;
gap : 2 rem ;
max-width : 1200 px ;
margin : 0 auto ;
padding : 2 rem ;
}
/* Stack on mobile */
@media ( max-width : 768 px ) {
. checkout-layout {
grid-template-columns : 1 fr ;
}
}
/* Product section */
. product-section {
background : white ;
border-radius : 16 px ;
padding : 2 rem ;
box-shadow : 0 4 px 6 px rgba ( 0 , 0 , 0 , 0.1 );
}
/* Payment section - sticky on scroll */
. payment-section {
position : sticky ;
top : 2 rem ;
background : white ;
border-radius : 16 px ;
padding : 2 rem ;
box-shadow : 0 4 px 6 px rgba ( 0 , 0 , 0 , 0.1 );
}
. payment-section h2 {
margin-bottom : 1.5 rem ;
text-align : center ;
}
/* Checkout container */
# checkout-container {
min-height : 400 px ;
}
JavaScript
Production Note Remove all console.log and console.error statements before deploying to production.
// Configuration
const PUBLISHABLE_KEY = 'pk_test_abc123...' ; // Your publishable key
const container = document . getElementById ( 'checkout-container' ) ;
let payonify = null ;
// Initialize Payonify SDK
function initPayonify () {
payonify = new Payonify ( {
publishableKey : PUBLISHABLE_KEY
} ) ;
payonify . onSuccess = ( data ) => {
console . log ( 'Payment successful!' , data) ; // Remove in production
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 on page load
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>' ;
}
}
// Initialize on page load
document . addEventListener ( 'DOMContentLoaded' , () => {
initPayonify () ;
loadCheckout () ;
} ) ;
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
Last modified on March 7, 2026