bison-web-components 1.0.0
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/LICENSE +21 -0
- package/README.md +749 -0
- package/api.js +659 -0
- package/bison-operator-payments.js +1913 -0
- package/bison_logo.png +0 -0
- package/bison_logo_green.png +0 -0
- package/bison_logo_green.svg +103 -0
- package/bison_logo_white.svg +68 -0
- package/component.js +48 -0
- package/demo-payments.html +275 -0
- package/index.html +199 -0
- package/operator-bank-account.js +1193 -0
- package/operator-management.js +823 -0
- package/operator-onboarding.js +3750 -0
- package/operator-payment.js +2404 -0
- package/operator-underwriting.js +1473 -0
- package/package.json +14 -0
- package/test.js +3 -0
- package/test.mjs +3 -0
- package/theme.css +312 -0
- package/wio-bank-account.js +536 -0
- package/wio-onboarding.js +3981 -0
- package/wio-payment-linking.js +2054 -0
- package/wio-payment.js +579 -0
package/wio-payment.js
ADDED
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WioPayment Web Component
|
|
3
|
+
*
|
|
4
|
+
* A web component that integrates Moov payment methods with Plaid Link for
|
|
5
|
+
* Worker-Independent Operators (WIOs) to securely link their bank accounts.
|
|
6
|
+
*
|
|
7
|
+
* @author @kfajardo
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
*
|
|
10
|
+
* @requires BisonJibPayAPI - Must be loaded before this component (from component.js)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```html
|
|
14
|
+
* <script src="component.js"></script>
|
|
15
|
+
* <script src="wio-payment.js"></script>
|
|
16
|
+
*
|
|
17
|
+
* <wio-payment id="payment"></wio-payment>
|
|
18
|
+
* <script>
|
|
19
|
+
* const payment = document.getElementById('payment');
|
|
20
|
+
* payment.wioEmail = 'wio@example.com';
|
|
21
|
+
* payment.env = 'sandbox';
|
|
22
|
+
* payment.onSuccess = (data) => console.log('Success!', data);
|
|
23
|
+
* payment.onError = ({ errorType, error }) => console.error(errorType, error);
|
|
24
|
+
* payment.open = true;
|
|
25
|
+
* </script>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
class WioPayment extends HTMLElement {
|
|
30
|
+
constructor() {
|
|
31
|
+
super();
|
|
32
|
+
this.attachShadow({ mode: "open" });
|
|
33
|
+
|
|
34
|
+
// API Configuration
|
|
35
|
+
this.apiBaseURL =
|
|
36
|
+
this.getAttribute("api-base-url") ||
|
|
37
|
+
"https://bison-jib-development.azurewebsites.net";
|
|
38
|
+
this.embeddableKey =
|
|
39
|
+
this.getAttribute("embeddable-key") ||
|
|
40
|
+
"R80WMkbNN8457RofiMYx03DL65P06IaVT30Q2emYJUBQwYCzRC";
|
|
41
|
+
|
|
42
|
+
// Check if BisonJibPayAPI is available
|
|
43
|
+
if (typeof BisonJibPayAPI === "undefined") {
|
|
44
|
+
console.error(
|
|
45
|
+
"WioPayment: BisonJibPayAPI is not available. Please ensure component.js is loaded before wio-payment.js"
|
|
46
|
+
);
|
|
47
|
+
this.api = null;
|
|
48
|
+
} else {
|
|
49
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Internal state
|
|
53
|
+
this._state = {
|
|
54
|
+
wioEmail: null,
|
|
55
|
+
env: "sandbox",
|
|
56
|
+
redirectURL: typeof window !== "undefined" ? window.location.origin : "",
|
|
57
|
+
moovToken: null,
|
|
58
|
+
plaidToken: null,
|
|
59
|
+
isInitialized: false,
|
|
60
|
+
isLoading: false,
|
|
61
|
+
error: null,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Callback references
|
|
65
|
+
this._onSuccessCallback = null;
|
|
66
|
+
this._onErrorCallback = null;
|
|
67
|
+
|
|
68
|
+
// Moov drop reference
|
|
69
|
+
this._moovRef = null;
|
|
70
|
+
|
|
71
|
+
// Render the component
|
|
72
|
+
this.render();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ==================== STATIC PROPERTIES ====================
|
|
76
|
+
|
|
77
|
+
static get observedAttributes() {
|
|
78
|
+
return [
|
|
79
|
+
"wio-email",
|
|
80
|
+
"env",
|
|
81
|
+
"redirect-url",
|
|
82
|
+
"on-success",
|
|
83
|
+
"on-error",
|
|
84
|
+
"open",
|
|
85
|
+
"api-base-url",
|
|
86
|
+
"embeddable-key",
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ==================== PROPERTY GETTERS/SETTERS ====================
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get the WIO email
|
|
94
|
+
* @returns {string|null}
|
|
95
|
+
*/
|
|
96
|
+
get wioEmail() {
|
|
97
|
+
return this._state.wioEmail;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set the WIO email (triggers initialization)
|
|
102
|
+
* @param {string} value - WIO's email address
|
|
103
|
+
*/
|
|
104
|
+
set wioEmail(value) {
|
|
105
|
+
if (this._state.wioEmail !== value) {
|
|
106
|
+
this._state.wioEmail = value;
|
|
107
|
+
this._state.isInitialized = false;
|
|
108
|
+
|
|
109
|
+
// Reinitialize if already connected and email is provided
|
|
110
|
+
if (this.isConnected && value && this._state.env) {
|
|
111
|
+
this.initializeMoovDrop();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get the Plaid environment
|
|
118
|
+
* @returns {string}
|
|
119
|
+
*/
|
|
120
|
+
get env() {
|
|
121
|
+
return this._state.env;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Set the Plaid environment (required for Plaid integration)
|
|
126
|
+
* @param {string} value - Plaid environment ('sandbox', 'development', or 'production')
|
|
127
|
+
*/
|
|
128
|
+
set env(value) {
|
|
129
|
+
if (this._state.env !== value) {
|
|
130
|
+
this._state.env = value;
|
|
131
|
+
this._state.isInitialized = false;
|
|
132
|
+
|
|
133
|
+
// Reinitialize if already connected and both email and env are provided
|
|
134
|
+
if (this.isConnected && this._state.wioEmail && value) {
|
|
135
|
+
this.initializeMoovDrop();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get the redirect URL
|
|
142
|
+
* @returns {string}
|
|
143
|
+
*/
|
|
144
|
+
get redirectURL() {
|
|
145
|
+
return this._state.redirectURL;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Set the redirect URL for Plaid OAuth flow
|
|
150
|
+
* @param {string} value - URL to redirect to after Plaid OAuth
|
|
151
|
+
*/
|
|
152
|
+
set redirectURL(value) {
|
|
153
|
+
this._state.redirectURL = value;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get the onSuccess callback
|
|
158
|
+
* @returns {Function|null}
|
|
159
|
+
*/
|
|
160
|
+
get onSuccess() {
|
|
161
|
+
return this._onSuccessCallback;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Set the onSuccess callback
|
|
166
|
+
* @param {Function} callback - Called when bank account is successfully linked
|
|
167
|
+
*/
|
|
168
|
+
set onSuccess(callback) {
|
|
169
|
+
if (typeof callback === "function" || callback === null) {
|
|
170
|
+
this._onSuccessCallback = callback;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the onError callback
|
|
176
|
+
* @returns {Function|null}
|
|
177
|
+
*/
|
|
178
|
+
get onError() {
|
|
179
|
+
return this._onErrorCallback;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Set the onError callback
|
|
184
|
+
* @param {Function} callback - Called when an error occurs
|
|
185
|
+
*/
|
|
186
|
+
set onError(callback) {
|
|
187
|
+
if (typeof callback === "function" || callback === null) {
|
|
188
|
+
this._onErrorCallback = callback;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get the open state of the payment drop
|
|
194
|
+
* @returns {boolean}
|
|
195
|
+
*/
|
|
196
|
+
get open() {
|
|
197
|
+
return this._moovRef?.open || false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Set the open state of the payment drop
|
|
202
|
+
* @param {boolean} value - Whether to show the drop
|
|
203
|
+
*/
|
|
204
|
+
set open(value) {
|
|
205
|
+
const shouldOpen = Boolean(value);
|
|
206
|
+
|
|
207
|
+
// Initialize if not yet initialized and trying to open
|
|
208
|
+
if (!this._state.isInitialized && shouldOpen) {
|
|
209
|
+
this.initializeMoovDrop().then(() => {
|
|
210
|
+
if (this._moovRef) {
|
|
211
|
+
this._moovRef.open = shouldOpen;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
} else if (this._moovRef) {
|
|
215
|
+
this._moovRef.open = shouldOpen;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ==================== LIFECYCLE METHODS ====================
|
|
220
|
+
|
|
221
|
+
connectedCallback() {
|
|
222
|
+
// Load Moov SDK if not already loaded
|
|
223
|
+
this.ensureMoovSDK().then(() => {
|
|
224
|
+
// Initialize if both wioEmail and env are already set
|
|
225
|
+
|
|
226
|
+
if (
|
|
227
|
+
this._state.wioEmail &&
|
|
228
|
+
this._state.env &&
|
|
229
|
+
!this._state.isInitialized
|
|
230
|
+
) {
|
|
231
|
+
this.initializeMoovDrop();
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
disconnectedCallback() {
|
|
237
|
+
// Cleanup if needed
|
|
238
|
+
this._moovRef = null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
242
|
+
if (oldValue === newValue) return;
|
|
243
|
+
|
|
244
|
+
switch (name) {
|
|
245
|
+
case "wio-email":
|
|
246
|
+
this.wioEmail = newValue;
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
case "env":
|
|
250
|
+
this.env = newValue;
|
|
251
|
+
break;
|
|
252
|
+
|
|
253
|
+
case "redirect-url":
|
|
254
|
+
this.redirectURL = newValue;
|
|
255
|
+
break;
|
|
256
|
+
|
|
257
|
+
case "on-success":
|
|
258
|
+
// Attribute-based callback (function name in global scope)
|
|
259
|
+
if (newValue && window[newValue]) {
|
|
260
|
+
this.onSuccess = window[newValue];
|
|
261
|
+
}
|
|
262
|
+
break;
|
|
263
|
+
|
|
264
|
+
case "on-error":
|
|
265
|
+
// Attribute-based callback (function name in global scope)
|
|
266
|
+
if (newValue && window[newValue]) {
|
|
267
|
+
this.onError = window[newValue];
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
|
|
271
|
+
case "open":
|
|
272
|
+
this.open = newValue !== null;
|
|
273
|
+
break;
|
|
274
|
+
|
|
275
|
+
case "api-base-url":
|
|
276
|
+
this.apiBaseURL = newValue;
|
|
277
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
278
|
+
break;
|
|
279
|
+
|
|
280
|
+
case "embeddable-key":
|
|
281
|
+
this.embeddableKey = newValue;
|
|
282
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ==================== CORE METHODS ====================
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Ensure Moov SDK is loaded
|
|
291
|
+
*
|
|
292
|
+
* This method dynamically loads the Moov SDK from the CDN if not already present.
|
|
293
|
+
* This eliminates the need for consumers to manually include the script tag.
|
|
294
|
+
*
|
|
295
|
+
* @returns {Promise<void>} Resolves when SDK is ready
|
|
296
|
+
*/
|
|
297
|
+
async ensureMoovSDK() {
|
|
298
|
+
// Check if Moov is already loaded
|
|
299
|
+
if (window.Moov) {
|
|
300
|
+
console.log("WioPayment: Moov SDK already loaded");
|
|
301
|
+
return Promise.resolve();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Check if script is already being loaded
|
|
305
|
+
const existingScript = document.querySelector('script[src*="moov.js"]');
|
|
306
|
+
if (existingScript) {
|
|
307
|
+
console.log("WioPayment: Moov SDK script found, waiting for load...");
|
|
308
|
+
return new Promise((resolve, reject) => {
|
|
309
|
+
existingScript.addEventListener("load", () => resolve());
|
|
310
|
+
existingScript.addEventListener("error", () =>
|
|
311
|
+
reject(new Error("Failed to load Moov SDK"))
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Load the SDK
|
|
317
|
+
console.log("WioPayment: Loading Moov SDK from CDN...");
|
|
318
|
+
return new Promise((resolve, reject) => {
|
|
319
|
+
const script = document.createElement("script");
|
|
320
|
+
script.src = "https://js.moov.io/v1";
|
|
321
|
+
script.async = true;
|
|
322
|
+
script.defer = true;
|
|
323
|
+
|
|
324
|
+
script.onload = () => {
|
|
325
|
+
console.log("WioPayment: Moov SDK loaded successfully");
|
|
326
|
+
resolve();
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
script.onerror = () => {
|
|
330
|
+
const error = new Error("Failed to load Moov SDK from CDN");
|
|
331
|
+
console.error("WioPayment:", error);
|
|
332
|
+
this.handleError({
|
|
333
|
+
errorType: "sdk",
|
|
334
|
+
error: error.message,
|
|
335
|
+
});
|
|
336
|
+
reject(error);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// Append to document head
|
|
340
|
+
document.head.appendChild(script);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Initialize the Moov payment methods drop with Plaid integration
|
|
346
|
+
*
|
|
347
|
+
* This method:
|
|
348
|
+
* 1. Validates prerequisites (wioEmail, env, Moov SDK)
|
|
349
|
+
* 2. Generates both Plaid and Moov access tokens
|
|
350
|
+
* 3. Configures the moov-payment-methods element with Plaid settings
|
|
351
|
+
* 4. Sets up success/error callbacks
|
|
352
|
+
*/
|
|
353
|
+
async initializeMoovDrop() {
|
|
354
|
+
// 1. Validate prerequisites
|
|
355
|
+
if (!this._state.wioEmail) {
|
|
356
|
+
console.warn("WioPayment: wioEmail is required");
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (!this._state.env) {
|
|
361
|
+
console.warn("WioPayment: env is required for Plaid integration");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (!window.Moov) {
|
|
366
|
+
this.handleError({
|
|
367
|
+
errorType: "sdk",
|
|
368
|
+
error: "Moov SDK not loaded. Please include the Moov SDK script.",
|
|
369
|
+
});
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// 2. Validate API availability
|
|
374
|
+
if (!this.api) {
|
|
375
|
+
this.handleError({
|
|
376
|
+
errorType: "initialization",
|
|
377
|
+
error:
|
|
378
|
+
"BisonJibPayAPI is not available. Please ensure component.js is loaded first.",
|
|
379
|
+
});
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
let accID = "";
|
|
383
|
+
|
|
384
|
+
try {
|
|
385
|
+
this._state.isLoading = true;
|
|
386
|
+
|
|
387
|
+
// 3. Generate Plaid token
|
|
388
|
+
console.log("WioPayment: Generating Plaid token...");
|
|
389
|
+
const plaidTokenResult = await this.api.generatePlaidToken(
|
|
390
|
+
this._state.wioEmail
|
|
391
|
+
);
|
|
392
|
+
this._state.plaidToken = plaidTokenResult.data.linkToken;
|
|
393
|
+
console.log("WioPayment: Plaid token generated successfully");
|
|
394
|
+
|
|
395
|
+
// 4. Generate Moov token
|
|
396
|
+
console.log("WioPayment: Generating Moov token...");
|
|
397
|
+
const moovTokenResult = await this.api.generateMoovToken(
|
|
398
|
+
this._state.wioEmail
|
|
399
|
+
);
|
|
400
|
+
this._state.moovToken = moovTokenResult.data.accessToken;
|
|
401
|
+
accID = moovTokenResult.data.moovAccountId;
|
|
402
|
+
|
|
403
|
+
console.log("WioPayment: Moov token generated successfully");
|
|
404
|
+
} catch (error) {
|
|
405
|
+
this.handleError({
|
|
406
|
+
errorType: "token",
|
|
407
|
+
error: error.message || "Failed to generate tokens",
|
|
408
|
+
});
|
|
409
|
+
return;
|
|
410
|
+
} finally {
|
|
411
|
+
this._state.isLoading = false;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// 5. Get reference to moov-payment-methods element
|
|
415
|
+
this._moovRef = this.shadowRoot.querySelector("moov-payment-methods");
|
|
416
|
+
|
|
417
|
+
if (!this._moovRef) {
|
|
418
|
+
console.error(
|
|
419
|
+
"WioPayment: moov-payment-methods element not found in shadow DOM"
|
|
420
|
+
);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// 6. Configure Plaid integration
|
|
425
|
+
this._moovRef.plaid = {
|
|
426
|
+
env: this._state.env,
|
|
427
|
+
redirectURL: this._state.redirectURL,
|
|
428
|
+
token: this._state.plaidToken,
|
|
429
|
+
onSuccess: (moovBankAccount) => {
|
|
430
|
+
console.log(
|
|
431
|
+
"WioPayment: Plaid flow completed successfully",
|
|
432
|
+
moovBankAccount
|
|
433
|
+
);
|
|
434
|
+
},
|
|
435
|
+
onExit: (err, metadata) => {
|
|
436
|
+
console.log("PLAID ERROR", err, metadata);
|
|
437
|
+
if (err) {
|
|
438
|
+
console.error("WioPayment: Plaid flow exited with error", err);
|
|
439
|
+
this.handleError({
|
|
440
|
+
errorType: "plaid",
|
|
441
|
+
error: err,
|
|
442
|
+
});
|
|
443
|
+
} else {
|
|
444
|
+
console.log("WioPayment: Plaid flow exited by user", metadata);
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
onLoad: () => {
|
|
448
|
+
console.log("WioPayment: Plaid Link resource loaded");
|
|
449
|
+
},
|
|
450
|
+
onProcessorTokenRequest: async (public_token, bank_account_id) => {
|
|
451
|
+
console.log(
|
|
452
|
+
"WioPayment: Generating processor token for bank account",
|
|
453
|
+
bank_account_id
|
|
454
|
+
);
|
|
455
|
+
|
|
456
|
+
try {
|
|
457
|
+
const result = await this.api.createProcessorToken(
|
|
458
|
+
public_token,
|
|
459
|
+
bank_account_id
|
|
460
|
+
);
|
|
461
|
+
console.log(
|
|
462
|
+
"WioPayment: Processor token generated successfully",
|
|
463
|
+
result.data.processorToken
|
|
464
|
+
);
|
|
465
|
+
return result.data.processorToken;
|
|
466
|
+
} catch (error) {
|
|
467
|
+
console.error("WioPayment: Failed to create processor token", error);
|
|
468
|
+
this.handleError({
|
|
469
|
+
errorType: "plaid",
|
|
470
|
+
error: "Failed to create processor token",
|
|
471
|
+
});
|
|
472
|
+
throw error;
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
};
|
|
476
|
+
console.log("accountID", accID);
|
|
477
|
+
// 7. Configure the Moov drop
|
|
478
|
+
this._moovRef.token = this._state.moovToken;
|
|
479
|
+
this._moovRef.accountID = accID;
|
|
480
|
+
this._moovRef.paymentMethodTypes = ["plaid"];
|
|
481
|
+
this._moovRef.showLogo = true;
|
|
482
|
+
|
|
483
|
+
// 8. Set up callbacks
|
|
484
|
+
this._moovRef.onResourceCreated = (result) => {
|
|
485
|
+
console.log("WioPayment: Bank account successfully linked", result);
|
|
486
|
+
|
|
487
|
+
// Call user's success callback
|
|
488
|
+
if (this._onSuccessCallback) {
|
|
489
|
+
this._onSuccessCallback(result);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Auto-close after success
|
|
493
|
+
this.open = false;
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
this._moovRef.onError = ({ errorType, error }) => {
|
|
497
|
+
console.error("WioPayment: Moov error", errorType, error);
|
|
498
|
+
this.handleError({ errorType, error });
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
// 9. Mark as initialized
|
|
502
|
+
this._state.isInitialized = true;
|
|
503
|
+
console.log(
|
|
504
|
+
"WioPayment: Initialized for",
|
|
505
|
+
this._state.wioEmail,
|
|
506
|
+
"with env",
|
|
507
|
+
this._state.env
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Handle errors
|
|
513
|
+
* @param {Object} errorData - Error information
|
|
514
|
+
* @param {string} errorData.errorType - Type of error
|
|
515
|
+
* @param {string|Error} errorData.error - Error message or object
|
|
516
|
+
*/
|
|
517
|
+
handleError({ errorType, error }) {
|
|
518
|
+
// Store error in state
|
|
519
|
+
this._state.error = { errorType, error };
|
|
520
|
+
|
|
521
|
+
// Log to console
|
|
522
|
+
console.error(`WioPayment Error (${errorType}):`, error);
|
|
523
|
+
|
|
524
|
+
// Call user's error callback
|
|
525
|
+
if (this._onErrorCallback) {
|
|
526
|
+
this._onErrorCallback({ errorType, error });
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Emit custom event
|
|
530
|
+
this.dispatchEvent(
|
|
531
|
+
new CustomEvent("payment-error", {
|
|
532
|
+
detail: { errorType, error },
|
|
533
|
+
bubbles: true,
|
|
534
|
+
composed: true,
|
|
535
|
+
})
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// ==================== RENDERING ====================
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Render the component (Shadow DOM)
|
|
543
|
+
*/
|
|
544
|
+
render() {
|
|
545
|
+
this.shadowRoot.innerHTML = `
|
|
546
|
+
<style>
|
|
547
|
+
:host {
|
|
548
|
+
display: block;
|
|
549
|
+
font-family: var(--font-sans, 'Inter', system-ui, sans-serif);
|
|
550
|
+
color: var(--color-secondary, #5f6e78);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* Ensure moov-payment-methods is properly contained */
|
|
554
|
+
moov-payment-methods {
|
|
555
|
+
display: block;
|
|
556
|
+
width: 100%;
|
|
557
|
+
}
|
|
558
|
+
</style>
|
|
559
|
+
|
|
560
|
+
<!-- Moov payment methods drop -->
|
|
561
|
+
<moov-payment-methods></moov-payment-methods>
|
|
562
|
+
`;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Register the custom element only if it hasn't been registered yet
|
|
567
|
+
if (!customElements.get("wio-payment")) {
|
|
568
|
+
customElements.define("wio-payment", WioPayment);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Export for module usage
|
|
572
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
573
|
+
module.exports = { WioPayment };
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Make available globally for script tag usage
|
|
577
|
+
if (typeof window !== "undefined") {
|
|
578
|
+
window.WioPayment = WioPayment;
|
|
579
|
+
}
|