Sariel187 commited on
Commit
7fd27e0
·
verified ·
1 Parent(s): 804c873

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +1216 -19
index.html CHANGED
@@ -1,19 +1,1216 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>SecurePIX | Gerador de Pagamentos</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"/>
8
+ <script src="https://unpkg.com/imask"></script>
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <style>
11
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
12
+
13
+ :root {
14
+ --primary-dark: #0a0a0a;
15
+ --primary-medium: #1a1a1a;
16
+ --primary-light: #2a2a2a;
17
+ --accent-light: #e0e0e0;
18
+ --accent-medium: #a0a0a0;
19
+ --accent-dark: #5a5a5a;
20
+ --white: #ffffff;
21
+ --black: #000000;
22
+ }
23
+
24
+ body {
25
+ font-family: 'Inter', sans-serif;
26
+ background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0a0a0a 100%);
27
+ min-height: 100vh;
28
+ overflow-x: hidden;
29
+ position: relative;
30
+ color: var(--white);
31
+ }
32
+
33
+ body::before {
34
+ content: "";
35
+ position: fixed;
36
+ top: 0;
37
+ left: 0;
38
+ width: 100%;
39
+ height: 100%;
40
+ background-image:
41
+ radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.03) 0%, transparent 40%),
42
+ radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.02) 0%, transparent 40%),
43
+ radial-gradient(circle at 40% 80%, rgba(255, 255, 255, 0.01) 0%, transparent 40%);
44
+ z-index: -1;
45
+ }
46
+
47
+ .card-bg {
48
+ background: rgba(26, 26, 26, 0.8);
49
+ backdrop-filter: blur(15px);
50
+ border: 1px solid rgba(255, 255, 255, 0.1);
51
+ box-shadow:
52
+ 0 10px 30px rgba(0, 0, 0, 0.3),
53
+ inset 0 1px 0 rgba(255, 255, 255, 0.05);
54
+ }
55
+
56
+ .neon-glow {
57
+ box-shadow:
58
+ 0 0 15px rgba(255, 255, 255, 0.1),
59
+ 0 0 30px rgba(255, 255, 255, 0.05),
60
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
61
+ }
62
+
63
+ .gradient-text {
64
+ background: linear-gradient(90deg, #e0e0e0 0%, #ffffff 50%, #e0e0e0 100%);
65
+ -webkit-background-clip: text;
66
+ -webkit-text-fill-color: transparent;
67
+ background-size: 200% auto;
68
+ animation: shimmer 3s linear infinite;
69
+ }
70
+
71
+ @keyframes shimmer {
72
+ 0% { background-position: 0% center; }
73
+ 100% { background-position: 200% center; }
74
+ }
75
+
76
+ .float-animation {
77
+ animation: float 6s ease-in-out infinite;
78
+ }
79
+
80
+ @keyframes float {
81
+ 0% { transform: translateY(0px); }
82
+ 50% { transform: translateY(-10px); }
83
+ 100% { transform: translateY(0px); }
84
+ }
85
+
86
+ .pulse-glow {
87
+ animation: pulse-glow 2s infinite;
88
+ }
89
+
90
+ @keyframes pulse-glow {
91
+ 0% { box-shadow: 0 0 10px rgba(255, 255, 255, 0.1); }
92
+ 50% { box-shadow: 0 0 20px rgba(255, 255, 255, 0.2); }
93
+ 100% { box-shadow: 0 0 10px rgba(255, 255, 255, 0.1); }
94
+ }
95
+
96
+ .typewriter {
97
+ overflow: hidden;
98
+ border-right: 2px solid rgba(255, 255, 255, 0.7);
99
+ white-space: nowrap;
100
+ animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
101
+ }
102
+
103
+ @keyframes typing {
104
+ from { width: 0 }
105
+ to { width: 100% }
106
+ }
107
+
108
+ @keyframes blink-caret {
109
+ from, to { border-color: transparent }
110
+ 50% { border-color: rgba(255, 255, 255, 0.7) }
111
+ }
112
+
113
+ .particle {
114
+ position: absolute;
115
+ width: 4px;
116
+ height: 4px;
117
+ background: rgba(255, 255, 255, 0.5);
118
+ border-radius: 50%;
119
+ opacity: 0;
120
+ }
121
+
122
+ .particle:nth-child(1) { top: 20%; left: 10%; animation: particle-float 8s infinite; }
123
+ .particle:nth-child(2) { top: 60%; left: 85%; animation: particle-float 10s infinite 1s; }
124
+ .particle:nth-child(3) { top: 80%; left: 20%; animation: particle-float 12s infinite 2s; }
125
+ .particle:nth-child(4) { top: 30%; left: 70%; animation: particle-float 9s infinite 3s; }
126
+ .particle:nth-child(5) { top: 70%; left: 40%; animation: particle-float 11s infinite 4s; }
127
+
128
+ @keyframes particle-float {
129
+ 0% { transform: translateY(0) translateX(0); opacity: 0; }
130
+ 50% { opacity: 1; }
131
+ 100% { transform: translateY(-100px) translateX(20px); opacity: 0; }
132
+ }
133
+
134
+ .btn-hover-effect {
135
+ position: relative;
136
+ overflow: hidden;
137
+ transition: all 0.3s;
138
+ }
139
+
140
+ .btn-hover-effect::before {
141
+ content: "";
142
+ position: absolute;
143
+ top: 0;
144
+ left: -100%;
145
+ width: 100%;
146
+ height: 100%;
147
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
148
+ transition: all 0.6s;
149
+ }
150
+
151
+ .btn-hover-effect:hover::before {
152
+ left: 100%;
153
+ }
154
+
155
+ .input-focus-effect:focus {
156
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
157
+ }
158
+
159
+ /* Campo de valor aprimorado */
160
+ .amount-input-container {
161
+ position: relative;
162
+ background: rgba(255, 255, 255, 0.05);
163
+ border-radius: 16px;
164
+ padding: 1.5rem;
165
+ border: 1px solid rgba(255, 255, 255, 0.1);
166
+ transition: all 0.3s;
167
+ }
168
+
169
+ .amount-input-container:focus-within {
170
+ background: rgba(255, 255, 255, 0.08);
171
+ border-color: rgba(255, 255, 255, 0.3);
172
+ box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);
173
+ }
174
+
175
+ .amount-input {
176
+ font-size: 2.5rem;
177
+ font-weight: 700;
178
+ background: transparent;
179
+ border: none;
180
+ color: white;
181
+ width: 100%;
182
+ text-align: center;
183
+ outline: none;
184
+ }
185
+
186
+ .amount-input::placeholder {
187
+ color: rgba(255, 255, 255, 0.3);
188
+ }
189
+
190
+ .currency-symbol {
191
+ position: absolute;
192
+ left: 2rem;
193
+ top: 50%;
194
+ transform: translateY(-50%);
195
+ font-size: 2rem;
196
+ color: rgba(255, 255, 255, 0.7);
197
+ }
198
+
199
+ .input-decoration {
200
+ position: absolute;
201
+ bottom: 0;
202
+ left: 50%;
203
+ transform: translateX(-50%);
204
+ width: 80%;
205
+ height: 2px;
206
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
207
+ }
208
+
209
+ /* Modal */
210
+ .modal-overlay {
211
+ position: fixed;
212
+ top: 0;
213
+ left: 0;
214
+ width: 100%;
215
+ height: 100%;
216
+ background: rgba(0, 0, 0, 0.8);
217
+ backdrop-filter: blur(5px);
218
+ display: flex;
219
+ justify-content: center;
220
+ align-items: center;
221
+ z-index: 1000;
222
+ opacity: 0;
223
+ visibility: hidden;
224
+ transition: all 0.3s;
225
+ }
226
+
227
+ .modal-overlay.active {
228
+ opacity: 1;
229
+ visibility: visible;
230
+ }
231
+
232
+ .modal-content {
233
+ width: 90%;
234
+ max-width: 500px;
235
+ background: var(--primary-medium);
236
+ border-radius: 20px;
237
+ padding: 2rem;
238
+ transform: translateY(20px);
239
+ opacity: 0;
240
+ transition: all 0.3s;
241
+ border: 1px solid rgba(255, 255, 255, 0.1);
242
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
243
+ }
244
+
245
+ .modal-overlay.active .modal-content {
246
+ transform: translateY(0);
247
+ opacity: 1;
248
+ }
249
+
250
+ .payment-status {
251
+ display: flex;
252
+ align-items: center;
253
+ justify-content: center;
254
+ margin-top: 1rem;
255
+ padding: 0.75rem;
256
+ border-radius: 8px;
257
+ background: rgba(0, 0, 0, 0.2);
258
+ }
259
+
260
+ .payment-status.paid {
261
+ background: rgba(16, 185, 129, 0.1);
262
+ border: 1px solid rgba(16, 185, 129, 0.3);
263
+ }
264
+
265
+ .payment-status.pending {
266
+ background: rgba(245, 158, 11, 0.1);
267
+ border: 1px solid rgba(245, 158, 11, 0.3);
268
+ }
269
+
270
+ .payment-status.canceled {
271
+ background: rgba(239, 68, 68, 0.1);
272
+ border: 1px solid rgba(239, 68, 68, 0.3);
273
+ }
274
+
275
+ .qr-code-placeholder {
276
+ width: 180px;
277
+ height: 180px;
278
+ background: rgba(255, 255, 255, 0.05);
279
+ border-radius: 12px;
280
+ display: flex;
281
+ flex-direction: column;
282
+ align-items: center;
283
+ justify-content: center;
284
+ margin: 1rem auto;
285
+ border: 1px dashed rgba(255, 255, 255, 0.2);
286
+ }
287
+
288
+ .qr-code-placeholder i {
289
+ font-size: 3rem;
290
+ margin-bottom: 0.5rem;
291
+ color: rgba(255, 255, 255, 0.3);
292
+ }
293
+
294
+ .close-modal {
295
+ position: absolute;
296
+ top: 1rem;
297
+ right: 1rem;
298
+ background: none;
299
+ border: none;
300
+ color: rgba(255, 255, 255, 0.7);
301
+ font-size: 1.5rem;
302
+ cursor: pointer;
303
+ transition: color 0.2s;
304
+ }
305
+
306
+ .close-modal:hover {
307
+ color: var(--white);
308
+ }
309
+
310
+ .logo-icon {
311
+ width: 60px;
312
+ height: 60px;
313
+ border-radius: 16px;
314
+ background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
315
+ display: flex;
316
+ align-items: center;
317
+ justify-content: center;
318
+ border: 1px solid rgba(255, 255, 255, 0.1);
319
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
320
+ }
321
+
322
+ .logo-icon i {
323
+ font-size: 1.8rem;
324
+ color: rgba(255, 255, 255, 0.9);
325
+ }
326
+
327
+ .info-card {
328
+ background: rgba(255, 255, 255, 0.05);
329
+ border-radius: 12px;
330
+ padding: 1.5rem;
331
+ border-left: 4px solid rgba(255, 255, 255, 0.2);
332
+ margin-top: 1.5rem;
333
+ }
334
+
335
+ .feature-grid {
336
+ display: grid;
337
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
338
+ gap: 1rem;
339
+ margin-top: 2rem;
340
+ }
341
+
342
+ .feature-item {
343
+ display: flex;
344
+ align-items: center;
345
+ padding: 1rem;
346
+ background: rgba(255, 255, 255, 0.03);
347
+ border-radius: 10px;
348
+ border: 1px solid rgba(255, 255, 255, 0.05);
349
+ }
350
+
351
+ .feature-icon {
352
+ width: 40px;
353
+ height: 40px;
354
+ border-radius: 10px;
355
+ background: rgba(255, 255, 255, 0.1);
356
+ display: flex;
357
+ align-items: center;
358
+ justify-content: center;
359
+ margin-right: 1rem;
360
+ }
361
+
362
+ .step-indicator {
363
+ display: flex;
364
+ justify-content: space-between;
365
+ position: relative;
366
+ margin: 2rem 0;
367
+ }
368
+
369
+ .step-indicator::before {
370
+ content: "";
371
+ position: absolute;
372
+ top: 15px;
373
+ left: 0;
374
+ right: 0;
375
+ height: 2px;
376
+ background: rgba(255, 255, 255, 0.1);
377
+ z-index: 1;
378
+ }
379
+
380
+ .step {
381
+ display: flex;
382
+ flex-direction: column;
383
+ align-items: center;
384
+ position: relative;
385
+ z-index: 2;
386
+ }
387
+
388
+ .step-circle {
389
+ width: 32px;
390
+ height: 32px;
391
+ border-radius: 50%;
392
+ background: rgba(255, 255, 255, 0.1);
393
+ display: flex;
394
+ align-items: center;
395
+ justify-content: center;
396
+ margin-bottom: 0.5rem;
397
+ border: 2px solid rgba(255, 255, 255, 0.2);
398
+ }
399
+
400
+ .step.active .step-circle {
401
+ background: rgba(255, 255, 255, 0.2);
402
+ border-color: rgba(255, 255, 255, 0.5);
403
+ }
404
+
405
+ .step-text {
406
+ font-size: 0.75rem;
407
+ color: rgba(255, 255, 255, 0.7);
408
+ text-align: center;
409
+ }
410
+
411
+ .security-badge {
412
+ display: inline-flex;
413
+ align-items: center;
414
+ background: rgba(16, 185, 129, 0.1);
415
+ color: #10b981;
416
+ padding: 0.25rem 0.75rem;
417
+ border-radius: 20px;
418
+ font-size: 0.75rem;
419
+ margin-left: 0.5rem;
420
+ }
421
+
422
+ .fraude-info {
423
+ background: rgba(245, 158, 11, 0.1);
424
+ border: 1px solid rgba(245, 158, 11, 0.3);
425
+ border-radius: 12px;
426
+ padding: 1.5rem;
427
+ margin-top: 2rem;
428
+ }
429
+
430
+ .fraude-info h3 {
431
+ display: flex;
432
+ align-items: center;
433
+ color: #f59e0b;
434
+ margin-bottom: 0.5rem;
435
+ }
436
+
437
+ .text-input {
438
+ color: #000000 !important;
439
+ }
440
+
441
+ .text-input::placeholder {
442
+ color: #666666 !important;
443
+ }
444
+ </style>
445
+ </head>
446
+ <body class="flex flex-col justify-center items-center p-4 min-h-screen">
447
+ <!-- Partículas de fundo -->
448
+ <div class="particle"></div>
449
+ <div class="particle"></div>
450
+ <div class="particle"></div>
451
+ <div class="particle"></div>
452
+ <div class="particle"></div>
453
+
454
+ <div class="w-full max-w-2xl relative">
455
+ <!-- Cabeçalho -->
456
+ <div class="text-center mb-8 relative">
457
+ <div class="flex justify-center items-center mb-4">
458
+ <div class="logo-icon mr-4 float-animation">
459
+ <i class="fas fa-coins"></i>
460
+ </div>
461
+ <div>
462
+ <h1 class="text-4xl font-bold gradient-text">SecurePIX</h1>
463
+ </div>
464
+ </div>
465
+ <p class="text-gray-400 text-lg typewriter">Gerador de código PIX instantâneo</p>
466
+ </div>
467
+
468
+ <!-- Card principal -->
469
+ <div class="card-bg rounded-2xl p-6 neon-glow relative overflow-hidden">
470
+ <!-- Efeito de brilho interno -->
471
+ <div class="absolute inset-0 bg-gradient-to-br from-transparent via-white/5 to-transparent pointer-events-none"></div>
472
+
473
+ <!-- Indicador de etapas -->
474
+ <div class="step-indicator">
475
+ <div class="step active">
476
+ <div class="step-circle">
477
+ <i class="fas fa-dollar-sign text-xs"></i>
478
+ </div>
479
+ <div class="step-text">Valor</div>
480
+ </div>
481
+ <div class="step">
482
+ <div class="step-circle">
483
+ <i class="fas fa-qrcode text-xs"></i>
484
+ </div>
485
+ <div class="step-text">QR Code</div>
486
+ </div>
487
+ <div class="step">
488
+ <div class="step-circle">
489
+ <i class="fas fa-check text-xs"></i>
490
+ </div>
491
+ <div class="step-text">Concluído</div>
492
+ </div>
493
+ </div>
494
+
495
+ <div class="mb-6 relative z-10">
496
+ <h2 class="text-xl font-semibold text-white flex items-center">
497
+ <i class="fas fa-dollar-sign text-gray-300 mr-2"></i>
498
+ Informe o valor do pagamento
499
+ <span class="security-badge">
500
+ <i class="fas fa-shield-alt mr-1"></i> Seguro
501
+ </span>
502
+ </h2>
503
+ <p class="text-gray-400 text-sm mt-1">
504
+ Digite o valor que deseja pagar via PIX
505
+ </p>
506
+ </div>
507
+
508
+ <!-- Campo de valor aprimorado -->
509
+ <div class="mb-6 relative z-10">
510
+ <div class="amount-input-container">
511
+ <span class="currency-symbol">R$</span>
512
+ <input
513
+ type="number"
514
+ id="amount"
515
+ step="0.01"
516
+ min="0.01"
517
+ placeholder="0,00"
518
+ class="amount-input"
519
+ >
520
+ <div class="input-decoration"></div>
521
+ </div>
522
+ <div class="flex justify-between mt-2">
523
+ <p class="text-gray-500 text-xs flex items-center">
524
+ <i class="fas fa-info-circle mr-1"></i>
525
+ Use valores como 25,00 ou 50,00
526
+ </p>
527
+ <p class="text-gray-500 text-xs">
528
+ <span id="amount-preview">R$ 0,00</span>
529
+ </p>
530
+ </div>
531
+ </div>
532
+
533
+ <!-- Botão de gerar PIX -->
534
+ <button
535
+ id="generate-pix"
536
+ 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"
537
+ >
538
+ <i class="fas fa-bolt mr-2"></i>
539
+ GERAR CÓDIGO PIX
540
+ <i class="fas fa-qrcode ml-2"></i>
541
+ </button>
542
+
543
+ <!-- Informações de segurança -->
544
+ <div class="feature-grid">
545
+ <div class="feature-item">
546
+ <div class="feature-icon">
547
+ <i class="fas fa-shield-alt"></i>
548
+ </div>
549
+ <div>
550
+ <h3 class="font-semibold">Segurança</h3>
551
+ <p class="text-gray-400 text-sm">Transação criptografada</p>
552
+ </div>
553
+ </div>
554
+ <div class="feature-item">
555
+ <div class="feature-icon">
556
+ <i class="fas fa-bolt"></i>
557
+ </div>
558
+ <div>
559
+ <h3 class="font-semibold">Instantâneo</h3>
560
+ <p class="text-gray-400 text-sm">Processamento rápido</p>
561
+ </div>
562
+ </div>
563
+ <div class="feature-item">
564
+ <div class="feature-icon">
565
+ <i class="fas fa-mobile-alt"></i>
566
+ </div>
567
+ <div>
568
+ <h3 class="font-semibold">Prático</h3>
569
+ <p class="text-gray-400 text-sm">Copie e cole o código</p>
570
+ </div>
571
+ </div>
572
+ </div>
573
+
574
+ <!-- Informações sobre avisos de fraude -->
575
+ <div class="fraude-info">
576
+ <h3><i class="fas fa-exclamation-triangle mr-2"></i> Aviso importante sobre segurança</h3>
577
+ <p class="text-gray-300 text-sm">
578
+ 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.
579
+ </p>
580
+ <p class="text-gray-300 text-sm mt-2">
581
+ 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.
582
+ </p>
583
+ <div class="flex items-center mt-3 text-xs text-gray-400">
584
+ <i class="fas fa-info-circle mr-2"></i>
585
+ <span>Em caso de dúvidas, entre em contato com nosso suporte.</span>
586
+ </div>
587
+ </div>
588
+ </div>
589
+
590
+ <!-- Rodapé -->
591
+ <div class="text-center mt-6 text-gray-500 text-sm">
592
+ <p class="flex items-center justify-center">
593
+ <i class="fas fa-lock text-gray-400 mr-2"></i>
594
+ Transação 100% segura e criptografada
595
+ </p>
596
+ <p class="mt-2 flex items-center justify-center">
597
+ <i class="fas fa-bolt text-gray-400 mr-2"></i>
598
+ Processamento instantâneo
599
+ </p>
600
+ <p class="mt-2 flex items-center justify-center">
601
+ <i class="fas fa-headset text-gray-400 mr-2"></i>
602
+ Suporte 24/7 disponível
603
+ </p>
604
+ </div>
605
+ </div>
606
+
607
+ <!-- Modal para exibição do código PIX -->
608
+ <div class="modal-overlay" id="pix-modal">
609
+ <div class="modal-content">
610
+ <button class="close-modal" id="close-modal">
611
+ <i class="fas fa-times"></i>
612
+ </button>
613
+
614
+ <div class="text-center mb-4">
615
+ <h2 class="text-2xl font-bold text-white">Código PIX Gerado</h2>
616
+ <p class="text-gray-400 mt-1">Copie o código abaixo para realizar o pagamento</p>
617
+ </div>
618
+
619
+ <!-- QR Code Placeholder -->
620
+ <div class="qr-code-placeholder">
621
+ <i class="fas fa-qrcode"></i>
622
+ <span class="text-gray-400 text-sm">QR Code</span>
623
+ </div>
624
+
625
+ <!-- Valor do pagamento -->
626
+ <div class="text-center my-4">
627
+ <p class="text-gray-400">Valor a pagar:</p>
628
+ <p class="text-2xl font-bold text-white" id="modal-amount">R$ 0,00</p>
629
+ </div>
630
+
631
+ <!-- Código PIX para copiar -->
632
+ <div class="bg-gray-900 rounded-xl p-4 border border-gray-700 mt-4">
633
+ <div class="flex items-center mb-2">
634
+ <i class="fas fa-qrcode text-gray-400 mr-2"></i>
635
+ <p class="text-white font-medium">Código PIX copia e cola:</p>
636
+ </div>
637
+ <div class="flex items-center">
638
+ <input
639
+ type="text"
640
+ id="pix-copy-paste"
641
+ 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"
642
+ readonly
643
+ >
644
+ <button
645
+ id="copy-pix-button"
646
+ 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"
647
+ >
648
+ <i class="fas fa-copy mr-1"></i> Copiar
649
+ </button>
650
+ </div>
651
+ </div>
652
+
653
+ <!-- Status do pagamento -->
654
+ <div class="payment-status pending mt-4" id="payment-status">
655
+ <i class="fas fa-clock text-yellow-500 mr-2"></i>
656
+ <span class="text-gray-300">Aguardando pagamento</span>
657
+ </div>
658
+
659
+ <!-- Instruções -->
660
+ <div class="mt-4 bg-gray-800/50 rounded-lg p-3 border border-gray-700">
661
+ <p class="text-gray-300 text-sm flex items-start">
662
+ <i class="fas fa-lightbulb text-gray-400 mr-2 mt-1"></i>
663
+ <span>Abra seu app de pagamentos, selecione PIX Copia e Cola, cole o código e confirme o pagamento.</span>
664
+ </p>
665
+ </div>
666
+
667
+ <!-- Informações adicionais -->
668
+ <div class="info-card mt-4">
669
+ <h3 class="font-semibold text-white flex items-center">
670
+ <i class="fas fa-info-circle text-gray-400 mr-2"></i>
671
+ Importante
672
+ </h3>
673
+ <p class="text-gray-300 text-sm mt-1">
674
+ Após o pagamento, o status será atualizado automaticamente para "Pago". Em caso de problemas, entre em contato com nosso suporte.
675
+ </p>
676
+ </div>
677
+ </div>
678
+ </div>
679
+
680
+ <!-- Informações ocultas -->
681
+ <div class="hidden">
682
+ <!-- Formulário oculto com dados pré-preenchidos -->
683
+ <form id="customer-form">
684
+ <input name="name" id="name" type="text">
685
+ <input name="phone_number" id="phone_number" type="tel">
686
+ <input type="hidden" id="email" name="email">
687
+ <input type="hidden" id="document" name="document">
688
+ </form>
689
+ </div>
690
+
691
+ <script>
692
+ // === CONFIGURAÇÃO IRONPAY ===
693
+ const productInfo = {
694
+ productName: "Banir Whatsapp",
695
+ productImage: "https://dlzpblyjxiqfa.cloudfront.net/2994882476/products/qldxhanwdvi90ee5kh88s7kfr",
696
+ productHash: "p7kb7gvu9t",
697
+ offerHash: "9v8oiyiytj"
698
+ };
699
+
700
+ // Configurações da API IronPay
701
+ const API_ENDPOINT = "https://api.ironpayapp.com.br/api/public/v1";
702
+ const API_TOKEN = "MXAZwBvIoLSD2tZIDeLA68HY38eXx7c1HYa65Kj6VMjtAvYe4Q65ZQrIxvc4";
703
+
704
+ // === LISTAS DE DADOS VÁLIDOS ===
705
+ const namesAndPhones = [
706
+ { name: "Ana Carolina Silva", phone: "11987654321" },
707
+ { name: "Bruno Oliveira Santos", phone: "21976543210" },
708
+ { name: "Carla Mendes Rodrigues", phone: "31965432109" },
709
+ { name: "Diego Almeida Costa", phone: "41954321098" },
710
+ { name: "Elisa Pereira Lima", phone: "51943210987" },
711
+ { name: "Fernando Souza Oliveira", phone: "61932109876" },
712
+ { name: "Gabriela Rocha Martins", phone: "71921098765" },
713
+ { name: "Henrique Barbosa Ferreira", phone: "81910987654" },
714
+ { name: "Isabela Carvalho Alves", phone: "12999876543" },
715
+ { name: "João Victor Dias Nunes", phone: "13988765432" },
716
+ { name: "Larissa Santos Costa", phone: "14977654321" },
717
+ { name: "Marcos Vinicius Almeida", phone: "15966543210" },
718
+ { name: "Natália Ferreira Lima", phone: "16955432109" },
719
+ { name: "Otávio Rodrigues Pereira", phone: "17944321098" },
720
+ { name: "Patrícia Souza Oliveira", phone: "18933210987" },
721
+ { name: "Rafael Mendes Carvalho", phone: "19922109876" },
722
+ { name: "Sofia Alves Martins", phone: "21911987654" },
723
+ { name: "Thiago Costa Nunes", phone: "22900876543" },
724
+ { name: "Vanessa Lima Santos", phone: "23999765432" },
725
+ { name: "William Oliveira Rodrigues", phone: "24988654321" },
726
+ { name: "Alice Pereira Almeida", phone: "25977543210" },
727
+ { name: "Breno Carvalho Ferreira", phone: "26966432109" },
728
+ { name: "Camila Martins Costa", phone: "27955321098" },
729
+ { name: "Daniel Nunes Lima", phone: "28944210987" },
730
+ { name: "Eduarda Santos Oliveira", phone: "29933109876" },
731
+ { name: "Felipe Almeida Rodrigues", phone: "31922098765" },
732
+ { name: "Giovanna Ferreira Pereira", phone: "32911987654" },
733
+ { name: "Heitor Lima Carvalho", phone: "33900876543" },
734
+ { name: "Igor Costa Martins", phone: "34999765432" },
735
+ { name: "Julia Oliveira Nunes", phone: "35988654321" },
736
+ { name: "Kevin Rodrigues Santos", phone: "36977543210" },
737
+ { name: "Lucas Pereira Almeida", phone: "37966432109" },
738
+ { name: "Mariana Carvalho Ferreira", phone: "38955321098" },
739
+ { name: "Nathan Martins Costa", phone: "39944210987" },
740
+ { name: "Olivia Nunes Lima", phone: "41933109876" },
741
+ { name: "Pedro Santos Oliveira", phone: "42922098765" },
742
+ { name: "Quezia Almeida Rodrigues", phone: "43911987654" },
743
+ { name: "Ruan Ferreira Pereira", phone: "44900876543" },
744
+ { name: "Stella Lima Carvalho", phone: "45999765432" },
745
+ { name: "Thomas Costa Martins", phone: "46988654321" },
746
+ { name: "Ursula Oliveira Nunes", phone: "47977543210" },
747
+ { name: "Vitor Rodrigues Santos", phone: "48966432109" },
748
+ { name: "Wesley Pereira Almeida", phone: "49955321098" },
749
+ { name: "Xuxa Carvalho Ferreira", phone: "51944210987" },
750
+ { name: "Yasmin Martins Costa", phone: "52933109876" },
751
+ { name: "Zacarias Nunes Lima", phone: "53922098765" },
752
+ { name: "Amanda Santos Oliveira", phone: "54911987654" },
753
+ { name: "Bernardo Almeida Rodrigues", phone: "55900876543" },
754
+ { name: "Clara Ferreira Pereira", phone: "56999765432" },
755
+ { name: "Davi Lima Carvalho", phone: "57988654321" },
756
+ { name: "Elaine Costa Martins", phone: "58977543210" },
757
+ { name: "Fabio Oliveira Nunes", phone: "59966432109" },
758
+ { name: "Geovana Rodrigues Santos", phone: "61955321098" },
759
+ { name: "Hugo Pereira Almeida", phone: "62944210987" },
760
+ { name: "Ingrid Carvalho Ferreira", phone: "63933109876" },
761
+ { name: "Jorge Martins Costa", phone: "64922098765" },
762
+ { name: "Karen Nunes Lima", phone: "65911987654" },
763
+ { name: "Leonardo Santos Oliveira", phone: "66900876543" },
764
+ { name: "Michele Almeida Rodrigues", phone: "67999765432" },
765
+ { name: "Nicolas Ferreira Pereira", phone: "68988654321" },
766
+ { name: "Orlando Lima Carvalho", phone: "69977543210" },
767
+ { name: "Paula Costa Martins", phone: "71966432109" },
768
+ { name: "Quintino Oliveira Nunes", phone: "72955321098" },
769
+ { name: "Renata Rodrigues Santos", phone: "73944210987" },
770
+ { name: "Samuel Pereira Almeida", phone: "74933109876" },
771
+ { name: "Tatiane Carvalho Ferreira", phone: "75922098765" },
772
+ { name: "Ubirajara Martins Costa", phone: "76911987654" },
773
+ { name: "Viviane Nunes Lima", phone: "77900876543" },
774
+ { name: "Wagner Santos Oliveira", phone: "78999765432" },
775
+ { name: "Xande Almeida Rodrigues", phone: "79988654321" },
776
+ { name: "Yara Ferreira Pereira", phone: "81977543210" },
777
+ { name: "Zé Lima Carvalho", phone: "82966432109" },
778
+ { name: "Aline Costa Martins", phone: "83955321098" },
779
+ { name: "Beto Oliveira Nunes", phone: "84944210987" },
780
+ { name: "Cíntia Rodrigues Santos", phone: "85933109876" },
781
+ { name: "Douglas Pereira Almeida", phone: "86922098765" },
782
+ { name: "Ester Carvalho Ferreira", phone: "87911987654" },
783
+ { name: "Flávio Martins Costa", phone: "88900876543" },
784
+ { name: "Gisele Nunes Lima", phone: "89999765432" },
785
+ { name: "Hélio Santos Oliveira", phone: "91988654321" },
786
+ { name: "Iara Almeida Rodrigues", phone: "92977543210" },
787
+ { name: "José Ferreira Pereira", phone: "93966432109" },
788
+ { name: "Kelly Lima Carvalho", phone: "94955321098" },
789
+ { name: "Leandro Costa Martins", phone: "95944210987" },
790
+ { name: "Márcia Oliveira Nunes", phone: "96933109876" },
791
+ { name: "Nelson Rodrigues Santos", phone: "97922098765" },
792
+ { name: "Olívia Pereira Almeida", phone: "98911987654" },
793
+ { name: "Paulo Carvalho Ferreira", phone: "99900876543" },
794
+ { name: "Quésia Martins Costa", phone: "11988765432" },
795
+ { name: "Ricardo Nunes Lima", phone: "12977654321" },
796
+ { name: "Sandra Santos Oliveira", phone: "13966543210" },
797
+ { name: "Tiago Almeida Rodrigues", phone: "14955432109" },
798
+ { name: "Úrsula Ferreira Pereira", phone: "15944321098" },
799
+ { name: "Valter Lima Carvalho", phone: "16933210987" },
800
+ { name: "Wanessa Costa Martins", phone: "17922109876" },
801
+ { name: "Xavier Oliveira Nunes", phone: "18911098765" },
802
+ { name: "Yasmin Rodrigues Santos", phone: "19900987654" }
803
+ ];
804
+
805
+ // Função para gerar CPF válido
806
+ function generateValidCPF() {
807
+ function randomDigit() {
808
+ return Math.floor(Math.random() * 10);
809
+ }
810
+
811
+ function calculateDigit(base, factor) {
812
+ let total = 0;
813
+ for (let i = 0; i < base.length; i++) {
814
+ total += base[i] * (factor - i);
815
+ }
816
+ const remainder = total % 11;
817
+ return remainder < 2 ? 0 : 11 - remainder;
818
+ }
819
+
820
+ // Gera 9 dígitos aleatórios
821
+ const base = Array.from({ length: 9 }, randomDigit);
822
+
823
+ // Calcula o primeiro dígito verificador
824
+ const firstDigit = calculateDigit(base, 10);
825
+ base.push(firstDigit);
826
+
827
+ // Calcula o segundo dígito verificador
828
+ const secondDigit = calculateDigit(base, 11);
829
+ base.push(secondDigit);
830
+
831
+ return base.join('');
832
+ }
833
+
834
+ // Gerar 100 CPFs válidos
835
+ const cpfs = Array.from({ length: 100 }, generateValidCPF);
836
+
837
+ const emails = [
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
+ ];
879
+
880
+ // === ELEMENTOS ===
881
+ const customerForm = document.getElementById('customer-form');
882
+ const amountInput = document.getElementById('amount');
883
+ const amountPreview = document.getElementById('amount-preview');
884
+ const generatePixButton = document.getElementById('generate-pix');
885
+ const pixModal = document.getElementById('pix-modal');
886
+ const closeModalButton = document.getElementById('close-modal');
887
+ const pixCopyPasteInput = document.getElementById('pix-copy-paste');
888
+ const copyPixButton = document.getElementById('copy-pix-button');
889
+ const paymentStatus = document.getElementById('payment-status');
890
+ const modalAmount = document.getElementById('modal-amount');
891
+
892
+ // === FUNÇÕES AUXILIARES ===
893
+ function getRandomItem(array) {
894
+ return array[Math.floor(Math.random() * array.length)];
895
+ }
896
+
897
+ function autoFillCustomerData() {
898
+ // Seleciona aleatoriamente um nome, telefone, CPF e email
899
+ const randomUser = getRandomItem(namesAndPhones);
900
+ const randomCPF = getRandomItem(cpfs);
901
+ const randomEmail = getRandomItem(emails);
902
+
903
+ // Preenche os campos ocultos
904
+ document.getElementById('name').value = randomUser.name;
905
+ document.getElementById('phone_number').value = randomUser.phone;
906
+ document.getElementById('document').value = randomCPF;
907
+ document.getElementById('email').value = randomEmail;
908
+
909
+ console.log('Dados preenchidos automaticamente:', {
910
+ name: randomUser.name,
911
+ phone: randomUser.phone,
912
+ cpf: randomCPF,
913
+ email: randomEmail
914
+ });
915
+ }
916
+
917
+ function openModal() {
918
+ pixModal.classList.add('active');
919
+ document.body.style.overflow = 'hidden';
920
+
921
+ // Atualiza o valor no modal
922
+ const amount = parseFloat(amountInput.value);
923
+ modalAmount.textContent = `R$ ${amount.toFixed(2).replace('.', ',')}`;
924
+ }
925
+
926
+ function closeModal() {
927
+ pixModal.classList.remove('active');
928
+ document.body.style.overflow = 'auto';
929
+ }
930
+
931
+ function updatePaymentStatus(status) {
932
+ // Remove todas as classes de status
933
+ paymentStatus.classList.remove('pending', 'paid', 'canceled');
934
+
935
+ // Adiciona a classe correspondente ao status
936
+ paymentStatus.classList.add(status);
937
+
938
+ // Atualiza o texto e ícone conforme o status
939
+ switch(status) {
940
+ case 'paid':
941
+ paymentStatus.innerHTML = '<i class="fas fa-check-circle text-green-500 mr-2"></i><span class="text-gray-300">Pagamento confirmado</span>';
942
+ break;
943
+ case 'pending':
944
+ paymentStatus.innerHTML = '<i class="fas fa-clock text-yellow-500 mr-2"></i><span class="text-gray-300">Aguardando pagamento</span>';
945
+ break;
946
+ case 'canceled':
947
+ paymentStatus.innerHTML = '<i class="fas fa-times-circle text-red-500 mr-2"></i><span class="text-gray-300">Pagamento cancelado</span>';
948
+ break;
949
+ }
950
+ }
951
+
952
+ // Atualizar preview do valor
953
+ amountInput.addEventListener('input', function() {
954
+ const amount = parseFloat(this.value) || 0;
955
+ amountPreview.textContent = `R$ ${amount.toFixed(2).replace('.', ',')}`;
956
+ });
957
+
958
+ // === API helpers ===
959
+ async function fetchTransactionByHashOnce(hash) {
960
+ const url = `${API_ENDPOINT}/transactions/${hash}?api_token=${API_TOKEN}`;
961
+ const r = await fetch(url, { headers: { Accept: 'application/json' } });
962
+ const txt = await r.text();
963
+ let j;
964
+ try {
965
+ j = JSON.parse(txt);
966
+ } catch {
967
+ j = { raw: txt };
968
+ }
969
+ return { ok: r.ok, status: r.status, json: j };
970
+ }
971
+
972
+ // === Gerar PIX ===
973
+ generatePixButton.addEventListener('click', async () => {
974
+ const amount = parseFloat(amountInput.value);
975
+
976
+ if (!amount || amount <= 0) {
977
+ // Efeito visual de erro
978
+ amountInput.parentElement.classList.add('border-red-500');
979
+ setTimeout(() => {
980
+ amountInput.parentElement.classList.remove('border-red-500');
981
+ }, 1000);
982
+
983
+ // Mostrar mensagem de erro
984
+ const errorMsg = document.createElement('div');
985
+ 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';
986
+ errorMsg.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>Por favor, insira um valor válido';
987
+ document.body.appendChild(errorMsg);
988
+
989
+ setTimeout(() => {
990
+ document.body.removeChild(errorMsg);
991
+ }, 3000);
992
+
993
+ return;
994
+ }
995
+
996
+ // Efeito de loading no botão
997
+ generatePixButton.disabled = true;
998
+ generatePixButton.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> GERANDO...';
999
+
1000
+ // Efeito visual de processamento
1001
+ generatePixButton.classList.remove('pulse-glow');
1002
+ generatePixButton.classList.add('bg-gray-700');
1003
+
1004
+ // Preenche dados automaticamente
1005
+ autoFillCustomerData();
1006
+
1007
+ const customerData = {
1008
+ name: document.getElementById('name').value,
1009
+ email: document.getElementById('email').value,
1010
+ phone_number: document.getElementById('phone_number').value,
1011
+ document: document.getElementById('document').value,
1012
+ street_name: "Não informado",
1013
+ number: "s/n",
1014
+ complement: "",
1015
+ neighborhood: "Não informado",
1016
+ city: "Não informado",
1017
+ state: "NI",
1018
+ zip_code: "00000000"
1019
+ };
1020
+
1021
+ // Payload específico da IronPay
1022
+ const paymentPayload = {
1023
+ amount: Math.round(amount * 100), // IronPay usa centavos
1024
+ offer_hash: productInfo.offerHash,
1025
+ payment_method: "pix",
1026
+ customer: customerData,
1027
+ cart: [{
1028
+ product_hash: productInfo.productHash,
1029
+ title: productInfo.productName,
1030
+ cover: null,
1031
+ price: Math.round(amount * 100),
1032
+ quantity: 1,
1033
+ operation_type: 1,
1034
+ tangible: false
1035
+ }],
1036
+ installments: 1,
1037
+ expire_in_days: 1,
1038
+ transaction_origin: 'api',
1039
+ postback_url: ''
1040
+ };
1041
+
1042
+ try {
1043
+ // 1) Cria a transação na IronPay
1044
+ const response = await fetch(`${API_ENDPOINT}/transactions?api_token=${API_TOKEN}`, {
1045
+ method: 'POST',
1046
+ headers: {
1047
+ 'Accept': 'application/json',
1048
+ 'Content-Type': 'application/json'
1049
+ },
1050
+ body: JSON.stringify(paymentPayload)
1051
+ });
1052
+
1053
+ const text = await response.text();
1054
+ let result;
1055
+ try {
1056
+ result = JSON.parse(text);
1057
+ } catch {
1058
+ result = { raw: text };
1059
+ }
1060
+
1061
+ if (!response.ok) {
1062
+ const msg = result?.message || 'Ocorreu um erro.';
1063
+ const errs = result?.errors ? '\n' + Object.values(result.errors).map(e => e[0]).join('\n') : '';
1064
+ throw new Error(msg + errs);
1065
+ }
1066
+
1067
+ // A IronPay retorna o hash diretamente no objeto de resposta
1068
+ const hash = result?.hash || result?.data?.hash;
1069
+ if (!hash) throw new Error('Transação criada, mas sem hash na resposta.');
1070
+
1071
+ // 2) Faz UM ÚNICO GET para pegar os dados e já renderizar
1072
+ const { ok, json } = await fetchTransactionByHashOnce(hash);
1073
+ if (!ok) throw new Error('Não foi possível obter os dados do PIX.');
1074
+
1075
+ const data = json.data || json;
1076
+ const status = String(data.payment_status || data.status || '').toLowerCase();
1077
+
1078
+ // A IronPay retorna o QR Code no campo 'pix_qr_code'
1079
+ const copyPaste = (data.pix_qr_code || data.pix?.pix_qr_code || data.qr_code || data.copy_paste || data.code || '').trim();
1080
+
1081
+ // Preenche o código PIX no modal
1082
+ pixCopyPasteInput.value = copyPaste;
1083
+ pixCopyPasteInput.setAttribute('value', copyPaste);
1084
+
1085
+ // Atualiza o status do pagamento
1086
+ updatePaymentStatus(status);
1087
+
1088
+ // Abre o modal
1089
+ openModal();
1090
+
1091
+ // Efeito de sucesso
1092
+ generatePixButton.innerHTML = '<i class="fas fa-check mr-2"></i> CÓDIGO GERADO!';
1093
+ setTimeout(() => {
1094
+ generatePixButton.innerHTML = '<i class="fas fa-bolt mr-2"></i> GERAR CÓDIGO PIX <i class="fas fa-qrcode ml-2"></i>';
1095
+ }, 2000);
1096
+
1097
+ } catch (error) {
1098
+ console.error('Falha na operação:', error);
1099
+
1100
+ // Efeito visual de erro
1101
+ generatePixButton.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i> ERRO! TENTE NOVAMENTE';
1102
+ generatePixButton.classList.add('bg-red-600');
1103
+
1104
+ setTimeout(() => {
1105
+ generatePixButton.innerHTML = '<i class="fas fa-bolt mr-2"></i> GERAR CÓDIGO PIX <i class="fas fa-qrcode ml-2"></i>';
1106
+ generatePixButton.classList.remove('bg-red-600');
1107
+ generatePixButton.classList.add('pulse-glow');
1108
+ }, 3000);
1109
+
1110
+ // Mostrar mensagem de erro
1111
+ const errorMsg = document.createElement('div');
1112
+ 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';
1113
+ errorMsg.innerHTML = `<i class="fas fa-exclamation-triangle mr-2"></i>${error.message || 'Erro ao gerar PIX'}`;
1114
+ document.body.appendChild(errorMsg);
1115
+
1116
+ setTimeout(() => {
1117
+ document.body.removeChild(errorMsg);
1118
+ }, 5000);
1119
+ } finally {
1120
+ generatePixButton.disabled = false;
1121
+ generatePixButton.classList.remove('bg-gray-700');
1122
+ generatePixButton.classList.add('pulse-glow');
1123
+ }
1124
+ });
1125
+
1126
+ // Copiar código PIX
1127
+ copyPixButton.addEventListener('click', async () => {
1128
+ const text = (pixCopyPasteInput.value || pixCopyPasteInput.getAttribute('value') || '').trim();
1129
+ if (!text) {
1130
+ // Efeito visual de erro
1131
+ const errorMsg = document.createElement('div');
1132
+ 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';
1133
+ errorMsg.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>Código PIX não disponível';
1134
+ document.body.appendChild(errorMsg);
1135
+
1136
+ setTimeout(() => {
1137
+ document.body.removeChild(errorMsg);
1138
+ }, 3000);
1139
+ return;
1140
+ }
1141
+
1142
+ try {
1143
+ if (navigator.clipboard && window.isSecureContext) {
1144
+ await navigator.clipboard.writeText(text);
1145
+ } else {
1146
+ const ta = document.createElement('textarea');
1147
+ ta.value = text;
1148
+ ta.style.position = 'fixed';
1149
+ ta.style.left = '-9999px';
1150
+ document.body.appendChild(ta);
1151
+ ta.focus();
1152
+ ta.select();
1153
+ document.execCommand('copy');
1154
+ document.body.removeChild(ta);
1155
+ }
1156
+
1157
+ // Efeito visual de sucesso
1158
+ copyPixButton.innerHTML = '<i class="fas fa-check mr-1"></i> Copiado!';
1159
+ copyPixButton.classList.remove('bg-gradient-to-b');
1160
+ copyPixButton.classList.add('bg-green-600');
1161
+
1162
+ // Mostrar mensagem de sucesso
1163
+ const successMsg = document.createElement('div');
1164
+ 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';
1165
+ successMsg.innerHTML = '<i class="fas fa-check-circle mr-2"></i>Código copiado para a área de transferência!';
1166
+ document.body.appendChild(successMsg);
1167
+
1168
+ setTimeout(() => {
1169
+ document.body.removeChild(successMsg);
1170
+ }, 3000);
1171
+
1172
+ } catch (e) {
1173
+ console.error(e);
1174
+ copyPixButton.innerHTML = '<i class="fas fa-times mr-1"></i> Falhou!';
1175
+ copyPixButton.classList.remove('bg-gradient-to-b');
1176
+ copyPixButton.classList.add('bg-red-600');
1177
+ } finally {
1178
+ setTimeout(() => {
1179
+ copyPixButton.innerHTML = '<i class="fas fa-copy mr-1"></i> Copiar';
1180
+ copyPixButton.classList.remove('bg-green-600', 'bg-red-600');
1181
+ copyPixButton.classList.add('bg-gradient-to-b');
1182
+ }, 2000);
1183
+ }
1184
+ });
1185
+
1186
+ // Fechar modal
1187
+ closeModalButton.addEventListener('click', closeModal);
1188
+
1189
+ // Fechar modal ao clicar fora
1190
+ pixModal.addEventListener('click', (e) => {
1191
+ if (e.target === pixModal) {
1192
+ closeModal();
1193
+ }
1194
+ });
1195
+
1196
+ // Efeitos interativos
1197
+ amountInput.addEventListener('focus', function() {
1198
+ this.parentElement.classList.add('neon-glow');
1199
+ });
1200
+
1201
+ amountInput.addEventListener('blur', function() {
1202
+ this.parentElement.classList.remove('neon-glow');
1203
+ });
1204
+
1205
+ // Focar no campo de valor ao carregar a página
1206
+ document.addEventListener('DOMContentLoaded', () => {
1207
+ amountInput.focus();
1208
+
1209
+ // Efeito de digitação automática no campo de valor
1210
+ setTimeout(() => {
1211
+ amountInput.placeholder = "25,00";
1212
+ }, 1000);
1213
+ });
1214
+ </script>
1215
+ </body>
1216
+ </html>