Configure Checkout Drop-in once with unified settings for all payment methods, callbacks, and transaction data.
Checkout Drop-in uses a single, unified configuration at initialisation. Instead of configuring individual payment components, you configure Drop-in once and it automatically handles all payment methods.
All configuration happens at initialisation via CheckoutDropIn.initialize():
import CheckoutDropIn from '@pxpio/web-components-sdk/src/checkoutDropIn/CheckoutDropIn';
import IntentType from '@pxpio/web-components-sdk/src/basePxpCheckout/types/IntentType';
const checkoutDropIn = CheckoutDropIn.initialize({
// REQUIRED
environment: 'test',
session: sessionData,
ownerId: 'YourMerchantId',
// ownerType is set to 'MerchantGroup' automatically by Checkout Drop-in
transactionData: {
currency: 'USD',
amount: 99.99,
entryType: 'Ecom',
intent: {
card: IntentType.Authorisation,
paypal: IntentType.Authorisation
},
merchantTransactionId: crypto.randomUUID(),
merchantTransactionDate: () => new Date().toISOString()
},
// REQUIRED: Callbacks
onSuccess: (result) => { /* ... */ },
onError: (error) => { /* ... */ },
// OPTIONAL: Callbacks
onGetShopper: () => Promise.resolve({ id: 'shopper-123' }),
onBeforeSubmit: async (before) => { /* return true to proceed */ },
onSubmit: (submit) => { /* ... */ },
analyticsEvent: (event) => { /* ... */ }
});
// Mount to page
checkoutDropIn.create('checkout-drop-in-container');Specifies which Unity environment to connect to:
{
environment: 'test' // or 'live'
}| Value | Description |
|---|---|
'test' | Sandbox environment. Use this for development, testing, and staging. |
'live' | Live environment. Use this for production deployments. |
Session data is retrieved from your backend and contains payment configuration:
// Backend endpoint
const sessionData = await fetch('/api/create-session')
.then(response => response.json());
// Pass to Drop-in
{
session: sessionData
}Session data includes:
sessionId: The unique session identifierhmacKey: HMAC authentication keyencryptionKey: Encryption keyallowedFundingTypes: Which payment methods are enabled- Session timeout and merchant identification
For session creation details, see our implementation guide.
Identifies who owns this transaction:
{
ownerId: 'YourMerchantId',
// ownerType is optional; Checkout Drop-in sets it to 'MerchantGroup'
}Defines the payment amount, currency, and intent:
import IntentType from '@pxpio/web-components-sdk/src/basePxpCheckout/types/IntentType';
{
transactionData: {
currency: 'USD', // ISO 4217 currency code
amount: 99.99, // Transaction amount
entryType: 'Ecom', // Entry type (usually 'Ecom' for web)
intent: {
card: IntentType.Authorisation, // Card payment intent
paypal: IntentType.Authorisation // PayPal payment intent
},
merchantTransactionId: crypto.randomUUID(), // Unique per transaction
merchantTransactionDate: () => new Date().toISOString() // Current timestamp
}
}Your unique identifier for the transaction:
merchantTransactionId: crypto.randomUUID()
// Or use your own format
merchantTransactionId: `order-${orderId}`Drop-in provides unified callbacks that work for all payment methods:
import { BaseSubmitResult } from '@pxpio/web-components-sdk/src/checkoutDropIn/types/BaseSubmitResult';
import BaseSdkException from '@pxpio/web-components-sdk/src/types/sdkExceptions/BaseSdkException';
import PaymentMethod from '@pxpio/web-components-sdk/src/components/checkoutDropInComponents/types/PaymentMethod';
{
// REQUIRED: Get shopper information
onGetShopper: () => {
return Promise.resolve({ id: 'shopper-123' });
},
// REQUIRED: Called when payment succeeds
onSuccess: async (result: BaseSubmitResult) => {
console.log('Payment successful:', result.systemTransactionId);
// CRITICAL: Always verify on backend before fulfilling order
await verifyPaymentOnBackend(result);
},
// REQUIRED: Called when payment fails
onError: (error: BaseSdkException) => {
console.error('Payment failed:', error.code, error.message);
},
// OPTIONAL: Called before payment submission (can cancel)
onBeforeSubmit: async (paymentMethod: PaymentMethod) => {
console.log('Payment method:', paymentMethod);
// Return false to cancel payment
return true;
},
// OPTIONAL: Called when payment starts processing
onSubmit: (paymentMethod: PaymentMethod) => {
console.log('Processing payment...');
}
}For detailed callback documentation, see Implementation.
Track payment flow events:
{
analyticsEvent: (event) => {
console.log('Analytics:', event.eventName, event);
// Send to your analytics platform
sendToGA4(event);
}
}For detailed analytics documentation, see Analytics.
Many behaviours are configured on the backend (in the Unity Portal), rather than in frontend code:
Controlled via session data:
// Backend session creation
{
"allowedFundingTypes": {
"cards": ["visa", "mastercard"],
"cardSchemes": ["Visa", "Mastercard"],
"wallets": {
"paypal": {
"allowedFundingOptions": ["PAYPAL"],
"merchantId": "paypal-merchant-123"
},
"googlePay": {
"merchantId": "your-googlepay-merchant-id",
"gatewayMerchantId": "gateway-merchant-id",
"merchantName": "Your merchant name"
},
"applePay": {
"merchantId": "your-applepay-merchant-id"
}
}
}
}Drop-in automatically shows only enabled payment methods.
Drop-in fetches and applies your branding configuration from the Unity Portal.
Drop-in respects the amount thresholds, risk assessment rules, and exemptions configured in the Unity Portal. For more information, see the 3DS section.
Configured in transactionData:
{
transactionData: {
// ... other transaction fields
recurring: {
frequencyInDays: 30,
frequencyExpiration: '2025-12-31'
}
}
}import CheckoutDropIn from '@pxpio/web-components-sdk/src/checkoutDropIn/CheckoutDropIn';
import IntentType from '@pxpio/web-components-sdk/src/basePxpCheckout/types/IntentType';
// Get session from backend
const sessionData = await fetch('/api/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(response => response.json());
// Initialise with minimal config
const checkoutDropIn = CheckoutDropIn.initialize({
environment: 'test',
session: sessionData,
ownerId: 'YourMerchantId',
ownerType: 'MerchantGroup',
transactionData: {
currency: 'USD',
amount: 99.99,
entryType: 'Ecom',
intent: {
card: IntentType.Authorisation,
paypal: IntentType.Authorisation
},
merchantTransactionId: crypto.randomUUID(),
merchantTransactionDate: () => new Date().toISOString()
},
onGetShopper: () => Promise.resolve({ id: 'shopper-123' }),
onSuccess: async (result) => {
await verifyPaymentOnBackend(result);
},
onError: (error) => {
alert(`Payment failed: ${error.message}`);
}
});
// Mount
checkoutDropIn.create('checkout-drop-in-container');import CheckoutDropIn from '@pxpio/web-components-sdk/src/checkoutDropIn/CheckoutDropIn';
import IntentType from '@pxpio/web-components-sdk/src/basePxpCheckout/types/IntentType';
import PaymentMethod from '@pxpio/web-components-sdk/src/components/checkoutDropInComponents/types/PaymentMethod';
import { BaseSubmitResult } from '@pxpio/web-components-sdk/src/checkoutDropIn/types/BaseSubmitResult';
import BaseSdkException from '@pxpio/web-components-sdk/src/types/sdkExceptions/BaseSdkException';
// Get session from backend
const sessionData = await fetch('/api/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(response => response.json());
// Initialise with all callbacks
const checkoutDropIn = CheckoutDropIn.initialize({
// REQUIRED
environment: 'live',
session: sessionData,
ownerId: 'YourMerchantId',
ownerType: 'MerchantGroup',
transactionData: {
currency: 'USD',
amount: 149.99,
entryType: 'Ecom',
intent: {
card: IntentType.Authorisation,
paypal: IntentType.Purchase
},
merchantTransactionId: `order-${orderId}`,
merchantTransactionDate: () => new Date().toISOString()
},
// CALLBACKS
onGetShopper: () => Promise.resolve({ id: 'shopper-123' }),
onBeforeSubmit: async (paymentMethod: PaymentMethod) => {
console.log('Payment method selected:', paymentMethod);
// Custom validation
const isValid = await validateOrder(orderId);
if (!isValid) {
alert('Order validation failed. Please review your order.');
return false; // Cancel payment
}
// Check inventory
const inStock = await checkInventory(orderId);
if (!inStock) {
alert('Item is out of stock. Please update your cart.');
return false; // Cancel payment
}
return true; // Proceed with payment
},
onSubmit: (paymentMethod: PaymentMethod) => {
console.log('Payment processing started for:', paymentMethod);
// Show loading spinner
document.getElementById('loading-spinner').style.display = 'block';
},
onSuccess: async (result: BaseSubmitResult) => {
console.log('Payment successful:', result.systemTransactionId);
document.getElementById('loading-spinner').style.display = 'none';
// CRITICAL: Verify on backend before fulfilling
try {
const verified = await fetch('/api/verify-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
systemTransactionId: result.systemTransactionId,
merchantTransactionId: result.merchantTransactionId,
orderId: orderId
})
}).then(r => r.json());
if (verified.success) {
window.location.href = `/order-confirmation?orderId=${verified.orderId}`;
} else {
alert('Payment verification failed. Please contact support.');
}
} catch (error) {
console.error('Verification failed:', error);
alert('Unable to verify payment. Please contact support.');
}
},
onError: (error: BaseSdkException) => {
console.error('Payment error:', error);
document.getElementById('loading-spinner').style.display = 'none';
// Show user-friendly error message based on error code and message
let userMessage = `Payment failed: ${error.message}`;
if (error.code === 'SDK1116' && error.message.toLowerCase().includes('declined')) {
userMessage = 'Card declined. Please try a different card.';
} else if (error.code === 'SDK1116' && error.message.toLowerCase().includes('insufficient funds')) {
userMessage = 'Insufficient funds.';
} else if (error.code === 'SDK1114') {
userMessage = 'Card verification failed.';
} else if (error.code === 'SDK0500') {
userMessage = 'Connection error. Check your internet.';
} else if (error.message.toLowerCase().includes('session') ||
error.message.toLowerCase().includes('expired')) {
userMessage = 'Session expired. Please refresh.';
}
document.getElementById('error-message').textContent = userMessage;
document.getElementById('error-message').style.display = 'block';
},
analyticsEvent: (event) => {
// Send to Google Analytics
if (typeof gtag !== 'undefined') {
gtag('event', event.eventName, {
event_category: 'checkout',
...event
});
}
// Send to backend
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(event)
}).catch(console.error);
}
});
// Mount
checkoutDropIn.create('checkout-drop-in-container');