PostMessage API
Two-way communication between your application and the Merso Modal.
Communication Flow
The modal uses the browser's postMessage API for secure communication. Messages flow in both directions:
↗
Parent → Modal
Configuration & control
↙
Modal → Parent
Events & results
Messages to Modal (Parent → Modal)
Messages from Modal (Modal → Parent)
Listening for Messages
Here's a complete example of handling all modal messages:
JavaScript
// Store payment data to use when modal closes
let pendingPaymentData = null;
window.addEventListener('message', (event) => {
// IMPORTANT: Ignore Stripe's internal messages
if (event.origin === 'https://js.stripe.com') {
return;
}
// Optional: Verify the origin matches your modal URL
const MODAL_ORIGIN = 'https://modal.dev.merso.io';
// if (event.origin !== MODAL_ORIGIN) return;
const { type, ...data } = event.data || {};
switch (type) {
case 'payment-success':
handlePaymentSuccess(data);
break;
case 'crypto-payment-success':
handleCryptoSuccess(data);
break;
case 'payment-cancelled':
handlePaymentCancelled();
break;
case 'crypto-payment-error':
handleCryptoError(data.error);
break;
case 'modal-choice':
trackAnalytics('modal_choice', data);
break;
case 'modal-close':
handleModalClose();
break;
default:
// Unknown message type - ignore
break;
}
});
function handlePaymentSuccess({ paymentIntentId, totalAmount, firstPaymentAmount, weeklyPaymentAmount }) {
console.log('Payment successful!', paymentIntentId);
// Store payment data - don't close modal yet (user sees success screen)
pendingPaymentData = { paymentIntentId, totalAmount, firstPaymentAmount, weeklyPaymentAmount };
}
function handleCryptoSuccess({ transactionHash, tokenId }) {
console.log('NFT minted!', transactionHash);
// Store payment data - don't close modal yet (user sees success screen)
pendingPaymentData = { transactionHash, tokenId };
}
function handleModalClose() {
// User clicked Close after seeing success screen
console.log('Modal closed by user');
closeModal();
if (pendingPaymentData) {
showSuccessNotification('Purchase completed!');
refreshUserInventory();
pendingPaymentData = null;
}
}
function handlePaymentCancelled() {
console.log('Payment cancelled by user');
closeModal();
}
function handleCryptoError(error) {
console.error('Crypto payment failed:', error);
showErrorNotification(error);
}
⚠️ Important: Stripe Messages
Stripe Elements uses postMessage internally. You'll see messages from https://js.stripe.com - these should be ignored as shown above.