@paynext/sdk 0.0.166 → 0.0.167
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checkout.html +244 -0
- package/package.json +1 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>PayNext Checkout - Iframe Mode</title>
|
|
7
|
+
|
|
8
|
+
<!-- Security headers -->
|
|
9
|
+
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
|
10
|
+
<meta http-equiv="X-Frame-Options" content="ALLOW-FROM *">
|
|
11
|
+
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
|
|
12
|
+
|
|
13
|
+
<!-- CSP for iframe -->
|
|
14
|
+
<meta http-equiv="Content-Security-Policy"
|
|
15
|
+
content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src *; frame-ancestors *;">
|
|
16
|
+
|
|
17
|
+
<style>
|
|
18
|
+
* {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
html, body {
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 100%;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
body {
|
|
31
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#checkout-container {
|
|
35
|
+
width: 100%;
|
|
36
|
+
min-height: 100%;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Loading state */
|
|
40
|
+
.loading {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
justify-content: center;
|
|
44
|
+
min-height: 400px;
|
|
45
|
+
color: #666;
|
|
46
|
+
font-size: 14px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.loading::after {
|
|
50
|
+
content: '...';
|
|
51
|
+
animation: dots 1.5s steps(4, end) infinite;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@keyframes dots {
|
|
55
|
+
0%, 20% { content: '.'; }
|
|
56
|
+
40% { content: '..'; }
|
|
57
|
+
60%, 100% { content: '...'; }
|
|
58
|
+
}
|
|
59
|
+
</style>
|
|
60
|
+
</head>
|
|
61
|
+
<body>
|
|
62
|
+
<div id="checkout-container">
|
|
63
|
+
<div class="loading">Loading checkout</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<script type="module">
|
|
67
|
+
// Message types for parent communication
|
|
68
|
+
const MessageType = {
|
|
69
|
+
INIT: 'paynext:init',
|
|
70
|
+
MOUNT: 'paynext:mount',
|
|
71
|
+
UNMOUNT: 'paynext:unmount',
|
|
72
|
+
UPDATE_CONFIG: 'paynext:updateConfig',
|
|
73
|
+
READY: 'paynext:ready',
|
|
74
|
+
LOADED: 'paynext:loaded',
|
|
75
|
+
ATTEMPT: 'paynext:attempt',
|
|
76
|
+
COMPLETE: 'paynext:complete',
|
|
77
|
+
FAIL: 'paynext:fail',
|
|
78
|
+
ERROR: 'paynext:error',
|
|
79
|
+
RESIZE: 'paynext:resize'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let checkout = null
|
|
83
|
+
let parentOrigin = null
|
|
84
|
+
let config = null
|
|
85
|
+
|
|
86
|
+
// Send message to parent
|
|
87
|
+
function sendToParent(type, payload, requestId) {
|
|
88
|
+
if (!parentOrigin) {
|
|
89
|
+
console.error('[Iframe] Parent origin not set')
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
window.parent.postMessage(
|
|
94
|
+
{ type, payload, requestId },
|
|
95
|
+
parentOrigin
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Handle messages from parent
|
|
100
|
+
window.addEventListener('message', async (event) => {
|
|
101
|
+
const data = event.data
|
|
102
|
+
|
|
103
|
+
// Store parent origin on first message
|
|
104
|
+
if (!parentOrigin) {
|
|
105
|
+
parentOrigin = event.origin
|
|
106
|
+
console.log('[Iframe] Parent origin set to:', parentOrigin)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Validate origin
|
|
110
|
+
if (event.origin !== parentOrigin) {
|
|
111
|
+
console.warn('[Iframe] Message from unauthorized origin:', event.origin)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!data.type || !data.type.startsWith('paynext:')) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
switch (data.type) {
|
|
121
|
+
case MessageType.MOUNT:
|
|
122
|
+
console.log('[Iframe] Mount request received')
|
|
123
|
+
|
|
124
|
+
if (data.payload?.config) {
|
|
125
|
+
config = data.payload.config
|
|
126
|
+
|
|
127
|
+
// Import and initialize SDK
|
|
128
|
+
const { PayNextCheckout } = await import('./index.cdn.js')
|
|
129
|
+
|
|
130
|
+
checkout = new PayNextCheckout()
|
|
131
|
+
|
|
132
|
+
// Mount checkout
|
|
133
|
+
await checkout.mount('checkout-container', {
|
|
134
|
+
...config,
|
|
135
|
+
// Override callbacks to send messages to parent
|
|
136
|
+
onCheckoutLoaded: (result) => {
|
|
137
|
+
sendToParent(MessageType.LOADED, result, data.requestId)
|
|
138
|
+
notifyResize()
|
|
139
|
+
},
|
|
140
|
+
onCheckoutAttempt: (result) => {
|
|
141
|
+
sendToParent(MessageType.ATTEMPT, result)
|
|
142
|
+
},
|
|
143
|
+
onCheckoutComplete: (result) => {
|
|
144
|
+
sendToParent(MessageType.COMPLETE, result)
|
|
145
|
+
},
|
|
146
|
+
onCheckoutFail: (error) => {
|
|
147
|
+
sendToParent(MessageType.FAIL, error)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
// Send success response
|
|
152
|
+
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
153
|
+
|
|
154
|
+
// Setup resize observer
|
|
155
|
+
setupResizeObserver()
|
|
156
|
+
}
|
|
157
|
+
break
|
|
158
|
+
|
|
159
|
+
case MessageType.UNMOUNT:
|
|
160
|
+
console.log('[Iframe] Unmount request received')
|
|
161
|
+
|
|
162
|
+
if (checkout) {
|
|
163
|
+
await checkout.unmount()
|
|
164
|
+
checkout = null
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
168
|
+
break
|
|
169
|
+
|
|
170
|
+
case MessageType.UPDATE_CONFIG:
|
|
171
|
+
console.log('[Iframe] Update config request received')
|
|
172
|
+
|
|
173
|
+
if (checkout && data.payload?.config) {
|
|
174
|
+
await checkout.updateConfig(data.payload.config)
|
|
175
|
+
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
176
|
+
}
|
|
177
|
+
break
|
|
178
|
+
|
|
179
|
+
default:
|
|
180
|
+
console.warn('[Iframe] Unknown message type:', data.type)
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('[Iframe] Error handling message:', error)
|
|
184
|
+
sendToParent(MessageType.ERROR, {
|
|
185
|
+
message: error.message,
|
|
186
|
+
stack: error.stack
|
|
187
|
+
}, data.requestId)
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
// Setup resize observer to notify parent of height changes
|
|
192
|
+
function setupResizeObserver() {
|
|
193
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
194
|
+
for (const entry of entries) {
|
|
195
|
+
const height = entry.contentRect.height
|
|
196
|
+
sendToParent(MessageType.RESIZE, { height })
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
resizeObserver.observe(document.body)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Notify parent of current height
|
|
204
|
+
function notifyResize() {
|
|
205
|
+
const height = document.body.scrollHeight
|
|
206
|
+
sendToParent(MessageType.RESIZE, { height })
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Send ready message when iframe loads
|
|
210
|
+
window.addEventListener('load', () => {
|
|
211
|
+
console.log('[Iframe] Iframe loaded and ready')
|
|
212
|
+
|
|
213
|
+
// Wait a bit for parent to setup message listener
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
// Send ready to any origin initially
|
|
216
|
+
window.parent.postMessage(
|
|
217
|
+
{ type: MessageType.READY, payload: { success: true } },
|
|
218
|
+
'*'
|
|
219
|
+
)
|
|
220
|
+
}, 100)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
// Log errors
|
|
224
|
+
window.addEventListener('error', (event) => {
|
|
225
|
+
console.error('[Iframe] Runtime error:', event.error)
|
|
226
|
+
sendToParent(MessageType.ERROR, {
|
|
227
|
+
message: event.error?.message || 'Unknown error',
|
|
228
|
+
stack: event.error?.stack
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
233
|
+
console.error('[Iframe] Unhandled promise rejection:', event.reason)
|
|
234
|
+
sendToParent(MessageType.ERROR, {
|
|
235
|
+
message: event.reason?.message || 'Unhandled promise rejection',
|
|
236
|
+
stack: event.reason?.stack
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
console.log('[Iframe] PayNext Checkout iframe initialized')
|
|
241
|
+
</script>
|
|
242
|
+
</body>
|
|
243
|
+
</html>
|
|
244
|
+
|