<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phoenix Payment Demo</title>
<style>
/* Basic page styling */
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.input-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: #16A34A;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
/* Phoenix Payment Styles */
#payment-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
display: none;
}
.payment-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.payment-modal {
position: relative;
background-color: transparent;
border-radius: 12px;
padding: 0;
box-shadow: none;
overflow: visible;
}
.close-button {
position: absolute;
top: -15px;
right: -15px;
background-color: #333;
color: white;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
font-size: 18px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
padding: 0;
line-height: 1;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.teller-iframe {
width: 350px;
height: 600px;
border: none;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
</style>
</head>
<body>
<h1>Phoenix Payment Demo</h1>
<div class="input-group">
<label for="wallet">Wallet Address:</label>
<input id="wallet" type="text" placeholder="0x...">
</div>
<div class="input-group">
<label for="amount">Amount (USD):</label>
<input id="amount" type="number" placeholder="100">
</div>
<!-- Add this new input group -->
<div class="input-group">
<label for="theme">Theme:</label>
<select id="theme">
<option value="">Default</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
<button id="start-payment">Make Payment</button>
<!-- Payment Container (Hidden by default) -->
<div id="payment-container">
<div class="payment-overlay">
<div class="payment-modal">
<button
id="cancel-payment-button"
class="close-button"
aria-label="Close payment window"
>
×
</button>
<iframe
id="phoenix-payment-iframe"
src="about:blank"
class="teller-iframe"
title="Phoenix Payment"
allow="clipboard-write"
></iframe>
</div>
</div>
</div>
<script>
// Function to get access token from your backend
async function getAccessToken() {
try {
const response = await fetch('/api/token');
const data = await response.json();
return data.access_token;
} catch (error) {
console.error('Error fetching access token:', error);
return null;
}
}
// Function to show payment iframe with parameters
async function showPayment(walletAddress, amount, theme) {
const iframe = document.getElementById('phoenix-payment-iframe');
const container = document.getElementById('payment-container');
// Get the access token from your backend
const accessToken = await getAccessToken();
if (!accessToken) {
alert('Unable to obtain access token. Please try again later.');
return;
}
// Build iframe URL with all parameters
let url = `https://app-partner.phoenix.market/?address=${walletAddress}&amount=${amount}&access_token=${accessToken}`;
if (theme) {
url += `&theme=${theme}`;
}
// Set iframe src
iframe.src = url;
// Display the container that holds the iframe
container.style.display = 'block';
// Set up event listener for messages from the iframe
window.addEventListener('message', handlePaymentMessage);
// Set up cancel button functionality
document.getElementById('cancel-payment-button').onclick = hidePayment;
}
// Function to handle messages received from the iframe
function handlePaymentMessage(event) {
// IMPORTANT: Verify origin for security
if (event.origin !== 'https://app-partner.phoenix.market') return;
// Handle order created message
if (event.data?.type === 'ORDER_CREATED') {
const { order_id, ...data } = event.data.data;
console.log('Order created:', event.data.data);
// Handle the order creation event as needed
// You should store order details in your database, especially the order_id
}
// Handle transaction success message
else if (event.data?.type === 'TRANSACTION_SUCCESS') {
const { amount, token, chain, walletAddress, sendAmount, transactionHash, basescanLink } = event.data.data;
console.log('Transaction successful:', transactionHash);
// You should store transaction details in your database
// and update your UI to show the payment was successful
// Uncomment the following line if you want to close the window after transaction success
// hidePayment();
}
// Handle cancel message
else if (event.data?.type === 'CANCEL') {
console.log('Payment canceled by user');
hidePayment();
}
// Handle open explorer URL message
else if (event.data?.type === 'OPEN_EXPLORER_URL') {
const url = event.data.url;
console.log('Opening explorer URL:', url);
// Open the URL in a new tab
window.open(url, '_blank');
}
// Handle done message
else if (event.data?.type === 'USER_DONE') {
console.log('Payment process completed');
hidePayment();
}
// Handle payment failure or cancellation
else if (event.data?.type === 'PAYMENT_FAILED' || event.data?.type === 'PAYMENT_CANCELLED') {
console.log('Payment failed or cancelled');
// Uncomment the following line if you want to close the window after payment failure/cancellation
// hidePayment();
}
}
// Function to hide the payment iframe
function hidePayment() {
document.getElementById('payment-container').style.display = 'none';
// IMPORTANT: Remove event listener to prevent memory leaks
window.removeEventListener('message', handlePaymentMessage);
}
// Set up the button click handler
document.getElementById('start-payment').addEventListener('click', function() {
// Get values from form inputs
const walletAddress = document.getElementById('wallet').value;
const amount = document.getElementById('amount').value;
const theme = document.getElementById('theme').value; // Get selected theme
// Validate inputs (basic validation)
if (!walletAddress || !amount) {
alert('Please enter both wallet address and amount');
return;
}
// Start payment process with collected values
showPayment(walletAddress, amount, theme);
});
</script>
</body>
</html>