bison-web-components 1.0.0 → 1.2.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/README.md +197 -176
- package/bison-operator-payments.js +691 -475
- package/demo-payments.html +2 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,16 +5,17 @@ A complete, self-contained web component for operator onboarding with 4-step ste
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```html
|
|
8
|
-
<script src="https://cdn.jsdelivr.net/npm/web-components
|
|
8
|
+
<script src="https://cdn.jsdelivr.net/npm/bison-web-components@1.0.0/component.js"></script>
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Basic Usage
|
|
12
12
|
|
|
13
13
|
### Minimal Setup (No Callbacks)
|
|
14
|
+
|
|
14
15
|
The simplest way to use the component:
|
|
15
16
|
|
|
16
17
|
```html
|
|
17
|
-
<script src="https://cdn.jsdelivr.net/npm/web-components
|
|
18
|
+
<script src="https://cdn.jsdelivr.net/npm/bison-web-components@1.0.0/component.js"></script>
|
|
18
19
|
<operator-onboarding></operator-onboarding>
|
|
19
20
|
```
|
|
20
21
|
|
|
@@ -27,21 +28,22 @@ When submitted, form data is automatically logged to console and success page is
|
|
|
27
28
|
The component can be configured with optional attributes for API integration:
|
|
28
29
|
|
|
29
30
|
```html
|
|
30
|
-
<operator-onboarding
|
|
31
|
+
<operator-onboarding
|
|
31
32
|
api-base-url="https://your-api-domain.com"
|
|
32
|
-
embeddable-key="your-embeddable-key"
|
|
33
|
+
embeddable-key="your-embeddable-key"
|
|
34
|
+
>
|
|
33
35
|
</operator-onboarding>
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
### Attributes
|
|
37
39
|
|
|
38
|
-
| Attribute
|
|
39
|
-
|
|
40
|
-
| `api-base-url`
|
|
41
|
-
| `embeddable-key` | `String` | Default key provided
|
|
42
|
-
| `on-success`
|
|
43
|
-
| `on-error`
|
|
44
|
-
| `on-load`
|
|
40
|
+
| Attribute | Type | Default | Description |
|
|
41
|
+
| ---------------- | -------- | ------------------------------------------------- | ---------------------------------------------------- |
|
|
42
|
+
| `api-base-url` | `String` | `https://bison-jib-development.azurewebsites.net` | Base URL for API endpoints |
|
|
43
|
+
| `embeddable-key` | `String` | Default key provided | Authentication key for API requests |
|
|
44
|
+
| `on-success` | `String` | - | Name of global function to call on success |
|
|
45
|
+
| `on-error` | `String` | - | Name of global function to call on error |
|
|
46
|
+
| `on-load` | `String` | - | JSON string or global variable name for initial data |
|
|
45
47
|
|
|
46
48
|
---
|
|
47
49
|
|
|
@@ -59,34 +61,38 @@ The onboarding process consists of a 4-step stepper form:
|
|
|
59
61
|
## Form Steps in Detail
|
|
60
62
|
|
|
61
63
|
### Step 1: Business Details
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
64
|
+
|
|
65
|
+
- Business name \*
|
|
66
|
+
- Doing Business As (DBA) \*
|
|
67
|
+
- EIN (Employer Identification Number) \* (auto-formatted as XX-XXXXXXX)
|
|
65
68
|
- Business website (auto-normalized to include https://)
|
|
66
|
-
- Business phone
|
|
67
|
-
- Business email
|
|
68
|
-
- Full address
|
|
69
|
+
- Business phone \* (auto-formatted as (555) 123-4567)
|
|
70
|
+
- Business email \*
|
|
71
|
+
- Full address \* (street, city, state, ZIP)
|
|
69
72
|
|
|
70
73
|
### Step 2: Representatives (Optional)
|
|
74
|
+
|
|
71
75
|
- Add/remove multiple representatives
|
|
72
76
|
- Full CRUD interface
|
|
73
77
|
- Each representative requires:
|
|
74
|
-
- First name, last name
|
|
75
|
-
- Job title
|
|
76
|
-
- Phone
|
|
77
|
-
- Email
|
|
78
|
-
- Date of birth
|
|
79
|
-
- Full address
|
|
78
|
+
- First name, last name \*
|
|
79
|
+
- Job title \*
|
|
80
|
+
- Phone \* (auto-formatted)
|
|
81
|
+
- Email \*
|
|
82
|
+
- Date of birth \*
|
|
83
|
+
- Full address \* (street, city, state, ZIP)
|
|
80
84
|
- Can skip entire step if no representatives to add
|
|
81
85
|
|
|
82
86
|
### Step 3: Bank Account
|
|
83
|
-
|
|
84
|
-
- Account
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
+
|
|
88
|
+
- Account holder name \*
|
|
89
|
+
- Account type \* (checking/savings)
|
|
90
|
+
- Routing number \* (9 digits)
|
|
91
|
+
- Account number \* (4-17 digits)
|
|
87
92
|
|
|
88
93
|
### Step 4: Underwriting
|
|
89
|
-
|
|
94
|
+
|
|
95
|
+
- Upload supporting documents \* (required)
|
|
90
96
|
- Drag-and-drop or browse file selection
|
|
91
97
|
- Maximum 10 files
|
|
92
98
|
- Maximum 10MB per file
|
|
@@ -99,52 +105,54 @@ The onboarding process consists of a 4-step stepper form:
|
|
|
99
105
|
### Method 1: Direct Property Assignment (Recommended)
|
|
100
106
|
|
|
101
107
|
```javascript
|
|
102
|
-
const component = document.querySelector(
|
|
108
|
+
const component = document.querySelector("operator-onboarding");
|
|
103
109
|
|
|
104
110
|
// Pre-populate with existing data
|
|
105
111
|
component.onLoad = {
|
|
106
112
|
businessDetails: {
|
|
107
|
-
businessName:
|
|
108
|
-
doingBusinessAs:
|
|
109
|
-
ein:
|
|
110
|
-
businessWebsite:
|
|
111
|
-
businessPhoneNumber:
|
|
112
|
-
businessEmail:
|
|
113
|
-
BusinessAddress1:
|
|
114
|
-
businessCity:
|
|
115
|
-
businessState:
|
|
116
|
-
businessPostalCode:
|
|
113
|
+
businessName: "Acme Corp",
|
|
114
|
+
doingBusinessAs: "Acme",
|
|
115
|
+
ein: "12-3456789",
|
|
116
|
+
businessWebsite: "https://acme.com",
|
|
117
|
+
businessPhoneNumber: "5551234567",
|
|
118
|
+
businessEmail: "contact@acme.com",
|
|
119
|
+
BusinessAddress1: "123 Main St",
|
|
120
|
+
businessCity: "San Francisco",
|
|
121
|
+
businessState: "CA",
|
|
122
|
+
businessPostalCode: "94105",
|
|
117
123
|
},
|
|
118
124
|
representatives: [
|
|
119
125
|
{
|
|
120
|
-
representativeFirstName:
|
|
121
|
-
representativeLastName:
|
|
122
|
-
representativeJobTitle:
|
|
123
|
-
representativePhone:
|
|
124
|
-
representativeEmail:
|
|
125
|
-
representativeDateOfBirth:
|
|
126
|
-
representativeAddress:
|
|
127
|
-
representativeCity:
|
|
128
|
-
representativeState:
|
|
129
|
-
representativeZip:
|
|
130
|
-
}
|
|
126
|
+
representativeFirstName: "John",
|
|
127
|
+
representativeLastName: "Doe",
|
|
128
|
+
representativeJobTitle: "CEO",
|
|
129
|
+
representativePhone: "5559876543",
|
|
130
|
+
representativeEmail: "john@company.com",
|
|
131
|
+
representativeDateOfBirth: "1980-01-15",
|
|
132
|
+
representativeAddress: "456 Oak Ave",
|
|
133
|
+
representativeCity: "San Francisco",
|
|
134
|
+
representativeState: "CA",
|
|
135
|
+
representativeZip: "94105",
|
|
136
|
+
},
|
|
131
137
|
],
|
|
132
138
|
underwriting: {
|
|
133
|
-
underwritingDocuments: []
|
|
139
|
+
underwritingDocuments: [], // Can be pre-populated with File objects
|
|
134
140
|
},
|
|
135
141
|
bankDetails: {
|
|
136
|
-
bankAccountHolderName:
|
|
137
|
-
bankAccountType:
|
|
138
|
-
bankRoutingNumber:
|
|
139
|
-
bankAccountNumber:
|
|
140
|
-
}
|
|
142
|
+
bankAccountHolderName: "Acme Corp",
|
|
143
|
+
bankAccountType: "checking",
|
|
144
|
+
bankRoutingNumber: "123456789",
|
|
145
|
+
bankAccountNumber: "987654321",
|
|
146
|
+
},
|
|
141
147
|
};
|
|
142
148
|
```
|
|
143
149
|
|
|
144
150
|
### Method 2: HTML Attribute with JSON
|
|
145
151
|
|
|
146
152
|
```html
|
|
147
|
-
<operator-onboarding
|
|
153
|
+
<operator-onboarding
|
|
154
|
+
on-load='{"businessDetails":{"businessName":"Acme Corp"}}'
|
|
155
|
+
></operator-onboarding>
|
|
148
156
|
```
|
|
149
157
|
|
|
150
158
|
### Method 3: HTML Attribute with Global Variable
|
|
@@ -153,9 +161,9 @@ component.onLoad = {
|
|
|
153
161
|
<script>
|
|
154
162
|
const initialData = {
|
|
155
163
|
businessDetails: {
|
|
156
|
-
businessName:
|
|
157
|
-
businessEmail:
|
|
158
|
-
}
|
|
164
|
+
businessName: "Acme Corp",
|
|
165
|
+
businessEmail: "test@company.com",
|
|
166
|
+
},
|
|
159
167
|
};
|
|
160
168
|
</script>
|
|
161
169
|
|
|
@@ -171,30 +179,30 @@ component.onLoad = {
|
|
|
171
179
|
**Perfect for React, Vue, Angular, and vanilla JavaScript:**
|
|
172
180
|
|
|
173
181
|
```javascript
|
|
174
|
-
const component = document.querySelector(
|
|
182
|
+
const component = document.querySelector("operator-onboarding");
|
|
175
183
|
|
|
176
184
|
// Success callback
|
|
177
185
|
component.onSuccess = (formData) => {
|
|
178
|
-
console.log(
|
|
179
|
-
|
|
186
|
+
console.log("Onboarding complete!", formData);
|
|
187
|
+
|
|
180
188
|
// Send to your backend
|
|
181
|
-
fetch(
|
|
182
|
-
method:
|
|
183
|
-
headers: {
|
|
184
|
-
body: JSON.stringify(formData)
|
|
189
|
+
fetch("/api/operators/onboard", {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "Content-Type": "application/json" },
|
|
192
|
+
body: JSON.stringify(formData),
|
|
185
193
|
});
|
|
186
|
-
|
|
194
|
+
|
|
187
195
|
// Close your modal
|
|
188
196
|
closeModal();
|
|
189
197
|
};
|
|
190
198
|
|
|
191
199
|
// Error callback
|
|
192
200
|
component.onError = (errorData) => {
|
|
193
|
-
console.error(
|
|
194
|
-
|
|
195
|
-
if (errorData.action ===
|
|
201
|
+
console.error("Onboarding error:", errorData);
|
|
202
|
+
|
|
203
|
+
if (errorData.action === "resubmit") {
|
|
196
204
|
// User clicked resubmit button
|
|
197
|
-
console.log(
|
|
205
|
+
console.log("User wants to retry submission");
|
|
198
206
|
}
|
|
199
207
|
};
|
|
200
208
|
```
|
|
@@ -204,19 +212,17 @@ component.onError = (errorData) => {
|
|
|
204
212
|
Good for simple cases with global functions:
|
|
205
213
|
|
|
206
214
|
```html
|
|
207
|
-
<operator-onboarding
|
|
208
|
-
on-success="handleSuccess"
|
|
209
|
-
on-error="handleError">
|
|
215
|
+
<operator-onboarding on-success="handleSuccess" on-error="handleError">
|
|
210
216
|
</operator-onboarding>
|
|
211
217
|
|
|
212
218
|
<script>
|
|
213
219
|
function handleSuccess(data) {
|
|
214
|
-
console.log(
|
|
220
|
+
console.log("Success!", data);
|
|
215
221
|
closeModal();
|
|
216
222
|
}
|
|
217
|
-
|
|
223
|
+
|
|
218
224
|
function handleError(errorData) {
|
|
219
|
-
console.error(
|
|
225
|
+
console.error("Error:", errorData);
|
|
220
226
|
}
|
|
221
227
|
</script>
|
|
222
228
|
```
|
|
@@ -227,16 +233,16 @@ Listen to custom events:
|
|
|
227
233
|
|
|
228
234
|
```javascript
|
|
229
235
|
// Success event
|
|
230
|
-
component.addEventListener(
|
|
236
|
+
component.addEventListener("formComplete", (event) => {
|
|
231
237
|
const formData = event.detail;
|
|
232
|
-
console.log(
|
|
238
|
+
console.log("Form completed!", formData);
|
|
233
239
|
closeModal();
|
|
234
240
|
});
|
|
235
241
|
|
|
236
242
|
// Submission failure event
|
|
237
|
-
component.addEventListener(
|
|
243
|
+
component.addEventListener("submissionFailed", (event) => {
|
|
238
244
|
const errorData = event.detail;
|
|
239
|
-
console.error(
|
|
245
|
+
console.error("Submission failed:", errorData);
|
|
240
246
|
});
|
|
241
247
|
```
|
|
242
248
|
|
|
@@ -247,43 +253,43 @@ component.addEventListener('submissionFailed', (event) => {
|
|
|
247
253
|
### Recommended Pattern (Using useRef)
|
|
248
254
|
|
|
249
255
|
```jsx
|
|
250
|
-
import { useEffect, useRef } from
|
|
256
|
+
import { useEffect, useRef } from "react";
|
|
251
257
|
|
|
252
258
|
function OnboardingModal({ isOpen, onClose }) {
|
|
253
259
|
const componentRef = useRef(null);
|
|
254
|
-
|
|
260
|
+
|
|
255
261
|
useEffect(() => {
|
|
256
262
|
if (componentRef.current) {
|
|
257
263
|
// Success handler
|
|
258
264
|
componentRef.current.onSuccess = (data) => {
|
|
259
|
-
console.log(
|
|
260
|
-
|
|
265
|
+
console.log("Onboarding complete:", data);
|
|
266
|
+
|
|
261
267
|
// Send to API
|
|
262
|
-
fetch(
|
|
263
|
-
method:
|
|
264
|
-
body: JSON.stringify(data)
|
|
268
|
+
fetch("/api/onboard", {
|
|
269
|
+
method: "POST",
|
|
270
|
+
body: JSON.stringify(data),
|
|
265
271
|
});
|
|
266
|
-
|
|
272
|
+
|
|
267
273
|
onClose();
|
|
268
274
|
};
|
|
269
|
-
|
|
275
|
+
|
|
270
276
|
// Error handler
|
|
271
277
|
componentRef.current.onError = (errorData) => {
|
|
272
|
-
console.error(
|
|
278
|
+
console.error("Error:", errorData);
|
|
273
279
|
// Handle errors appropriately
|
|
274
280
|
};
|
|
275
281
|
}
|
|
276
282
|
}, [onClose]);
|
|
277
|
-
|
|
283
|
+
|
|
278
284
|
if (!isOpen) return null;
|
|
279
|
-
|
|
285
|
+
|
|
280
286
|
return (
|
|
281
287
|
<div className="modal">
|
|
282
|
-
<operator-onboarding
|
|
288
|
+
<operator-onboarding
|
|
283
289
|
ref={componentRef}
|
|
284
290
|
api-base-url="https://your-api.com"
|
|
285
|
-
embeddable-key="your-key"
|
|
286
|
-
|
|
291
|
+
embeddable-key="your-key"
|
|
292
|
+
></operator-onboarding>
|
|
287
293
|
</div>
|
|
288
294
|
);
|
|
289
295
|
}
|
|
@@ -295,36 +301,36 @@ function OnboardingModal({ isOpen, onClose }) {
|
|
|
295
301
|
function EditOperatorModal({ operatorId, isOpen, onClose }) {
|
|
296
302
|
const componentRef = useRef(null);
|
|
297
303
|
const [initialData, setInitialData] = useState(null);
|
|
298
|
-
|
|
304
|
+
|
|
299
305
|
useEffect(() => {
|
|
300
306
|
if (isOpen && operatorId) {
|
|
301
307
|
// Fetch existing operator data
|
|
302
308
|
fetch(`/api/operators/${operatorId}`)
|
|
303
|
-
.then(res => res.json())
|
|
304
|
-
.then(data => setInitialData(data));
|
|
309
|
+
.then((res) => res.json())
|
|
310
|
+
.then((data) => setInitialData(data));
|
|
305
311
|
}
|
|
306
312
|
}, [isOpen, operatorId]);
|
|
307
|
-
|
|
313
|
+
|
|
308
314
|
useEffect(() => {
|
|
309
315
|
if (componentRef.current) {
|
|
310
316
|
// Pre-populate form
|
|
311
317
|
if (initialData) {
|
|
312
318
|
componentRef.current.onLoad = initialData;
|
|
313
319
|
}
|
|
314
|
-
|
|
320
|
+
|
|
315
321
|
// Set success handler
|
|
316
322
|
componentRef.current.onSuccess = (updatedData) => {
|
|
317
323
|
fetch(`/api/operators/${operatorId}`, {
|
|
318
|
-
method:
|
|
319
|
-
body: JSON.stringify(updatedData)
|
|
324
|
+
method: "PUT",
|
|
325
|
+
body: JSON.stringify(updatedData),
|
|
320
326
|
});
|
|
321
327
|
onClose();
|
|
322
328
|
};
|
|
323
329
|
}
|
|
324
330
|
}, [initialData, operatorId, onClose]);
|
|
325
|
-
|
|
331
|
+
|
|
326
332
|
if (!isOpen) return null;
|
|
327
|
-
|
|
333
|
+
|
|
328
334
|
return (
|
|
329
335
|
<div className="modal">
|
|
330
336
|
<operator-onboarding ref={componentRef} />
|
|
@@ -397,7 +403,7 @@ The component returns a complete data object:
|
|
|
397
403
|
✅ **Framework Friendly** - Easy integration with React, Vue, etc.
|
|
398
404
|
✅ **Shadow DOM** - Fully encapsulated styles
|
|
399
405
|
✅ **Zero Dependencies** - Pure vanilla JavaScript
|
|
400
|
-
✅ **API Integration** - Ready for backend integration
|
|
406
|
+
✅ **API Integration** - Ready for backend integration
|
|
401
407
|
|
|
402
408
|
---
|
|
403
409
|
|
|
@@ -405,25 +411,25 @@ The component returns a complete data object:
|
|
|
405
411
|
|
|
406
412
|
### Properties
|
|
407
413
|
|
|
408
|
-
| Property
|
|
409
|
-
|
|
410
|
-
| `onSuccess`
|
|
411
|
-
| `onError`
|
|
412
|
-
| `onLoad`
|
|
413
|
-
| `apiBaseURL`
|
|
414
|
-
| `embeddableKey` | `String`
|
|
414
|
+
| Property | Type | Description |
|
|
415
|
+
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------- |
|
|
416
|
+
| `onSuccess` | `Function` | Callback function called when form is successfully submitted. Receives complete form data as parameter. |
|
|
417
|
+
| `onError` | `Function` | Callback function called when submission fails. Receives error data as parameter. |
|
|
418
|
+
| `onLoad` | `Object` | Pre-populate form fields with initial data. Accepts partial or complete form data object. |
|
|
419
|
+
| `apiBaseURL` | `String` | Base URL for API endpoints. |
|
|
420
|
+
| `embeddableKey` | `String` | Authentication key for API requests. |
|
|
415
421
|
|
|
416
422
|
### Events
|
|
417
423
|
|
|
418
|
-
| Event
|
|
419
|
-
|
|
420
|
-
| `formComplete`
|
|
421
|
-
| `submissionFailed` | `Object` | Emitted when form submission fails. `event.detail` contains error information.
|
|
424
|
+
| Event | Detail | Description |
|
|
425
|
+
| ------------------ | -------- | ---------------------------------------------------------------------------------------- |
|
|
426
|
+
| `formComplete` | `Object` | Emitted when form is successfully submitted. `event.detail` contains complete form data. |
|
|
427
|
+
| `submissionFailed` | `Object` | Emitted when form submission fails. `event.detail` contains error information. |
|
|
422
428
|
|
|
423
429
|
### Global Functions
|
|
424
430
|
|
|
425
|
-
| Function
|
|
426
|
-
|
|
431
|
+
| Function | Parameters | Returns | Description |
|
|
432
|
+
| ------------------------------------------- | ---------------------------------------------- | --------- | ----------------------------------- |
|
|
427
433
|
| `verifyOperator(operatorEmail, mockResult)` | `operatorEmail: string`, `mockResult: boolean` | `boolean` | Verify if an operator email exists. |
|
|
428
434
|
|
|
429
435
|
---
|
|
@@ -434,14 +440,14 @@ You can verify operator emails:
|
|
|
434
440
|
|
|
435
441
|
```javascript
|
|
436
442
|
// Check if operator exists
|
|
437
|
-
const exists = verifyOperator(
|
|
443
|
+
const exists = verifyOperator("operator@company.com", true);
|
|
438
444
|
|
|
439
445
|
if (exists) {
|
|
440
446
|
// Proceed with operation
|
|
441
|
-
console.log(
|
|
447
|
+
console.log("Operator verified");
|
|
442
448
|
} else {
|
|
443
449
|
// Show error
|
|
444
|
-
console.error(
|
|
450
|
+
console.error("Operator not found");
|
|
445
451
|
}
|
|
446
452
|
```
|
|
447
453
|
|
|
@@ -456,15 +462,15 @@ The component provides comprehensive error handling:
|
|
|
456
462
|
When form submission fails:
|
|
457
463
|
|
|
458
464
|
```javascript
|
|
459
|
-
component.addEventListener(
|
|
465
|
+
component.addEventListener("submissionFailed", (event) => {
|
|
460
466
|
const { formData, message, timestamp } = event.detail;
|
|
461
|
-
console.error(
|
|
467
|
+
console.error("Submission failed:", message);
|
|
462
468
|
// Retry or show error
|
|
463
469
|
});
|
|
464
470
|
|
|
465
471
|
// Or use callback
|
|
466
472
|
component.onError = (errorData) => {
|
|
467
|
-
if (errorData.action ===
|
|
473
|
+
if (errorData.action === "resubmit") {
|
|
468
474
|
// User clicked resubmit button
|
|
469
475
|
// Your retry logic here
|
|
470
476
|
}
|
|
@@ -478,30 +484,31 @@ component.onError = (errorData) => {
|
|
|
478
484
|
```html
|
|
479
485
|
<div id="onboardingModal" class="modal">
|
|
480
486
|
<div class="modal-content">
|
|
481
|
-
<operator-onboarding
|
|
487
|
+
<operator-onboarding
|
|
482
488
|
on-success="closeOnboardingModal"
|
|
483
|
-
on-error="handleOnboardingError"
|
|
489
|
+
on-error="handleOnboardingError"
|
|
490
|
+
>
|
|
484
491
|
</operator-onboarding>
|
|
485
492
|
</div>
|
|
486
493
|
</div>
|
|
487
494
|
|
|
488
495
|
<script>
|
|
489
496
|
function closeOnboardingModal(data) {
|
|
490
|
-
console.log(
|
|
491
|
-
|
|
497
|
+
console.log("Onboarding complete for:", data.businessDetails.businessName);
|
|
498
|
+
|
|
492
499
|
// Close modal
|
|
493
|
-
document.getElementById(
|
|
494
|
-
|
|
500
|
+
document.getElementById("onboardingModal").style.display = "none";
|
|
501
|
+
|
|
495
502
|
// Send data to backend
|
|
496
|
-
fetch(
|
|
497
|
-
method:
|
|
498
|
-
headers: {
|
|
499
|
-
body: JSON.stringify(data)
|
|
503
|
+
fetch("/api/onboarding", {
|
|
504
|
+
method: "POST",
|
|
505
|
+
headers: { "Content-Type": "application/json" },
|
|
506
|
+
body: JSON.stringify(data),
|
|
500
507
|
});
|
|
501
508
|
}
|
|
502
|
-
|
|
509
|
+
|
|
503
510
|
function handleOnboardingError(errorData) {
|
|
504
|
-
console.error(
|
|
511
|
+
console.error("Onboarding error:", errorData);
|
|
505
512
|
// Show error notification
|
|
506
513
|
}
|
|
507
514
|
</script>
|
|
@@ -541,7 +548,7 @@ The API class is automatically exported when you load the component:
|
|
|
541
548
|
|
|
542
549
|
```javascript
|
|
543
550
|
// ES Module
|
|
544
|
-
import { BisonJibPayAPI } from
|
|
551
|
+
import { BisonJibPayAPI } from "./component.js";
|
|
545
552
|
|
|
546
553
|
// Or access from window (script tag)
|
|
547
554
|
const BisonJibPayAPI = window.BisonJibPayAPI;
|
|
@@ -552,67 +559,78 @@ const BisonJibPayAPI = window.BisonJibPayAPI;
|
|
|
552
559
|
```javascript
|
|
553
560
|
// Create API instance
|
|
554
561
|
const api = new BisonJibPayAPI(
|
|
555
|
-
|
|
556
|
-
|
|
562
|
+
"https://bison-jib-development.azurewebsites.net",
|
|
563
|
+
"YOUR_EMBEDDABLE_KEY",
|
|
557
564
|
);
|
|
558
565
|
|
|
559
566
|
// Validate operator email
|
|
560
567
|
try {
|
|
561
568
|
const result = await api.validateOperatorEmail(
|
|
562
|
-
|
|
563
|
-
|
|
569
|
+
"operator@example.com",
|
|
570
|
+
"OP123456",
|
|
564
571
|
);
|
|
565
|
-
console.log(
|
|
572
|
+
console.log("Operator email is valid:", result);
|
|
566
573
|
} catch (error) {
|
|
567
|
-
console.error(
|
|
574
|
+
console.error("Validation failed:", error);
|
|
568
575
|
}
|
|
569
576
|
|
|
570
577
|
// Register operator
|
|
571
578
|
const formData = new FormData();
|
|
572
|
-
formData.append(
|
|
573
|
-
formData.append(
|
|
579
|
+
formData.append("businessName", "Acme Corp");
|
|
580
|
+
formData.append("businessEmail", "contact@acme.com");
|
|
574
581
|
// ... add more fields
|
|
575
582
|
|
|
576
583
|
try {
|
|
577
584
|
const result = await api.registerOperator(formData);
|
|
578
|
-
console.log(
|
|
585
|
+
console.log("Operator registered successfully:", result);
|
|
579
586
|
} catch (error) {
|
|
580
|
-
console.error(
|
|
587
|
+
console.error("Registration failed:", error);
|
|
581
588
|
}
|
|
582
589
|
```
|
|
583
590
|
|
|
584
591
|
### API Methods
|
|
585
592
|
|
|
586
593
|
#### `validateOperatorEmail(email, operatorId)`
|
|
594
|
+
|
|
587
595
|
Validates an operator email address.
|
|
588
596
|
|
|
589
597
|
**Parameters:**
|
|
598
|
+
|
|
590
599
|
- `email` (string) - The operator email address to validate
|
|
591
600
|
- `operatorId` (string) - The operator ID to validate
|
|
592
601
|
|
|
593
602
|
**Returns:**
|
|
603
|
+
|
|
594
604
|
- Promise resolving to the API response
|
|
595
605
|
|
|
596
606
|
**Example:**
|
|
607
|
+
|
|
597
608
|
```javascript
|
|
598
|
-
const result = await api.validateOperatorEmail(
|
|
609
|
+
const result = await api.validateOperatorEmail(
|
|
610
|
+
"operator@company.com",
|
|
611
|
+
"OP123456",
|
|
612
|
+
);
|
|
599
613
|
```
|
|
600
614
|
|
|
601
615
|
#### `registerOperator(formData)`
|
|
616
|
+
|
|
602
617
|
Registers a new operator with complete form data.
|
|
603
618
|
|
|
604
619
|
**Parameters:**
|
|
620
|
+
|
|
605
621
|
- `formData` (FormData) - FormData object containing all operator information
|
|
606
622
|
|
|
607
623
|
**Returns:**
|
|
624
|
+
|
|
608
625
|
- Promise resolving to the API response
|
|
609
626
|
|
|
610
627
|
**Example:**
|
|
628
|
+
|
|
611
629
|
```javascript
|
|
612
630
|
const formData = new FormData();
|
|
613
|
-
formData.append(
|
|
614
|
-
formData.append(
|
|
615
|
-
formData.append(
|
|
631
|
+
formData.append("businessName", "Acme Corp");
|
|
632
|
+
formData.append("businessEmail", "contact@acme.com");
|
|
633
|
+
formData.append("ein", "12-3456789");
|
|
616
634
|
// ... add all required fields
|
|
617
635
|
|
|
618
636
|
const result = await api.registerOperator(formData);
|
|
@@ -621,16 +639,19 @@ const result = await api.registerOperator(formData);
|
|
|
621
639
|
### React Integration Example
|
|
622
640
|
|
|
623
641
|
```jsx
|
|
624
|
-
import { useEffect, useState } from
|
|
625
|
-
import { BisonJibPayAPI } from
|
|
642
|
+
import { useEffect, useState } from "react";
|
|
643
|
+
import { BisonJibPayAPI } from "./component.js";
|
|
626
644
|
|
|
627
645
|
function EmailValidator() {
|
|
628
|
-
const [api] = useState(
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
646
|
+
const [api] = useState(
|
|
647
|
+
() =>
|
|
648
|
+
new BisonJibPayAPI(
|
|
649
|
+
"https://bison-jib-development.azurewebsites.net",
|
|
650
|
+
"YOUR_KEY",
|
|
651
|
+
),
|
|
652
|
+
);
|
|
653
|
+
const [email, setEmail] = useState("");
|
|
654
|
+
const [operatorId, setOperatorId] = useState("");
|
|
634
655
|
const [isValid, setIsValid] = useState(null);
|
|
635
656
|
const [isLoading, setIsLoading] = useState(false);
|
|
636
657
|
|
|
@@ -641,7 +662,7 @@ function EmailValidator() {
|
|
|
641
662
|
setIsValid(true);
|
|
642
663
|
} catch (error) {
|
|
643
664
|
setIsValid(false);
|
|
644
|
-
console.error(
|
|
665
|
+
console.error("Validation failed:", error);
|
|
645
666
|
} finally {
|
|
646
667
|
setIsLoading(false);
|
|
647
668
|
}
|
|
@@ -662,11 +683,9 @@ function EmailValidator() {
|
|
|
662
683
|
placeholder="Enter operator email"
|
|
663
684
|
/>
|
|
664
685
|
<button onClick={validateEmail} disabled={isLoading}>
|
|
665
|
-
{isLoading ?
|
|
686
|
+
{isLoading ? "Validating..." : "Validate"}
|
|
666
687
|
</button>
|
|
667
|
-
{isValid !== null &&
|
|
668
|
-
<p>{isValid ? '✓ Valid' : '✗ Invalid'}</p>
|
|
669
|
-
)}
|
|
688
|
+
{isValid !== null && <p>{isValid ? "✓ Valid" : "✗ Invalid"}</p>}
|
|
670
689
|
</div>
|
|
671
690
|
);
|
|
672
691
|
}
|
|
@@ -678,15 +697,16 @@ The API methods throw structured errors that you can catch:
|
|
|
678
697
|
|
|
679
698
|
```javascript
|
|
680
699
|
try {
|
|
681
|
-
await api.validateOperatorEmail(
|
|
700
|
+
await api.validateOperatorEmail("invalid@email.com", "OP123456");
|
|
682
701
|
} catch (error) {
|
|
683
|
-
console.error(
|
|
684
|
-
console.error(
|
|
685
|
-
console.error(
|
|
702
|
+
console.error("Status:", error.status);
|
|
703
|
+
console.error("Message:", error.data.message);
|
|
704
|
+
console.error("Errors:", error.data.errors);
|
|
686
705
|
}
|
|
687
706
|
```
|
|
688
707
|
|
|
689
708
|
Error structure:
|
|
709
|
+
|
|
690
710
|
```javascript
|
|
691
711
|
{
|
|
692
712
|
status: 400, // HTTP status code
|
|
@@ -703,20 +723,20 @@ Error structure:
|
|
|
703
723
|
```javascript
|
|
704
724
|
// Development
|
|
705
725
|
const devApi = new BisonJibPayAPI(
|
|
706
|
-
|
|
707
|
-
|
|
726
|
+
"https://bison-jib-development.azurewebsites.net",
|
|
727
|
+
"DEV_KEY",
|
|
708
728
|
);
|
|
709
729
|
|
|
710
730
|
// Production
|
|
711
731
|
const prodApi = new BisonJibPayAPI(
|
|
712
|
-
|
|
713
|
-
|
|
732
|
+
"https://bison-jib-production.azurewebsites.net",
|
|
733
|
+
"PROD_KEY",
|
|
714
734
|
);
|
|
715
735
|
|
|
716
736
|
// Use environment variables
|
|
717
737
|
const api = new BisonJibPayAPI(
|
|
718
738
|
process.env.REACT_APP_API_URL,
|
|
719
|
-
process.env.REACT_APP_EMBEDDABLE_KEY
|
|
739
|
+
process.env.REACT_APP_EMBEDDABLE_KEY,
|
|
720
740
|
);
|
|
721
741
|
```
|
|
722
742
|
|
|
@@ -729,7 +749,8 @@ The component is designed to work with the BisonJibPay API. Configure your endpo
|
|
|
729
749
|
```html
|
|
730
750
|
<operator-onboarding
|
|
731
751
|
api-base-url="https://your-api-domain.com"
|
|
732
|
-
embeddable-key="your-embeddable-key"
|
|
752
|
+
embeddable-key="your-embeddable-key"
|
|
753
|
+
>
|
|
733
754
|
</operator-onboarding>
|
|
734
755
|
```
|
|
735
756
|
|