canvasframework 0.4.4 → 0.4.5
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/components/QRCodeReader.js +2 -2
- package/components/TimePicker.js +2 -2
- package/index.js +10 -1
- package/package.json +1 -1
- package/utils/FirebaseAuth.js +653 -0
- package/utils/FirebaseCore.js +246 -0
- package/utils/FirebaseFirestore.js +581 -0
- package/utils/FirebaseFunctions.js +97 -0
- package/utils/FirebaseRealtimeDB.js +498 -0
- package/utils/FirebaseStorage.js +612 -0
- package/utils/PayPalPayment.js +678 -0
- package/utils/StripePayment.js +552 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StripePayment - Utilitaire pour gérer les paiements Stripe dans Canvas
|
|
3
|
+
* Version avec création/suppression automatique des éléments DOM
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const stripe = new StripePayment('pk_test_xxxxx', {
|
|
7
|
+
* canvasContainer: canvasElement,
|
|
8
|
+
* onElementReady: (element) => { /* afficher dans canvas *\/ }
|
|
9
|
+
* });
|
|
10
|
+
*/
|
|
11
|
+
class StripePayment {
|
|
12
|
+
constructor(publishableKey, options = {}) {
|
|
13
|
+
this.publishableKey = publishableKey;
|
|
14
|
+
this.stripe = null;
|
|
15
|
+
this.elements = null;
|
|
16
|
+
this.cardElement = null;
|
|
17
|
+
|
|
18
|
+
// Options spécifiques Canvas
|
|
19
|
+
this.canvasContainer = options.canvasContainer || null;
|
|
20
|
+
this.canvasContext = options.canvasContext || null;
|
|
21
|
+
this.onElementReady = options.onElementReady || null;
|
|
22
|
+
this.onErrorDisplay = options.onErrorDisplay || null;
|
|
23
|
+
|
|
24
|
+
// Options Stripe
|
|
25
|
+
this.locale = options.locale || 'fr';
|
|
26
|
+
this.appearance = options.appearance || {
|
|
27
|
+
theme: 'stripe',
|
|
28
|
+
variables: {
|
|
29
|
+
colorPrimary: '#0570de',
|
|
30
|
+
colorBackground: '#ffffff',
|
|
31
|
+
colorText: '#30313d',
|
|
32
|
+
colorDanger: '#df1b41',
|
|
33
|
+
fontFamily: 'system-ui, sans-serif',
|
|
34
|
+
spacingUnit: '4px',
|
|
35
|
+
borderRadius: '8px'
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
this.onPaymentSuccess = options.onPaymentSuccess || null;
|
|
40
|
+
this.onPaymentError = options.onPaymentError || null;
|
|
41
|
+
this.onPaymentProcessing = options.onPaymentProcessing || null;
|
|
42
|
+
|
|
43
|
+
// Stockage des éléments DOM temporaires
|
|
44
|
+
this.temporaryElements = {
|
|
45
|
+
script: null,
|
|
46
|
+
container: null,
|
|
47
|
+
iframeContainer: null
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
this.isInitialized = false;
|
|
51
|
+
this.isProcessing = false;
|
|
52
|
+
this.paymentFormData = {
|
|
53
|
+
cardNumber: '',
|
|
54
|
+
expiry: '',
|
|
55
|
+
cvc: '',
|
|
56
|
+
postalCode: ''
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Créer un élément DOM temporaire
|
|
62
|
+
*/
|
|
63
|
+
createTemporaryElement(tagName, attributes = {}, parent = document.body) {
|
|
64
|
+
if (typeof document === 'undefined') {
|
|
65
|
+
throw new Error('DOM non disponible');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const element = document.createElement(tagName);
|
|
69
|
+
|
|
70
|
+
// Appliquer les attributs
|
|
71
|
+
Object.keys(attributes).forEach(key => {
|
|
72
|
+
if (key === 'style' && typeof attributes[key] === 'object') {
|
|
73
|
+
Object.assign(element.style, attributes[key]);
|
|
74
|
+
} else if (key === 'textContent') {
|
|
75
|
+
element.textContent = attributes[key];
|
|
76
|
+
} else if (key === 'innerHTML') {
|
|
77
|
+
element.innerHTML = attributes[key];
|
|
78
|
+
} else {
|
|
79
|
+
element.setAttribute(key, attributes[key]);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Ajouter au parent
|
|
84
|
+
if (parent) {
|
|
85
|
+
parent.appendChild(element);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return element;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Supprimer un élément DOM temporaire
|
|
93
|
+
*/
|
|
94
|
+
removeTemporaryElement(element) {
|
|
95
|
+
if (element && element.parentNode) {
|
|
96
|
+
element.parentNode.removeChild(element);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Nettoyer tous les éléments DOM temporaires
|
|
102
|
+
*/
|
|
103
|
+
cleanupTemporaryElements() {
|
|
104
|
+
Object.keys(this.temporaryElements).forEach(key => {
|
|
105
|
+
if (this.temporaryElements[key]) {
|
|
106
|
+
this.removeTemporaryElement(this.temporaryElements[key]);
|
|
107
|
+
this.temporaryElements[key] = null;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Initialiser Stripe.js avec gestion automatique du script
|
|
114
|
+
*/
|
|
115
|
+
async initialize() {
|
|
116
|
+
if (this.isInitialized) return;
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
// Charger Stripe.js dynamiquement
|
|
120
|
+
await this.loadStripeScript();
|
|
121
|
+
|
|
122
|
+
// Initialiser Stripe
|
|
123
|
+
this.stripe = window.Stripe(this.publishableKey, {
|
|
124
|
+
locale: this.locale,
|
|
125
|
+
betas: ['elements_enable_deferred_intent_beta_1']
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.isInitialized = true;
|
|
129
|
+
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('❌ Erreur initialisation Stripe:', error);
|
|
132
|
+
this.cleanupTemporaryElements();
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Charger Stripe.js avec création/suppression automatique du script
|
|
139
|
+
*/
|
|
140
|
+
loadStripeScript() {
|
|
141
|
+
return new Promise((resolve, reject) => {
|
|
142
|
+
// Vérifier si Stripe est déjà chargé
|
|
143
|
+
if (typeof window.Stripe !== 'undefined') {
|
|
144
|
+
resolve();
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Vérifier si un script existe déjà
|
|
149
|
+
const existingScript = document.querySelector('script[src="https://js.stripe.com/v3/"]');
|
|
150
|
+
if (existingScript) {
|
|
151
|
+
// Utiliser le script existant
|
|
152
|
+
this.temporaryElements.script = existingScript;
|
|
153
|
+
resolve();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Créer un nouveau script
|
|
158
|
+
try {
|
|
159
|
+
this.temporaryElements.script = this.createTemporaryElement('script', {
|
|
160
|
+
src: 'https://js.stripe.com/v3/',
|
|
161
|
+
async: true,
|
|
162
|
+
onload: () => {
|
|
163
|
+
if (typeof window.Stripe === 'undefined') {
|
|
164
|
+
reject(new Error('Stripe.js chargé mais non défini'));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
resolve();
|
|
168
|
+
},
|
|
169
|
+
onerror: () => {
|
|
170
|
+
reject(new Error('Échec du chargement de Stripe.js'));
|
|
171
|
+
this.cleanupTemporaryElements();
|
|
172
|
+
}
|
|
173
|
+
}, document.head);
|
|
174
|
+
|
|
175
|
+
} catch (error) {
|
|
176
|
+
reject(error);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Créer un conteneur temporaire pour les éléments de paiement
|
|
183
|
+
*/
|
|
184
|
+
createTemporaryContainer(options = {}) {
|
|
185
|
+
if (!this.temporaryElements.container) {
|
|
186
|
+
this.temporaryElements.container = this.createTemporaryElement('div', {
|
|
187
|
+
id: 'stripe-payment-container-' + Date.now(),
|
|
188
|
+
style: {
|
|
189
|
+
position: 'fixed',
|
|
190
|
+
top: '0',
|
|
191
|
+
left: '0',
|
|
192
|
+
width: '100%',
|
|
193
|
+
height: '100%',
|
|
194
|
+
zIndex: '9999',
|
|
195
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
196
|
+
display: 'flex',
|
|
197
|
+
justifyContent: 'center',
|
|
198
|
+
alignItems: 'center'
|
|
199
|
+
}
|
|
200
|
+
}, document.body);
|
|
201
|
+
|
|
202
|
+
// Ajouter un bouton de fermeture
|
|
203
|
+
const closeButton = this.createTemporaryElement('button', {
|
|
204
|
+
style: {
|
|
205
|
+
position: 'absolute',
|
|
206
|
+
top: '20px',
|
|
207
|
+
right: '20px',
|
|
208
|
+
background: 'none',
|
|
209
|
+
border: 'none',
|
|
210
|
+
fontSize: '24px',
|
|
211
|
+
color: '#fff',
|
|
212
|
+
cursor: 'pointer',
|
|
213
|
+
zIndex: '10000'
|
|
214
|
+
},
|
|
215
|
+
textContent: '×',
|
|
216
|
+
onclick: () => this.destroyTemporaryContainer()
|
|
217
|
+
}, this.temporaryElements.container);
|
|
218
|
+
|
|
219
|
+
// Ajouter un conteneur pour le formulaire
|
|
220
|
+
const formContainer = this.createTemporaryElement('div', {
|
|
221
|
+
style: {
|
|
222
|
+
backgroundColor: '#fff',
|
|
223
|
+
padding: '30px',
|
|
224
|
+
borderRadius: '12px',
|
|
225
|
+
width: '400px',
|
|
226
|
+
maxWidth: '90%',
|
|
227
|
+
maxHeight: '90%',
|
|
228
|
+
overflow: 'auto',
|
|
229
|
+
position: 'relative'
|
|
230
|
+
}
|
|
231
|
+
}, this.temporaryElements.container);
|
|
232
|
+
|
|
233
|
+
// Retourner l'ID du conteneur pour Stripe Elements
|
|
234
|
+
return formContainer;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return this.temporaryElements.container;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Détruire le conteneur temporaire
|
|
242
|
+
*/
|
|
243
|
+
destroyTemporaryContainer() {
|
|
244
|
+
if (this.temporaryElements.container) {
|
|
245
|
+
this.removeTemporaryElement(this.temporaryElements.container);
|
|
246
|
+
this.temporaryElements.container = null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Créer et monter un élément de carte dans un conteneur temporaire
|
|
252
|
+
*/
|
|
253
|
+
async createCardElementInTemporaryContainer() {
|
|
254
|
+
if (!this.isInitialized) {
|
|
255
|
+
throw new Error('Stripe non initialisé');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
// Créer le conteneur temporaire
|
|
260
|
+
const formContainer = this.createTemporaryContainer();
|
|
261
|
+
|
|
262
|
+
// Créer un div pour l'élément de carte
|
|
263
|
+
const cardContainer = this.createTemporaryElement('div', {
|
|
264
|
+
id: 'stripe-card-element-' + Date.now(),
|
|
265
|
+
style: {
|
|
266
|
+
margin: '20px 0'
|
|
267
|
+
}
|
|
268
|
+
}, formContainer);
|
|
269
|
+
|
|
270
|
+
// Créer les éléments Stripe
|
|
271
|
+
this.elements = this.stripe.elements({
|
|
272
|
+
appearance: this.appearance,
|
|
273
|
+
locale: this.locale
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Créer et monter l'élément de carte
|
|
277
|
+
this.cardElement = this.elements.create('card', {
|
|
278
|
+
style: {
|
|
279
|
+
base: {
|
|
280
|
+
fontSize: '16px',
|
|
281
|
+
color: '#32325d',
|
|
282
|
+
fontFamily: 'system-ui, sans-serif',
|
|
283
|
+
'::placeholder': {
|
|
284
|
+
color: '#aab7c4'
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
invalid: {
|
|
288
|
+
color: '#fa755a',
|
|
289
|
+
iconColor: '#fa755a'
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
hidePostalCode: false
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
this.cardElement.mount(cardContainer);
|
|
296
|
+
|
|
297
|
+
// Ajouter un bouton de paiement
|
|
298
|
+
const payButton = this.createTemporaryElement('button', {
|
|
299
|
+
style: {
|
|
300
|
+
backgroundColor: '#5469d4',
|
|
301
|
+
color: '#fff',
|
|
302
|
+
border: 'none',
|
|
303
|
+
padding: '12px 24px',
|
|
304
|
+
borderRadius: '6px',
|
|
305
|
+
fontSize: '16px',
|
|
306
|
+
cursor: 'pointer',
|
|
307
|
+
width: '100%',
|
|
308
|
+
marginTop: '20px'
|
|
309
|
+
},
|
|
310
|
+
textContent: 'Payer',
|
|
311
|
+
onclick: () => this.processPaymentWithTemporaryElement()
|
|
312
|
+
}, formContainer);
|
|
313
|
+
|
|
314
|
+
// Configurer les écouteurs
|
|
315
|
+
this.setupElementListeners();
|
|
316
|
+
|
|
317
|
+
return this.cardElement;
|
|
318
|
+
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.error('❌ Erreur création élément:', error);
|
|
321
|
+
this.cleanupTemporaryElements();
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Configurer les écouteurs pour l'élément
|
|
328
|
+
*/
|
|
329
|
+
setupElementListeners() {
|
|
330
|
+
if (!this.cardElement) return;
|
|
331
|
+
|
|
332
|
+
this.cardElement.on('change', (event) => {
|
|
333
|
+
if (event.error && this.onErrorDisplay) {
|
|
334
|
+
this.onErrorDisplay(event.error.message);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (event.value) {
|
|
338
|
+
this.paymentFormData = {
|
|
339
|
+
...this.paymentFormData,
|
|
340
|
+
...event.value
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Traiter le paiement avec l'élément temporaire
|
|
348
|
+
*/
|
|
349
|
+
async processPaymentWithTemporaryElement(paymentData) {
|
|
350
|
+
if (!this.cardElement || this.isProcessing) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
this.isProcessing = true;
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
// Créer un PaymentIntent
|
|
358
|
+
const clientSecret = await this.createPaymentIntent(paymentData);
|
|
359
|
+
|
|
360
|
+
// Confirmer le paiement
|
|
361
|
+
const { error, paymentIntent } = await this.stripe.confirmCardPayment(clientSecret, {
|
|
362
|
+
payment_method: {
|
|
363
|
+
card: this.cardElement
|
|
364
|
+
},
|
|
365
|
+
billing_details: paymentData.billingDetails || {}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
if (error) {
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Succès
|
|
373
|
+
if (this.onPaymentSuccess) {
|
|
374
|
+
this.onPaymentSuccess(paymentIntent);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Nettoyer après succès
|
|
378
|
+
this.destroyTemporaryContainer();
|
|
379
|
+
|
|
380
|
+
return { success: true, paymentIntent };
|
|
381
|
+
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.error('❌ Erreur paiement:', error);
|
|
384
|
+
|
|
385
|
+
if (this.onPaymentError) {
|
|
386
|
+
this.onPaymentError(error);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return { success: false, error: error.message };
|
|
390
|
+
|
|
391
|
+
} finally {
|
|
392
|
+
this.isProcessing = false;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Créer un PaymentIntent
|
|
398
|
+
*/
|
|
399
|
+
async createPaymentIntent(paymentData) {
|
|
400
|
+
const {
|
|
401
|
+
amount,
|
|
402
|
+
currency = 'eur',
|
|
403
|
+
description = '',
|
|
404
|
+
metadata = {},
|
|
405
|
+
serverUrl = '/api/create-payment-intent'
|
|
406
|
+
} = paymentData;
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
const response = await fetch(serverUrl, {
|
|
410
|
+
method: 'POST',
|
|
411
|
+
headers: {
|
|
412
|
+
'Content-Type': 'application/json'
|
|
413
|
+
},
|
|
414
|
+
body: JSON.stringify({
|
|
415
|
+
amount,
|
|
416
|
+
currency,
|
|
417
|
+
description,
|
|
418
|
+
metadata
|
|
419
|
+
})
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
if (!response.ok) {
|
|
423
|
+
throw new Error('Erreur création PaymentIntent');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const data = await response.json();
|
|
427
|
+
return data.clientSecret;
|
|
428
|
+
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.error('❌ Erreur createPaymentIntent:', error);
|
|
431
|
+
throw error;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Interface simplifiée pour le paiement
|
|
437
|
+
*/
|
|
438
|
+
async startPaymentFlow(paymentData) {
|
|
439
|
+
try {
|
|
440
|
+
// Initialiser Stripe
|
|
441
|
+
await this.initialize();
|
|
442
|
+
|
|
443
|
+
// Créer l'interface de paiement
|
|
444
|
+
await this.createCardElementInTemporaryContainer();
|
|
445
|
+
|
|
446
|
+
// Stocker les données de paiement pour utilisation ultérieure
|
|
447
|
+
this.currentPaymentData = paymentData;
|
|
448
|
+
|
|
449
|
+
return { success: true, message: 'Interface de paiement prête' };
|
|
450
|
+
|
|
451
|
+
} catch (error) {
|
|
452
|
+
console.error('❌ Erreur démarrage paiement:', error);
|
|
453
|
+
this.cleanupTemporaryElements();
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Méthode Checkout (redirection)
|
|
460
|
+
*/
|
|
461
|
+
async redirectToCheckout(paymentData) {
|
|
462
|
+
if (!this.isInitialized) {
|
|
463
|
+
await this.initialize();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
// Créer une session de checkout côté serveur
|
|
468
|
+
const response = await fetch('/api/create-checkout-session', {
|
|
469
|
+
method: 'POST',
|
|
470
|
+
headers: {
|
|
471
|
+
'Content-Type': 'application/json'
|
|
472
|
+
},
|
|
473
|
+
body: JSON.stringify({
|
|
474
|
+
amount: paymentData.amount,
|
|
475
|
+
currency: paymentData.currency || 'eur',
|
|
476
|
+
successUrl: paymentData.successUrl || `${window.location.origin}/success`,
|
|
477
|
+
cancelUrl: paymentData.cancelUrl || `${window.location.origin}/cancel`,
|
|
478
|
+
metadata: paymentData.metadata || {}
|
|
479
|
+
})
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
const session = await response.json();
|
|
483
|
+
|
|
484
|
+
// Rediriger vers Stripe Checkout
|
|
485
|
+
const result = await this.stripe.redirectToCheckout({
|
|
486
|
+
sessionId: session.id
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
if (result.error) {
|
|
490
|
+
throw result.error;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
} catch (error) {
|
|
494
|
+
console.error('❌ Erreur Checkout:', error);
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Nettoyer toutes les ressources
|
|
501
|
+
*/
|
|
502
|
+
destroy() {
|
|
503
|
+
// Détruire les éléments Stripe
|
|
504
|
+
if (this.cardElement) {
|
|
505
|
+
try {
|
|
506
|
+
this.cardElement.destroy();
|
|
507
|
+
} catch (e) {
|
|
508
|
+
// Ignorer les erreurs de destruction
|
|
509
|
+
}
|
|
510
|
+
this.cardElement = null;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (this.elements) {
|
|
514
|
+
this.elements = null;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
this.stripe = null;
|
|
518
|
+
this.isInitialized = false;
|
|
519
|
+
this.isProcessing = false;
|
|
520
|
+
|
|
521
|
+
// Nettoyer tous les éléments DOM temporaires
|
|
522
|
+
this.cleanupTemporaryElements();
|
|
523
|
+
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Détruire proprement avec callback
|
|
528
|
+
*/
|
|
529
|
+
destroyWithCallback(onComplete) {
|
|
530
|
+
this.destroy();
|
|
531
|
+
if (typeof onComplete === 'function') {
|
|
532
|
+
onComplete();
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Méthodes statiques utilitaires
|
|
538
|
+
StripePayment.isStripeSupported = function() {
|
|
539
|
+
return typeof window !== 'undefined' &&
|
|
540
|
+
typeof document !== 'undefined' &&
|
|
541
|
+
typeof window.Stripe !== 'undefined';
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
StripePayment.createHiddenInput = function(name, value) {
|
|
545
|
+
const input = document.createElement('input');
|
|
546
|
+
input.type = 'hidden';
|
|
547
|
+
input.name = name;
|
|
548
|
+
input.value = value;
|
|
549
|
+
return input;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
export default StripePayment;
|