|
|
<!DOCTYPE html> |
|
|
<html lang="pt-BR"> |
|
|
<head> |
|
|
<meta charset="UTF-8" /> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
|
|
<title>SecurePIX | Gerador de Pagamentos</title> |
|
|
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"/> |
|
|
<script src="https://unpkg.com/imask"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); |
|
|
|
|
|
:root { |
|
|
--primary-dark: #0a0a0a; |
|
|
--primary-medium: #1a1a1a; |
|
|
--primary-light: #2a2a2a; |
|
|
--accent-light: #e0e0e0; |
|
|
--accent-medium: #a0a0a0; |
|
|
--accent-dark: #5a5a5a; |
|
|
--white: #ffffff; |
|
|
--black: #000000; |
|
|
} |
|
|
|
|
|
body { |
|
|
font-family: 'Inter', sans-serif; |
|
|
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0a0a0a 100%); |
|
|
min-height: 100vh; |
|
|
overflow-x: hidden; |
|
|
position: relative; |
|
|
color: var(--white); |
|
|
} |
|
|
|
|
|
body::before { |
|
|
content: ""; |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background-image: |
|
|
radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.03) 0%, transparent 40%), |
|
|
radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.02) 0%, transparent 40%), |
|
|
radial-gradient(circle at 40% 80%, rgba(255, 255, 255, 0.01) 0%, transparent 40%); |
|
|
z-index: -1; |
|
|
} |
|
|
|
|
|
.card-bg { |
|
|
background: rgba(26, 26, 26, 0.8); |
|
|
backdrop-filter: blur(15px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: |
|
|
0 10px 30px rgba(0, 0, 0, 0.3), |
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.05); |
|
|
} |
|
|
|
|
|
.neon-glow { |
|
|
box-shadow: |
|
|
0 0 15px rgba(255, 255, 255, 0.1), |
|
|
0 0 30px rgba(255, 255, 255, 0.05), |
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.gradient-text { |
|
|
background: linear-gradient(90deg, #e0e0e0 0%, #ffffff 50%, #e0e0e0 100%); |
|
|
-webkit-background-clip: text; |
|
|
-webkit-text-fill-color: transparent; |
|
|
background-size: 200% auto; |
|
|
animation: shimmer 3s linear infinite; |
|
|
} |
|
|
|
|
|
@keyframes shimmer { |
|
|
0% { background-position: 0% center; } |
|
|
100% { background-position: 200% center; } |
|
|
} |
|
|
|
|
|
.float-animation { |
|
|
animation: float 6s ease-in-out infinite; |
|
|
} |
|
|
|
|
|
@keyframes float { |
|
|
0% { transform: translateY(0px); } |
|
|
50% { transform: translateY(-10px); } |
|
|
100% { transform: translateY(0px); } |
|
|
} |
|
|
|
|
|
.pulse-glow { |
|
|
animation: pulse-glow 2s infinite; |
|
|
} |
|
|
|
|
|
@keyframes pulse-glow { |
|
|
0% { box-shadow: 0 0 10px rgba(255, 255, 255, 0.1); } |
|
|
50% { box-shadow: 0 0 20px rgba(255, 255, 255, 0.2); } |
|
|
100% { box-shadow: 0 0 10px rgba(255, 255, 255, 0.1); } |
|
|
} |
|
|
|
|
|
.typewriter { |
|
|
overflow: hidden; |
|
|
border-right: 2px solid rgba(255, 255, 255, 0.7); |
|
|
white-space: nowrap; |
|
|
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; |
|
|
} |
|
|
|
|
|
@keyframes typing { |
|
|
from { width: 0 } |
|
|
to { width: 100% } |
|
|
} |
|
|
|
|
|
@keyframes blink-caret { |
|
|
from, to { border-color: transparent } |
|
|
50% { border-color: rgba(255, 255, 255, 0.7) } |
|
|
} |
|
|
|
|
|
.particle { |
|
|
position: absolute; |
|
|
width: 4px; |
|
|
height: 4px; |
|
|
background: rgba(255, 255, 255, 0.5); |
|
|
border-radius: 50%; |
|
|
opacity: 0; |
|
|
} |
|
|
|
|
|
.particle:nth-child(1) { top: 20%; left: 10%; animation: particle-float 8s infinite; } |
|
|
.particle:nth-child(2) { top: 60%; left: 85%; animation: particle-float 10s infinite 1s; } |
|
|
.particle:nth-child(3) { top: 80%; left: 20%; animation: particle-float 12s infinite 2s; } |
|
|
.particle:nth-child(4) { top: 30%; left: 70%; animation: particle-float 9s infinite 3s; } |
|
|
.particle:nth-child(5) { top: 70%; left: 40%; animation: particle-float 11s infinite 4s; } |
|
|
|
|
|
@keyframes particle-float { |
|
|
0% { transform: translateY(0) translateX(0); opacity: 0; } |
|
|
50% { opacity: 1; } |
|
|
100% { transform: translateY(-100px) translateX(20px); opacity: 0; } |
|
|
} |
|
|
|
|
|
.btn-hover-effect { |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.btn-hover-effect::before { |
|
|
content: ""; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: -100%; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); |
|
|
transition: all 0.6s; |
|
|
} |
|
|
|
|
|
.btn-hover-effect:hover::before { |
|
|
left: 100%; |
|
|
} |
|
|
|
|
|
.input-focus-effect:focus { |
|
|
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3); |
|
|
} |
|
|
|
|
|
|
|
|
.amount-input-container { |
|
|
position: relative; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 16px; |
|
|
padding: 1.5rem; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.amount-input-container:focus-within { |
|
|
background: rgba(255, 255, 255, 0.08); |
|
|
border-color: rgba(255, 255, 255, 0.3); |
|
|
box-shadow: 0 0 20px rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.amount-input { |
|
|
font-size: 2.5rem; |
|
|
font-weight: 700; |
|
|
background: transparent; |
|
|
border: none; |
|
|
color: white; |
|
|
width: 100%; |
|
|
text-align: center; |
|
|
outline: none; |
|
|
} |
|
|
|
|
|
.amount-input::placeholder { |
|
|
color: rgba(255, 255, 255, 0.3); |
|
|
} |
|
|
|
|
|
.currency-symbol { |
|
|
position: absolute; |
|
|
left: 2rem; |
|
|
top: 50%; |
|
|
transform: translateY(-50%); |
|
|
font-size: 2rem; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
} |
|
|
|
|
|
.input-decoration { |
|
|
position: absolute; |
|
|
bottom: 0; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
width: 80%; |
|
|
height: 2px; |
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent); |
|
|
} |
|
|
|
|
|
|
|
|
.modal-overlay { |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0, 0, 0, 0.8); |
|
|
backdrop-filter: blur(5px); |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
z-index: 1000; |
|
|
opacity: 0; |
|
|
visibility: hidden; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.modal-overlay.active { |
|
|
opacity: 1; |
|
|
visibility: visible; |
|
|
} |
|
|
|
|
|
.modal-content { |
|
|
width: 90%; |
|
|
max-width: 500px; |
|
|
background: var(--primary-medium); |
|
|
border-radius: 20px; |
|
|
padding: 2rem; |
|
|
transform: translateY(20px); |
|
|
opacity: 0; |
|
|
transition: all 0.3s; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); |
|
|
} |
|
|
|
|
|
.modal-overlay.active .modal-content { |
|
|
transform: translateY(0); |
|
|
opacity: 1; |
|
|
} |
|
|
|
|
|
.payment-status { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin-top: 1rem; |
|
|
padding: 0.75rem; |
|
|
border-radius: 8px; |
|
|
background: rgba(0, 0, 0, 0.2); |
|
|
} |
|
|
|
|
|
.payment-status.paid { |
|
|
background: rgba(16, 185, 129, 0.1); |
|
|
border: 1px solid rgba(16, 185, 129, 0.3); |
|
|
} |
|
|
|
|
|
.payment-status.pending { |
|
|
background: rgba(245, 158, 11, 0.1); |
|
|
border: 1px solid rgba(245, 158, 11, 0.3); |
|
|
} |
|
|
|
|
|
.payment-status.canceled { |
|
|
background: rgba(239, 68, 68, 0.1); |
|
|
border: 1px solid rgba(239, 68, 68, 0.3); |
|
|
} |
|
|
|
|
|
.qr-code-placeholder { |
|
|
width: 180px; |
|
|
height: 180px; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 12px; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin: 1rem auto; |
|
|
border: 1px dashed rgba(255, 255, 255, 0.2); |
|
|
} |
|
|
|
|
|
.qr-code-placeholder i { |
|
|
font-size: 3rem; |
|
|
margin-bottom: 0.5rem; |
|
|
color: rgba(255, 255, 255, 0.3); |
|
|
} |
|
|
|
|
|
.close-modal { |
|
|
position: absolute; |
|
|
top: 1rem; |
|
|
right: 1rem; |
|
|
background: none; |
|
|
border: none; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
font-size: 1.5rem; |
|
|
cursor: pointer; |
|
|
transition: color 0.2s; |
|
|
} |
|
|
|
|
|
.close-modal:hover { |
|
|
color: var(--white); |
|
|
} |
|
|
|
|
|
.logo-icon { |
|
|
width: 60px; |
|
|
height: 60px; |
|
|
border-radius: 16px; |
|
|
background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); |
|
|
} |
|
|
|
|
|
.logo-icon i { |
|
|
font-size: 1.8rem; |
|
|
color: rgba(255, 255, 255, 0.9); |
|
|
} |
|
|
|
|
|
.info-card { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 12px; |
|
|
padding: 1.5rem; |
|
|
border-left: 4px solid rgba(255, 255, 255, 0.2); |
|
|
margin-top: 1.5rem; |
|
|
} |
|
|
|
|
|
.feature-grid { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
|
|
gap: 1rem; |
|
|
margin-top: 2rem; |
|
|
} |
|
|
|
|
|
.feature-item { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
padding: 1rem; |
|
|
background: rgba(255, 255, 255, 0.03); |
|
|
border-radius: 10px; |
|
|
border: 1px solid rgba(255, 255, 255, 0.05); |
|
|
} |
|
|
|
|
|
.feature-icon { |
|
|
width: 40px; |
|
|
height: 40px; |
|
|
border-radius: 10px; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin-right: 1rem; |
|
|
} |
|
|
|
|
|
.step-indicator { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
position: relative; |
|
|
margin: 2rem 0; |
|
|
} |
|
|
|
|
|
.step-indicator::before { |
|
|
content: ""; |
|
|
position: absolute; |
|
|
top: 15px; |
|
|
left: 0; |
|
|
right: 0; |
|
|
height: 2px; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
z-index: 1; |
|
|
} |
|
|
|
|
|
.step { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
position: relative; |
|
|
z-index: 2; |
|
|
} |
|
|
|
|
|
.step-circle { |
|
|
width: 32px; |
|
|
height: 32px; |
|
|
border-radius: 50%; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin-bottom: 0.5rem; |
|
|
border: 2px solid rgba(255, 255, 255, 0.2); |
|
|
} |
|
|
|
|
|
.step.active .step-circle { |
|
|
background: rgba(255, 255, 255, 0.2); |
|
|
border-color: rgba(255, 255, 255, 0.5); |
|
|
} |
|
|
|
|
|
.step-text { |
|
|
font-size: 0.75rem; |
|
|
color: rgba(255, 255, 255, 0.7); |
|
|
text-align: center; |
|
|
} |
|
|
|
|
|
.security-badge { |
|
|
display: inline-flex; |
|
|
align-items: center; |
|
|
background: rgba(16, 185, 129, 0.1); |
|
|
color: #10b981; |
|
|
padding: 0.25rem 0.75rem; |
|
|
border-radius: 20px; |
|
|
font-size: 0.75rem; |
|
|
margin-left: 0.5rem; |
|
|
} |
|
|
|
|
|
.fraude-info { |
|
|
background: rgba(245, 158, 11, 0.1); |
|
|
border: 1px solid rgba(245, 158, 11, 0.3); |
|
|
border-radius: 12px; |
|
|
padding: 1.5rem; |
|
|
margin-top: 2rem; |
|
|
} |
|
|
|
|
|
.fraude-info h3 { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
color: #f59e0b; |
|
|
margin-bottom: 0.5rem; |
|
|
} |
|
|
|
|
|
.text-input { |
|
|
color: #000000 !important; |
|
|
} |
|
|
|
|
|
.text-input::placeholder { |
|
|
color: #666666 !important; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="flex flex-col justify-center items-center p-4 min-h-screen"> |
|
|
|
|
|
<div class="particle"></div> |
|
|
<div class="particle"></div> |
|
|
<div class="particle"></div> |
|
|
<div class="particle"></div> |
|
|
<div class="particle"></div> |
|
|
|
|
|
<div class="w-full max-w-2xl relative"> |
|
|
|
|
|
<div class="text-center mb-8 relative"> |
|
|
<div class="flex justify-center items-center mb-4"> |
|
|
<div class="logo-icon mr-4 float-animation"> |
|
|
<i class="fas fa-coins"></i> |
|
|
</div> |
|
|
<div> |
|
|
<h1 class="text-4xl font-bold gradient-text">SecurePIX</h1> |
|
|
</div> |
|
|
</div> |
|
|
<p class="text-gray-400 text-lg typewriter">Gerador de código PIX instantâneo</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="card-bg rounded-2xl p-6 neon-glow relative overflow-hidden"> |
|
|
|
|
|
<div class="absolute inset-0 bg-gradient-to-br from-transparent via-white/5 to-transparent pointer-events-none"></div> |
|
|
|
|
|
|
|
|
<div class="step-indicator"> |
|
|
<div class="step active"> |
|
|
<div class="step-circle"> |
|
|
<i class="fas fa-dollar-sign text-xs"></i> |
|
|
</div> |
|
|
<div class="step-text">Valor</div> |
|
|
</div> |
|
|
<div class="step"> |
|
|
<div class="step-circle"> |
|
|
<i class="fas fa-qrcode text-xs"></i> |
|
|
</div> |
|
|
<div class="step-text">QR Code</div> |
|
|
</div> |
|
|
<div class="step"> |
|
|
<div class="step-circle"> |
|
|
<i class="fas fa-check text-xs"></i> |
|
|
</div> |
|
|
<div class="step-text">Concluído</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mb-6 relative z-10"> |
|
|
<h2 class="text-xl font-semibold text-white flex items-center"> |
|
|
<i class="fas fa-dollar-sign text-gray-300 mr-2"></i> |
|
|
Informe o valor do pagamento |
|
|
<span class="security-badge"> |
|
|
<i class="fas fa-shield-alt mr-1"></i> Seguro |
|
|
</span> |
|
|
</h2> |
|
|
<p class="text-gray-400 text-sm mt-1"> |
|
|
Digite o valor que deseja pagar via PIX |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="mb-6 relative z-10"> |
|
|
<div class="amount-input-container"> |
|
|
<span class="currency-symbol">R$</span> |
|
|
<input |
|
|
type="number" |
|
|
id="amount" |
|
|
step="0.01" |
|
|
min="0.01" |
|
|
placeholder="0,00" |
|
|
class="amount-input" |
|
|
> |
|
|
<div class="input-decoration"></div> |
|
|
</div> |
|
|
<div class="flex justify-between mt-2"> |
|
|
<p class="text-gray-500 text-xs flex items-center"> |
|
|
<i class="fas fa-info-circle mr-1"></i> |
|
|
Use valores como 25,00 ou 50,00 |
|
|
</p> |
|
|
<p class="text-gray-500 text-xs"> |
|
|
<span id="amount-preview">R$ 0,00</span> |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<button |
|
|
id="generate-pix" |
|
|
class="w-full bg-gradient-to-r from-gray-800 to-gray-900 text-white font-bold py-4 rounded-xl btn-hover-effect pulse-glow relative overflow-hidden transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-gray-600" |
|
|
> |
|
|
<i class="fas fa-bolt mr-2"></i> |
|
|
GERAR CÓDIGO PIX |
|
|
<i class="fas fa-qrcode ml-2"></i> |
|
|
</button> |
|
|
|
|
|
|
|
|
<div class="feature-grid"> |
|
|
<div class="feature-item"> |
|
|
<div class="feature-icon"> |
|
|
<i class="fas fa-shield-alt"></i> |
|
|
</div> |
|
|
<div> |
|
|
<h3 class="font-semibold">Segurança</h3> |
|
|
<p class="text-gray-400 text-sm">Transação criptografada</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="feature-item"> |
|
|
<div class="feature-icon"> |
|
|
<i class="fas fa-bolt"></i> |
|
|
</div> |
|
|
<div> |
|
|
<h3 class="font-semibold">Instantâneo</h3> |
|
|
<p class="text-gray-400 text-sm">Processamento rápido</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="feature-item"> |
|
|
<div class="feature-icon"> |
|
|
<i class="fas fa-mobile-alt"></i> |
|
|
</div> |
|
|
<div> |
|
|
<h3 class="font-semibold">Prático</h3> |
|
|
<p class="text-gray-400 text-sm">Copie e cole o código</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="fraude-info"> |
|
|
<h3><i class="fas fa-exclamation-triangle mr-2"></i> Aviso importante sobre segurança</h3> |
|
|
<p class="text-gray-300 text-sm"> |
|
|
Alguns bancos podem exibir alertas de segurança durante o pagamento. Isso acontece porque o recebedor processa um grande volume de transações, o que pode ativar sistemas automáticos de prevenção a fraudes. |
|
|
</p> |
|
|
<p class="text-gray-300 text-sm mt-2"> |
|
|
Estes avisos são normais e não indicam qualquer problema com sua transação. Nossa plataforma é 100% segura e todas as transações são criptografadas. |
|
|
</p> |
|
|
<div class="flex items-center mt-3 text-xs text-gray-400"> |
|
|
<i class="fas fa-info-circle mr-2"></i> |
|
|
<span>Em caso de dúvidas, entre em contato com nosso suporte.</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="text-center mt-6 text-gray-500 text-sm"> |
|
|
<p class="flex items-center justify-center"> |
|
|
<i class="fas fa-lock text-gray-400 mr-2"></i> |
|
|
Transação 100% segura e criptografada |
|
|
</p> |
|
|
<p class="mt-2 flex items-center justify-center"> |
|
|
<i class="fas fa-bolt text-gray-400 mr-2"></i> |
|
|
Processamento instantâneo |
|
|
</p> |
|
|
<p class="mt-2 flex items-center justify-center"> |
|
|
<i class="fas fa-headset text-gray-400 mr-2"></i> |
|
|
Suporte 24/7 disponível |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="modal-overlay" id="pix-modal"> |
|
|
<div class="modal-content"> |
|
|
<button class="close-modal" id="close-modal"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
|
|
|
<div class="text-center mb-4"> |
|
|
<h2 class="text-2xl font-bold text-white">Código PIX Gerado</h2> |
|
|
<p class="text-gray-400 mt-1">Copie o código abaixo para realizar o pagamento</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="qr-code-placeholder"> |
|
|
<i class="fas fa-qrcode"></i> |
|
|
<span class="text-gray-400 text-sm">QR Code</span> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="text-center my-4"> |
|
|
<p class="text-gray-400">Valor a pagar:</p> |
|
|
<p class="text-2xl font-bold text-white" id="modal-amount">R$ 0,00</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-900 rounded-xl p-4 border border-gray-700 mt-4"> |
|
|
<div class="flex items-center mb-2"> |
|
|
<i class="fas fa-qrcode text-gray-400 mr-2"></i> |
|
|
<p class="text-white font-medium">Código PIX copia e cola:</p> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<input |
|
|
type="text" |
|
|
id="pix-copy-paste" |
|
|
class="flex-1 bg-white border border-gray-600 rounded-l-lg py-3 px-4 text-input text-sm font-mono focus:outline-none input-focus-effect" |
|
|
readonly |
|
|
> |
|
|
<button |
|
|
id="copy-pix-button" |
|
|
class="bg-gradient-to-b from-gray-800 to-gray-900 hover:from-gray-700 hover:to-gray-800 text-white py-3 px-4 rounded-r-lg transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-gray-600 flex items-center btn-hover-effect" |
|
|
> |
|
|
<i class="fas fa-copy mr-1"></i> Copiar |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="payment-status pending mt-4" id="payment-status"> |
|
|
<i class="fas fa-clock text-yellow-500 mr-2"></i> |
|
|
<span class="text-gray-300">Aguardando pagamento</span> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="mt-4 bg-gray-800/50 rounded-lg p-3 border border-gray-700"> |
|
|
<p class="text-gray-300 text-sm flex items-start"> |
|
|
<i class="fas fa-lightbulb text-gray-400 mr-2 mt-1"></i> |
|
|
<span>Abra seu app de pagamentos, selecione PIX Copia e Cola, cole o código e confirme o pagamento.</span> |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="info-card mt-4"> |
|
|
<h3 class="font-semibold text-white flex items-center"> |
|
|
<i class="fas fa-info-circle text-gray-400 mr-2"></i> |
|
|
Importante |
|
|
</h3> |
|
|
<p class="text-gray-300 text-sm mt-1"> |
|
|
Após o pagamento, o status será atualizado automaticamente para "Pago". Em caso de problemas, entre em contato com nosso suporte. |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="hidden"> |
|
|
|
|
|
<form id="customer-form"> |
|
|
<input name="name" id="name" type="text"> |
|
|
<input name="phone_number" id="phone_number" type="tel"> |
|
|
<input type="hidden" id="email" name="email"> |
|
|
<input type="hidden" id="document" name="document"> |
|
|
</form> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const productInfo = { |
|
|
productName: "Banir Whatsapp", |
|
|
productImage: "https://dlzpblyjxiqfa.cloudfront.net/2994882476/products/qldxhanwdvi90ee5kh88s7kfr", |
|
|
productHash: "p7kb7gvu9t", |
|
|
offerHash: "9v8oiyiytj" |
|
|
}; |
|
|
|
|
|
|
|
|
const API_ENDPOINT = "https://api.ironpayapp.com.br/api/public/v1"; |
|
|
const API_TOKEN = "MXAZwBvIoLSD2tZIDeLA68HY38eXx7c1HYa65Kj6VMjtAvYe4Q65ZQrIxvc4"; |
|
|
|
|
|
|
|
|
const namesAndPhones = [ |
|
|
{ name: "Ana Carolina Silva", phone: "11987654321" }, |
|
|
{ name: "Bruno Oliveira Santos", phone: "21976543210" }, |
|
|
{ name: "Carla Mendes Rodrigues", phone: "31965432109" }, |
|
|
{ name: "Diego Almeida Costa", phone: "41954321098" }, |
|
|
{ name: "Elisa Pereira Lima", phone: "51943210987" }, |
|
|
{ name: "Fernando Souza Oliveira", phone: "61932109876" }, |
|
|
{ name: "Gabriela Rocha Martins", phone: "71921098765" }, |
|
|
{ name: "Henrique Barbosa Ferreira", phone: "81910987654" }, |
|
|
{ name: "Isabela Carvalho Alves", phone: "12999876543" }, |
|
|
{ name: "João Victor Dias Nunes", phone: "13988765432" }, |
|
|
{ name: "Larissa Santos Costa", phone: "14977654321" }, |
|
|
{ name: "Marcos Vinicius Almeida", phone: "15966543210" }, |
|
|
{ name: "Natália Ferreira Lima", phone: "16955432109" }, |
|
|
{ name: "Otávio Rodrigues Pereira", phone: "17944321098" }, |
|
|
{ name: "Patrícia Souza Oliveira", phone: "18933210987" }, |
|
|
{ name: "Rafael Mendes Carvalho", phone: "19922109876" }, |
|
|
{ name: "Sofia Alves Martins", phone: "21911987654" }, |
|
|
{ name: "Thiago Costa Nunes", phone: "22900876543" }, |
|
|
{ name: "Vanessa Lima Santos", phone: "23999765432" }, |
|
|
{ name: "William Oliveira Rodrigues", phone: "24988654321" }, |
|
|
{ name: "Alice Pereira Almeida", phone: "25977543210" }, |
|
|
{ name: "Breno Carvalho Ferreira", phone: "26966432109" }, |
|
|
{ name: "Camila Martins Costa", phone: "27955321098" }, |
|
|
{ name: "Daniel Nunes Lima", phone: "28944210987" }, |
|
|
{ name: "Eduarda Santos Oliveira", phone: "29933109876" }, |
|
|
{ name: "Felipe Almeida Rodrigues", phone: "31922098765" }, |
|
|
{ name: "Giovanna Ferreira Pereira", phone: "32911987654" }, |
|
|
{ name: "Heitor Lima Carvalho", phone: "33900876543" }, |
|
|
{ name: "Igor Costa Martins", phone: "34999765432" }, |
|
|
{ name: "Julia Oliveira Nunes", phone: "35988654321" }, |
|
|
{ name: "Kevin Rodrigues Santos", phone: "36977543210" }, |
|
|
{ name: "Lucas Pereira Almeida", phone: "37966432109" }, |
|
|
{ name: "Mariana Carvalho Ferreira", phone: "38955321098" }, |
|
|
{ name: "Nathan Martins Costa", phone: "39944210987" }, |
|
|
{ name: "Olivia Nunes Lima", phone: "41933109876" }, |
|
|
{ name: "Pedro Santos Oliveira", phone: "42922098765" }, |
|
|
{ name: "Quezia Almeida Rodrigues", phone: "43911987654" }, |
|
|
{ name: "Ruan Ferreira Pereira", phone: "44900876543" }, |
|
|
{ name: "Stella Lima Carvalho", phone: "45999765432" }, |
|
|
{ name: "Thomas Costa Martins", phone: "46988654321" }, |
|
|
{ name: "Ursula Oliveira Nunes", phone: "47977543210" }, |
|
|
{ name: "Vitor Rodrigues Santos", phone: "48966432109" }, |
|
|
{ name: "Wesley Pereira Almeida", phone: "49955321098" }, |
|
|
{ name: "Xuxa Carvalho Ferreira", phone: "51944210987" }, |
|
|
{ name: "Yasmin Martins Costa", phone: "52933109876" }, |
|
|
{ name: "Zacarias Nunes Lima", phone: "53922098765" }, |
|
|
{ name: "Amanda Santos Oliveira", phone: "54911987654" }, |
|
|
{ name: "Bernardo Almeida Rodrigues", phone: "55900876543" }, |
|
|
{ name: "Clara Ferreira Pereira", phone: "56999765432" }, |
|
|
{ name: "Davi Lima Carvalho", phone: "57988654321" }, |
|
|
{ name: "Elaine Costa Martins", phone: "58977543210" }, |
|
|
{ name: "Fabio Oliveira Nunes", phone: "59966432109" }, |
|
|
{ name: "Geovana Rodrigues Santos", phone: "61955321098" }, |
|
|
{ name: "Hugo Pereira Almeida", phone: "62944210987" }, |
|
|
{ name: "Ingrid Carvalho Ferreira", phone: "63933109876" }, |
|
|
{ name: "Jorge Martins Costa", phone: "64922098765" }, |
|
|
{ name: "Karen Nunes Lima", phone: "65911987654" }, |
|
|
{ name: "Leonardo Santos Oliveira", phone: "66900876543" }, |
|
|
{ name: "Michele Almeida Rodrigues", phone: "67999765432" }, |
|
|
{ name: "Nicolas Ferreira Pereira", phone: "68988654321" }, |
|
|
{ name: "Orlando Lima Carvalho", phone: "69977543210" }, |
|
|
{ name: "Paula Costa Martins", phone: "71966432109" }, |
|
|
{ name: "Quintino Oliveira Nunes", phone: "72955321098" }, |
|
|
{ name: "Renata Rodrigues Santos", phone: "73944210987" }, |
|
|
{ name: "Samuel Pereira Almeida", phone: "74933109876" }, |
|
|
{ name: "Tatiane Carvalho Ferreira", phone: "75922098765" }, |
|
|
{ name: "Ubirajara Martins Costa", phone: "76911987654" }, |
|
|
{ name: "Viviane Nunes Lima", phone: "77900876543" }, |
|
|
{ name: "Wagner Santos Oliveira", phone: "78999765432" }, |
|
|
{ name: "Xande Almeida Rodrigues", phone: "79988654321" }, |
|
|
{ name: "Yara Ferreira Pereira", phone: "81977543210" }, |
|
|
{ name: "Zé Lima Carvalho", phone: "82966432109" }, |
|
|
{ name: "Aline Costa Martins", phone: "83955321098" }, |
|
|
{ name: "Beto Oliveira Nunes", phone: "84944210987" }, |
|
|
{ name: "Cíntia Rodrigues Santos", phone: "85933109876" }, |
|
|
{ name: "Douglas Pereira Almeida", phone: "86922098765" }, |
|
|
{ name: "Ester Carvalho Ferreira", phone: "87911987654" }, |
|
|
{ name: "Flávio Martins Costa", phone: "88900876543" }, |
|
|
{ name: "Gisele Nunes Lima", phone: "89999765432" }, |
|
|
{ name: "Hélio Santos Oliveira", phone: "91988654321" }, |
|
|
{ name: "Iara Almeida Rodrigues", phone: "92977543210" }, |
|
|
{ name: "José Ferreira Pereira", phone: "93966432109" }, |
|
|
{ name: "Kelly Lima Carvalho", phone: "94955321098" }, |
|
|
{ name: "Leandro Costa Martins", phone: "95944210987" }, |
|
|
{ name: "Márcia Oliveira Nunes", phone: "96933109876" }, |
|
|
{ name: "Nelson Rodrigues Santos", phone: "97922098765" }, |
|
|
{ name: "Olívia Pereira Almeida", phone: "98911987654" }, |
|
|
{ name: "Paulo Carvalho Ferreira", phone: "99900876543" }, |
|
|
{ name: "Quésia Martins Costa", phone: "11988765432" }, |
|
|
{ name: "Ricardo Nunes Lima", phone: "12977654321" }, |
|
|
{ name: "Sandra Santos Oliveira", phone: "13966543210" }, |
|
|
{ name: "Tiago Almeida Rodrigues", phone: "14955432109" }, |
|
|
{ name: "Úrsula Ferreira Pereira", phone: "15944321098" }, |
|
|
{ name: "Valter Lima Carvalho", phone: "16933210987" }, |
|
|
{ name: "Wanessa Costa Martins", phone: "17922109876" }, |
|
|
{ name: "Xavier Oliveira Nunes", phone: "18911098765" }, |
|
|
{ name: "Yasmin Rodrigues Santos", phone: "19900987654" } |
|
|
]; |
|
|
|
|
|
|
|
|
function generateValidCPF() { |
|
|
function randomDigit() { |
|
|
return Math.floor(Math.random() * 10); |
|
|
} |
|
|
|
|
|
function calculateDigit(base, factor) { |
|
|
let total = 0; |
|
|
for (let i = 0; i < base.length; i++) { |
|
|
total += base[i] * (factor - i); |
|
|
} |
|
|
const remainder = total % 11; |
|
|
return remainder < 2 ? 0 : 11 - remainder; |
|
|
} |
|
|
|
|
|
|
|
|
const base = Array.from({ length: 9 }, randomDigit); |
|
|
|
|
|
|
|
|
const firstDigit = calculateDigit(base, 10); |
|
|
base.push(firstDigit); |
|
|
|
|
|
|
|
|
const secondDigit = calculateDigit(base, 11); |
|
|
base.push(secondDigit); |
|
|
|
|
|
return base.join(''); |
|
|
} |
|
|
|
|
|
|
|
|
const cpfs = Array.from({ length: 100 }, generateValidCPF); |
|
|
|
|
|
const emails = [ |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]", "[email protected]", |
|
|
"[email protected]", "[email protected]" |
|
|
]; |
|
|
|
|
|
|
|
|
const customerForm = document.getElementById('customer-form'); |
|
|
const amountInput = document.getElementById('amount'); |
|
|
const amountPreview = document.getElementById('amount-preview'); |
|
|
const generatePixButton = document.getElementById('generate-pix'); |
|
|
const pixModal = document.getElementById('pix-modal'); |
|
|
const closeModalButton = document.getElementById('close-modal'); |
|
|
const pixCopyPasteInput = document.getElementById('pix-copy-paste'); |
|
|
const copyPixButton = document.getElementById('copy-pix-button'); |
|
|
const paymentStatus = document.getElementById('payment-status'); |
|
|
const modalAmount = document.getElementById('modal-amount'); |
|
|
|
|
|
|
|
|
function getRandomItem(array) { |
|
|
return array[Math.floor(Math.random() * array.length)]; |
|
|
} |
|
|
|
|
|
function autoFillCustomerData() { |
|
|
|
|
|
const randomUser = getRandomItem(namesAndPhones); |
|
|
const randomCPF = getRandomItem(cpfs); |
|
|
const randomEmail = getRandomItem(emails); |
|
|
|
|
|
|
|
|
document.getElementById('name').value = randomUser.name; |
|
|
document.getElementById('phone_number').value = randomUser.phone; |
|
|
document.getElementById('document').value = randomCPF; |
|
|
document.getElementById('email').value = randomEmail; |
|
|
|
|
|
console.log('Dados preenchidos automaticamente:', { |
|
|
name: randomUser.name, |
|
|
phone: randomUser.phone, |
|
|
cpf: randomCPF, |
|
|
email: randomEmail |
|
|
}); |
|
|
} |
|
|
|
|
|
function openModal() { |
|
|
pixModal.classList.add('active'); |
|
|
document.body.style.overflow = 'hidden'; |
|
|
|
|
|
|
|
|
const amount = parseFloat(amountInput.value); |
|
|
modalAmount.textContent = `R$ ${amount.toFixed(2).replace('.', ',')}`; |
|
|
} |
|
|
|
|
|
function closeModal() { |
|
|
pixModal.classList.remove('active'); |
|
|
document.body.style.overflow = 'auto'; |
|
|
} |
|
|
|
|
|
function updatePaymentStatus(status) { |
|
|
|
|
|
paymentStatus.classList.remove('pending', 'paid', 'canceled'); |
|
|
|
|
|
|
|
|
paymentStatus.classList.add(status); |
|
|
|
|
|
|
|
|
switch(status) { |
|
|
case 'paid': |
|
|
paymentStatus.innerHTML = '<i class="fas fa-check-circle text-green-500 mr-2"></i><span class="text-gray-300">Pagamento confirmado</span>'; |
|
|
break; |
|
|
case 'pending': |
|
|
paymentStatus.innerHTML = '<i class="fas fa-clock text-yellow-500 mr-2"></i><span class="text-gray-300">Aguardando pagamento</span>'; |
|
|
break; |
|
|
case 'canceled': |
|
|
paymentStatus.innerHTML = '<i class="fas fa-times-circle text-red-500 mr-2"></i><span class="text-gray-300">Pagamento cancelado</span>'; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
amountInput.addEventListener('input', function() { |
|
|
const amount = parseFloat(this.value) || 0; |
|
|
amountPreview.textContent = `R$ ${amount.toFixed(2).replace('.', ',')}`; |
|
|
}); |
|
|
|
|
|
|
|
|
async function fetchTransactionByHashOnce(hash) { |
|
|
const url = `${API_ENDPOINT}/transactions/${hash}?api_token=${API_TOKEN}`; |
|
|
const r = await fetch(url, { headers: { Accept: 'application/json' } }); |
|
|
const txt = await r.text(); |
|
|
let j; |
|
|
try { |
|
|
j = JSON.parse(txt); |
|
|
} catch { |
|
|
j = { raw: txt }; |
|
|
} |
|
|
return { ok: r.ok, status: r.status, json: j }; |
|
|
} |
|
|
|
|
|
|
|
|
generatePixButton.addEventListener('click', async () => { |
|
|
const amount = parseFloat(amountInput.value); |
|
|
|
|
|
if (!amount || amount <= 0) { |
|
|
|
|
|
amountInput.parentElement.classList.add('border-red-500'); |
|
|
setTimeout(() => { |
|
|
amountInput.parentElement.classList.remove('border-red-500'); |
|
|
}, 1000); |
|
|
|
|
|
|
|
|
const errorMsg = document.createElement('div'); |
|
|
errorMsg.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-red-600 text-white px-4 py-2 rounded-lg shadow-lg z-50'; |
|
|
errorMsg.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>Por favor, insira um valor válido'; |
|
|
document.body.appendChild(errorMsg); |
|
|
|
|
|
setTimeout(() => { |
|
|
document.body.removeChild(errorMsg); |
|
|
}, 3000); |
|
|
|
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
generatePixButton.disabled = true; |
|
|
generatePixButton.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> GERANDO...'; |
|
|
|
|
|
|
|
|
generatePixButton.classList.remove('pulse-glow'); |
|
|
generatePixButton.classList.add('bg-gray-700'); |
|
|
|
|
|
|
|
|
autoFillCustomerData(); |
|
|
|
|
|
const customerData = { |
|
|
name: document.getElementById('name').value, |
|
|
email: document.getElementById('email').value, |
|
|
phone_number: document.getElementById('phone_number').value, |
|
|
document: document.getElementById('document').value, |
|
|
street_name: "Não informado", |
|
|
number: "s/n", |
|
|
complement: "", |
|
|
neighborhood: "Não informado", |
|
|
city: "Não informado", |
|
|
state: "NI", |
|
|
zip_code: "00000000" |
|
|
}; |
|
|
|
|
|
|
|
|
const paymentPayload = { |
|
|
amount: Math.round(amount * 100), |
|
|
offer_hash: productInfo.offerHash, |
|
|
payment_method: "pix", |
|
|
customer: customerData, |
|
|
cart: [{ |
|
|
product_hash: productInfo.productHash, |
|
|
title: productInfo.productName, |
|
|
cover: null, |
|
|
price: Math.round(amount * 100), |
|
|
quantity: 1, |
|
|
operation_type: 1, |
|
|
tangible: false |
|
|
}], |
|
|
installments: 1, |
|
|
expire_in_days: 1, |
|
|
transaction_origin: 'api', |
|
|
postback_url: '' |
|
|
}; |
|
|
|
|
|
try { |
|
|
|
|
|
const response = await fetch(`${API_ENDPOINT}/transactions?api_token=${API_TOKEN}`, { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Accept': 'application/json', |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify(paymentPayload) |
|
|
}); |
|
|
|
|
|
const text = await response.text(); |
|
|
let result; |
|
|
try { |
|
|
result = JSON.parse(text); |
|
|
} catch { |
|
|
result = { raw: text }; |
|
|
} |
|
|
|
|
|
if (!response.ok) { |
|
|
const msg = result?.message || 'Ocorreu um erro.'; |
|
|
const errs = result?.errors ? '\n' + Object.values(result.errors).map(e => e[0]).join('\n') : ''; |
|
|
throw new Error(msg + errs); |
|
|
} |
|
|
|
|
|
|
|
|
const hash = result?.hash || result?.data?.hash; |
|
|
if (!hash) throw new Error('Transação criada, mas sem hash na resposta.'); |
|
|
|
|
|
|
|
|
const { ok, json } = await fetchTransactionByHashOnce(hash); |
|
|
if (!ok) throw new Error('Não foi possível obter os dados do PIX.'); |
|
|
|
|
|
const data = json.data || json; |
|
|
const status = String(data.payment_status || data.status || '').toLowerCase(); |
|
|
|
|
|
|
|
|
const copyPaste = (data.pix_qr_code || data.pix?.pix_qr_code || data.qr_code || data.copy_paste || data.code || '').trim(); |
|
|
|
|
|
|
|
|
pixCopyPasteInput.value = copyPaste; |
|
|
pixCopyPasteInput.setAttribute('value', copyPaste); |
|
|
|
|
|
|
|
|
updatePaymentStatus(status); |
|
|
|
|
|
|
|
|
openModal(); |
|
|
|
|
|
|
|
|
generatePixButton.innerHTML = '<i class="fas fa-check mr-2"></i> CÓDIGO GERADO!'; |
|
|
setTimeout(() => { |
|
|
generatePixButton.innerHTML = '<i class="fas fa-bolt mr-2"></i> GERAR CÓDIGO PIX <i class="fas fa-qrcode ml-2"></i>'; |
|
|
}, 2000); |
|
|
|
|
|
} catch (error) { |
|
|
console.error('Falha na operação:', error); |
|
|
|
|
|
|
|
|
generatePixButton.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i> ERRO! TENTE NOVAMENTE'; |
|
|
generatePixButton.classList.add('bg-red-600'); |
|
|
|
|
|
setTimeout(() => { |
|
|
generatePixButton.innerHTML = '<i class="fas fa-bolt mr-2"></i> GERAR CÓDIGO PIX <i class="fas fa-qrcode ml-2"></i>'; |
|
|
generatePixButton.classList.remove('bg-red-600'); |
|
|
generatePixButton.classList.add('pulse-glow'); |
|
|
}, 3000); |
|
|
|
|
|
|
|
|
const errorMsg = document.createElement('div'); |
|
|
errorMsg.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-red-600 text-white px-4 py-2 rounded-lg shadow-lg z-50'; |
|
|
errorMsg.innerHTML = `<i class="fas fa-exclamation-triangle mr-2"></i>${error.message || 'Erro ao gerar PIX'}`; |
|
|
document.body.appendChild(errorMsg); |
|
|
|
|
|
setTimeout(() => { |
|
|
document.body.removeChild(errorMsg); |
|
|
}, 5000); |
|
|
} finally { |
|
|
generatePixButton.disabled = false; |
|
|
generatePixButton.classList.remove('bg-gray-700'); |
|
|
generatePixButton.classList.add('pulse-glow'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
copyPixButton.addEventListener('click', async () => { |
|
|
const text = (pixCopyPasteInput.value || pixCopyPasteInput.getAttribute('value') || '').trim(); |
|
|
if (!text) { |
|
|
|
|
|
const errorMsg = document.createElement('div'); |
|
|
errorMsg.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-red-600 text-white px-4 py-2 rounded-lg shadow-lg z-50'; |
|
|
errorMsg.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>Código PIX não disponível'; |
|
|
document.body.appendChild(errorMsg); |
|
|
|
|
|
setTimeout(() => { |
|
|
document.body.removeChild(errorMsg); |
|
|
}, 3000); |
|
|
return; |
|
|
} |
|
|
|
|
|
try { |
|
|
if (navigator.clipboard && window.isSecureContext) { |
|
|
await navigator.clipboard.writeText(text); |
|
|
} else { |
|
|
const ta = document.createElement('textarea'); |
|
|
ta.value = text; |
|
|
ta.style.position = 'fixed'; |
|
|
ta.style.left = '-9999px'; |
|
|
document.body.appendChild(ta); |
|
|
ta.focus(); |
|
|
ta.select(); |
|
|
document.execCommand('copy'); |
|
|
document.body.removeChild(ta); |
|
|
} |
|
|
|
|
|
|
|
|
copyPixButton.innerHTML = '<i class="fas fa-check mr-1"></i> Copiado!'; |
|
|
copyPixButton.classList.remove('bg-gradient-to-b'); |
|
|
copyPixButton.classList.add('bg-green-600'); |
|
|
|
|
|
|
|
|
const successMsg = document.createElement('div'); |
|
|
successMsg.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg z-50'; |
|
|
successMsg.innerHTML = '<i class="fas fa-check-circle mr-2"></i>Código copiado para a área de transferência!'; |
|
|
document.body.appendChild(successMsg); |
|
|
|
|
|
setTimeout(() => { |
|
|
document.body.removeChild(successMsg); |
|
|
}, 3000); |
|
|
|
|
|
} catch (e) { |
|
|
console.error(e); |
|
|
copyPixButton.innerHTML = '<i class="fas fa-times mr-1"></i> Falhou!'; |
|
|
copyPixButton.classList.remove('bg-gradient-to-b'); |
|
|
copyPixButton.classList.add('bg-red-600'); |
|
|
} finally { |
|
|
setTimeout(() => { |
|
|
copyPixButton.innerHTML = '<i class="fas fa-copy mr-1"></i> Copiar'; |
|
|
copyPixButton.classList.remove('bg-green-600', 'bg-red-600'); |
|
|
copyPixButton.classList.add('bg-gradient-to-b'); |
|
|
}, 2000); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
closeModalButton.addEventListener('click', closeModal); |
|
|
|
|
|
|
|
|
pixModal.addEventListener('click', (e) => { |
|
|
if (e.target === pixModal) { |
|
|
closeModal(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
amountInput.addEventListener('focus', function() { |
|
|
this.parentElement.classList.add('neon-glow'); |
|
|
}); |
|
|
|
|
|
amountInput.addEventListener('blur', function() { |
|
|
this.parentElement.classList.remove('neon-glow'); |
|
|
}); |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
amountInput.focus(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
amountInput.placeholder = "25,00"; |
|
|
}, 1000); |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |