@test-glide/glide-payment 0.0.2 → 0.0.3
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 +233 -0
- package/dist/index.cjs.js +9 -9
- package/dist/index.es.js +153 -153
- package/dist/index.umd.js +9 -9
- package/dist/react/react.cjs.js +9 -9
- package/dist/react/react.es.js +147 -145
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# bivo-payments SDK
|
|
2
|
+
|
|
3
|
+
A highly flexible React SDK for adding card details. Supports both standalone form rendering and built-in modal overlays, and handles both individual and recipient (beneficiary) card flows.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @test-glide/glide-payment
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Import Methods
|
|
12
|
+
|
|
13
|
+
**For React:**
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { AddCard } from "@test-glide/glide-payment/react";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**For Vanilla JavaScript:**
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import * as BivoPayments from "@test-glide/glide-payment";
|
|
23
|
+
// or CommonJS: const BivoPayments = require("@test-glide/glide-payment");
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**For CSS Styling:**
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
import "@test-glide/glide-payment/style.css";
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
The SDK can be used in two ways: **React Component** or **Vanilla JavaScript API**.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## React Component
|
|
39
|
+
|
|
40
|
+
The `AddCard` React component supports **Inline** (default) or **Modal** rendering modes.
|
|
41
|
+
|
|
42
|
+
```jsx
|
|
43
|
+
import { AddCard } from "@test-glide/glide-payment/react";
|
|
44
|
+
import "@test-glide/glide-payment/style.css";
|
|
45
|
+
import { useState } from "react";
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
49
|
+
|
|
50
|
+
const handleResult = (result) => {
|
|
51
|
+
if (result.success) {
|
|
52
|
+
console.log("Success! Data:", result.data);
|
|
53
|
+
setIsOpen(false); // Close modal on success (for modal mode)
|
|
54
|
+
} else {
|
|
55
|
+
console.error("Error:", result.error);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<>
|
|
61
|
+
{/* Inline Mode: Form renders directly into the layout */}
|
|
62
|
+
<AddCard
|
|
63
|
+
token="your-session-token"
|
|
64
|
+
endpoint="your-api-endpoint"
|
|
65
|
+
onCallback={handleResult}
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
{/* Inline Mode with Beneficiary Card */}
|
|
69
|
+
<AddCard
|
|
70
|
+
token="your-session-token"
|
|
71
|
+
endpoint="your-api-endpoint"
|
|
72
|
+
onCallback={handleResult}
|
|
73
|
+
beneficiaryCard
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
{/* Modal Mode: Form opens in a controlled modal */}
|
|
77
|
+
<button onClick={() => setIsOpen(true)}>Add Card (Modal)</button>
|
|
78
|
+
|
|
79
|
+
<AddCard
|
|
80
|
+
isModal
|
|
81
|
+
isOpen={isOpen}
|
|
82
|
+
token="your-session-token"
|
|
83
|
+
endpoint="your-api-endpoint"
|
|
84
|
+
onCallback={handleResult}
|
|
85
|
+
onClose={() => console.log("Modal closed")}
|
|
86
|
+
/>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Key Points:**
|
|
93
|
+
|
|
94
|
+
- **Inline Mode** - Form renders directly into your layout. Default behavior.
|
|
95
|
+
- **Modal Mode** - Pass `isModal` and control visibility with `isOpen` prop. Component renders `null` to the DOM; modal is managed by SDK internally.
|
|
96
|
+
- **Beneficiary Card** - Add the `beneficiaryCard` prop in either mode to show recipient card flow.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Vanilla JavaScript API
|
|
101
|
+
|
|
102
|
+
For non-React applications, use the `init()` function from the main entry point:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
import * as BivoPayments from "@test-glide/glide-payment";
|
|
106
|
+
import "@test-glide/glide-payment/style.css";
|
|
107
|
+
|
|
108
|
+
// Initialize the SDK
|
|
109
|
+
const bivo = BivoPayments.init({
|
|
110
|
+
token: "your-session-token",
|
|
111
|
+
endpoint: "your-api-endpoint",
|
|
112
|
+
beneficiaryCard: false,
|
|
113
|
+
isModal: false,
|
|
114
|
+
onCallback: (result) => {
|
|
115
|
+
if (result.success) {
|
|
116
|
+
console.log("Success! Data:", result.data);
|
|
117
|
+
} else {
|
|
118
|
+
console.error("Error:", result.error);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Inline mode: mount to a DOM element
|
|
124
|
+
bivo.mount({ id: "my-form-container" });
|
|
125
|
+
|
|
126
|
+
// OR for modal mode
|
|
127
|
+
const bivoModal = BivoPayments.init({
|
|
128
|
+
token: "your-session-token",
|
|
129
|
+
endpoint: "your-api-endpoint",
|
|
130
|
+
isModal: true,
|
|
131
|
+
onCallback: handleCallback,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Control modal visibility
|
|
135
|
+
document.querySelector("#openBtn").addEventListener("click", () => {
|
|
136
|
+
bivoModal.open();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Close modal and clean up
|
|
140
|
+
bivo.destroy();
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Selector Options for `mount()`
|
|
144
|
+
|
|
145
|
+
The `mount()` method accepts one of three selector formats:
|
|
146
|
+
|
|
147
|
+
- **By element ID:** `mount({ id: "container-id" })`
|
|
148
|
+
- **By CSS class name:** `mount({ className: "form-container" })`
|
|
149
|
+
- **By DOM element reference:** `mount({ element: document.querySelector("#form") })`
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## React Component Props
|
|
154
|
+
|
|
155
|
+
The `AddCard` React component accepts the following props:
|
|
156
|
+
|
|
157
|
+
| Prop | Type | Required | Description |
|
|
158
|
+
| ----------------- | ---------- | ----------- | ------------------------------------------------------------------------------- |
|
|
159
|
+
| `token` | `string` | **Yes** | Session token for API authentication. |
|
|
160
|
+
| `endpoint` | `string` | **Yes** | API endpoint URL for card submission. |
|
|
161
|
+
| `onCallback` | `function` | No | Callback function receiving `{ success: boolean, data?: any, error?: string }`. |
|
|
162
|
+
| `onClose` | `function` | No | Callback function triggered when modal is closed (modal mode only). |
|
|
163
|
+
| `isModal` | `boolean` | No | If `true`, renders in modal mode. Defaults to `false`. |
|
|
164
|
+
| `isOpen` | `boolean` | Conditional | **Required if `isModal` is true.** Controls modal visibility. |
|
|
165
|
+
| `beneficiaryCard` | `boolean` | No | If `true`, shows recipient card flow. Defaults to `false` (individual flow). |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Vanilla JS API
|
|
170
|
+
|
|
171
|
+
### `init(options)` Function
|
|
172
|
+
|
|
173
|
+
Returns an object with the following methods:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
init(options: {
|
|
177
|
+
token: string;
|
|
178
|
+
endpoint: string;
|
|
179
|
+
beneficiaryCard?: boolean;
|
|
180
|
+
isModal?: boolean;
|
|
181
|
+
onCallback?: (args: { success: boolean; error?: string; data?: any }) => void;
|
|
182
|
+
onModalClose?: () => void;
|
|
183
|
+
}): {
|
|
184
|
+
mount(selector: Selector): void;
|
|
185
|
+
open(): void;
|
|
186
|
+
destroy(): void;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Methods:**
|
|
191
|
+
|
|
192
|
+
- **`mount(selector)`** - Mounts the form to a DOM element. Accepts one selector type: `{ id: string }`, `{ className: string }`, or `{ element: HTMLElement }`.
|
|
193
|
+
- **`open()`** - Opens the modal (only works if `isModal: true`).
|
|
194
|
+
- **`destroy()`** - Closes the modal and cleans up resources.
|
|
195
|
+
|
|
196
|
+
**Options:**
|
|
197
|
+
|
|
198
|
+
- **`onModalClose`** - Optional callback triggered when the modal is closed via `destroy()`.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Theming (CSS Variables)
|
|
203
|
+
|
|
204
|
+
The components in `@test-glide/glide-payment` can be easily themed by overriding the default CSS variables. Below is the list of available CSS variables with their default values and where they are used:
|
|
205
|
+
|
|
206
|
+
```css
|
|
207
|
+
:root {
|
|
208
|
+
--bivo-payments-font-family: inherit; /* Applied globally to AddCard and internal components */
|
|
209
|
+
|
|
210
|
+
--bivo-payments-bg: #ffffff; /* Main background color for AddCard form, Modal, Inputs, and Alerts */
|
|
211
|
+
--bivo-payments-bg-overlay: rgba(
|
|
212
|
+
0,
|
|
213
|
+
0,
|
|
214
|
+
0,
|
|
215
|
+
0.35
|
|
216
|
+
); /* Background color for the overlay behind modals and alerts */
|
|
217
|
+
--bivo-payments-bg-secondary: #f9f9f9; /* Secondary background color, e.g., Modal actions footer */
|
|
218
|
+
|
|
219
|
+
--bivo-payments-text: #000000; /* Primary text color used across headings, inputs, and form content */
|
|
220
|
+
--bivo-payments-text-secondary: #666666; /* Secondary text color for close buttons, labels, and descriptions */
|
|
221
|
+
--bivo-payments-placeholder: #999999; /* Placeholder text color in input fields */
|
|
222
|
+
|
|
223
|
+
--bivo-payments-border: #e3e5e9; /* Standard border color for inputs and dividers */
|
|
224
|
+
--bivo-payments-secondary: #eee; /* Divider line color (e.g., above modal footer) */
|
|
225
|
+
|
|
226
|
+
--bivo-payments-primary: #000000; /* Primary button background, active input borders, and primary confirm actions */
|
|
227
|
+
--bivo-payments-primary-text: #ffffff; /* Text color inside primary buttons */
|
|
228
|
+
|
|
229
|
+
--bivo-payments-info: #4a90e2; /* Info state text/borders, loading skeleton, and links */
|
|
230
|
+
--bivo-payments-success: #15803d; /* Success text color (e.g., success messages, valid checkmarks) */
|
|
231
|
+
--bivo-payments-danger: #eb5757; /* Error/Danger text color, error borders */
|
|
232
|
+
}
|
|
233
|
+
```
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(n,e={}){const t=document.createElement(n),{className:l,id:a,innerHTML:h,textContent:i,attributes:c,styles:p,dataset:s,children:r,events:m}=e;if(l){const d=Array.isArray(l)?l:l.split(" ");t.classList.add(...d.filter(Boolean))}if(a&&(t.id=a),h&&(t.innerHTML=h),i&&(t.textContent=i),c)for(const[d,o]of Object.entries(c))o&&t.setAttribute(d,o);if(p)for(const[d,o]of Object.entries(p))t.style[d]=o;if(s)for(const[d,o]of Object.entries(s))t.dataset[d]=o;if(r&&t.append(...r.filter(Boolean)),m)for(const[d,o]of Object.entries(m))t.addEventListener(d,o);return t}function x(n,e){const t="id"in n?[document.getElementById(n.id)].filter(Boolean):"className"in n?Array.from(document.getElementsByClassName(n.className)):[n.element];if(!t.length){console.warn("updateElements: no elements found for",n);return}for(const l of t){const{styles:a,attributes:h,dataset:i,innerHTML:c,textContent:p,className:s}=e;if(a)for(const[r,m]of Object.entries(a))l.style[r]=m;if(h)for(const[r,m]of Object.entries(h))l.setAttribute(r,m);if(i)for(const[r,m]of Object.entries(i))l.dataset[r]=m;if(c!==void 0&&(l.innerHTML=c),p!==void 0&&(l.textContent=p),s?.add){const r=Array.isArray(s.add)?s.add:[s.add];l.classList.add(...r)}if(s?.remove){const r=Array.isArray(s.remove)?s.remove:[s.remove];l.classList.remove(...r)}s?.toggle&&(Array.isArray(s.toggle)?s.toggle:[s.toggle]).forEach(m=>l.classList.toggle(m))}}const Q=`
|
|
2
2
|
<svg
|
|
3
3
|
xmlns="http://www.w3.org/2000/svg"
|
|
4
4
|
width="16"
|
|
@@ -45,28 +45,28 @@
|
|
|
45
45
|
></path>
|
|
46
46
|
</svg>`,k=`
|
|
47
47
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>
|
|
48
|
-
`,te=({children:n,onClick:e,disabled:t=!1,size:l="medium",type:
|
|
48
|
+
`,te=({children:n,onClick:e,disabled:t=!1,size:l="medium",type:a="button",className:h="",variant:i="primary"})=>{const c=u("span",{className:"button-spinner",innerHTML:X,dataset:{show:"false"}}),p=u("span",{className:"button-label",children:[null],textContent:n}),s=u("button",{className:`custom-button ${i} ${l} ${h}`,attributes:{type:a,...t?{disabled:"true"}:{}},events:{click:e},children:[c,p]}),r=(d=!1)=>{x({element:c},{dataset:{show:String(d)}}),m(d)},m=(d=!1)=>{d?s.setAttribute("disabled","true"):s.removeAttribute("disabled")};return{element:s,setLoading:r,setDisabled:m}},ne=({content:n,position:e="top",delay:t=200,maxWidth:l=250,className:a="",id:h=""})=>{var i=u("div",{className:`tooltip ${e} ${a}`,styles:{maxWidth:`${l}px`},attributes:{role:"tooltip"},dataset:{show:"false"},innerHTML:`
|
|
49
49
|
<div class="tooltip-content">${n}</div>
|
|
50
50
|
<div class="tooltip-arrow"></div>
|
|
51
|
-
`});let c=null;var
|
|
51
|
+
`});let c=null;var r=u("span",{className:"tooltip-trigger",innerHTML:k,events:{mouseenter:()=>{t>0?c=window.setTimeout(()=>{i.dataset.show="true",m()},t):(i.dataset.show="true",m())},mouseleave:()=>{c&&clearTimeout(c),i.dataset.show="false"}}});function m(){if(!r||!i)return;const o=r.getBoundingClientRect(),v=i.getBoundingClientRect(),y=8;let w,g;switch(e){case"top":w=o.top-v.height-y,g=o.left+o.width/2-v.width/2;break;case"bottom":w=o.bottom+y,g=o.left+o.width/2-v.width/2;break;case"left":w=o.top+o.height/2-v.height/2,g=o.left-v.width-y;break;case"right":w=o.top+o.height/2-v.height/2,g=o.right+y;break;default:w=o.top-v.height-y,g=o.left+o.width/2-v.width/2}const N=window.innerWidth,C=window.innerHeight;g<0&&(g=y),g+v.width>N&&(g=N-v.width-y),w<0&&(w=y),w+v.height>C&&(w=C-v.height-y),i.style.top=`${w}px`,i.style.left=`${g}px`}return u("div",{className:"tooltip-wrapper",id:`tooltip-${h}`,children:[r,i]})},se=n=>{const e={},t=Object.values(n).every(a=>!a||a.trim()===""),l=n.cardNumber?.replace(/\s/g,"");if(l?/^\d{13,19}$/.test(l)||(e.cardNumber="Card number must be 13-19 digits"):e.cardNumber="Card number is required",!n.expiryDate)e.expiryDate="Expiry date is required";else{const a=n.expiryDate.replace(/\D/g,"");if(a.length<4)e.expiryDate="Enter complete expiry date (MM/YY)";else{const h=parseInt(a.substring(0,2),10),i=parseInt(a.substring(2,4),10);if(isNaN(h)||h<1||h>12)e.expiryDate="Invalid month (must be 01-12)";else if(isNaN(i)||i<0||i>99)e.expiryDate="Invalid year";else{const c=new Date,p=c.getFullYear(),s=c.getMonth()+1,r=Math.floor(p/100)*100,m=r+i,d=r+100+i;let o;m>=p&&m<=p+20?o=m:(d>=p&&d<=p+20,o=d),o<p||o===p&&h<s?e.expiryDate="Card has expired":o>p+20&&(e.expiryDate="Expiry year is too far in the future")}}}return n.cvv?.trim()?/^\d{3,4}$/.test(n.cvv.trim())||(e.cvv="CVV must be 3 or 4 digits"):e.cvv="CVV is required",n.zipCode?.trim()?/^[A-Z0-9\s-]{3,10}$/i.test(n.zipCode.trim())||(e.zipCode="Invalid ZIP code format"):e.zipCode="Postal code is required",{isValid:Object.keys(e).length===0,errors:e,isEmpty:t}};function re(n){const e=parseInt(n,10);if(isNaN(e)||e<0||e>99)return null;const t=new Date().getFullYear(),l=Math.floor(t/100)*100;let a=l+e;return a>=t&&a<=t+20||(a=l+100+e,a>=t&&a<=t+20)?a:l+100+e}function V(n=""){return n.trim().replaceAll(/\s/g,"").replaceAll("-","")}const oe={card:n=>n.replace(/\s+/g,"").replace(/[^0-9]/gi,"").substring(0,16).match(/.{1,4}/g)?.join(" ")??"",phone:n=>{const e=n.replace(/\D/g,"").substring(0,10),t=e.match(/^(\d{3})(\d{3})(\d{4})$/);return t?`(${t[1]}) ${t[2]}-${t[3]}`:e},expiry:n=>{const e=n.replace(/\//g,"");return e.substring(0,2)+(n.length>2?"/":"")+e.substring(2,4)},cvv:n=>n.replace(/\D/g,"").substring(0,4),zip:n=>{const e=n.replace(/\D/g,"").substring(0,9);return e.length>5?`${e.substring(0,5)}-${e.substring(5)}`:e}};function ae(n,e){return e==="none"?n:oe[e](n)}const $=({label:n,maskType:e,id:t,name:l,type:a="text",placeholder:h="Enter value",tooltip:i="",onChange:c})=>{const p=["card","expiry","phone","cvv","zip"].includes(e)?"numeric":"",s=u("label",{className:"input-label",innerHTML:n,attributes:{for:t}});let r=!1;const d=u("input",{id:t||"input-id",className:"styled-input",attributes:{placeholder:h,type:a,inputMode:p,name:l},events:{input:o,blur:v,keydown:b=>{b.key==="Enter"&&(r=!0)}}});function o(b){const D=e!=="none"?ae(b?.target?.value,e):b?.target?.value;d.value=D,c?.(D)}function v(){r=!0,c?.(d?.value||"")}const y=u("div",{className:"input-loader",innerHTML:'<div class="loader"></div>',dataset:{show:"false"}}),w=i?u("div",{className:"input-right-element",children:[ne({content:i,id:t})]}):null,g=u("div",{className:"input-wrapper",children:[d,y,w]}),N=u("div",{className:"error-message",dataset:{show:"false"},innerHTML:`
|
|
52
52
|
${k}
|
|
53
53
|
<span></span>
|
|
54
|
-
`});return{element:
|
|
54
|
+
`});return{element:u("div",{className:"custom-input-group",children:[s,g,N]}),setLoading:b=>{x({element:g},{dataset:{loading:b?"true":"false"}}),x({element:d},{attributes:{disabled:b?"true":"false"}}),x({element:y},{dataset:{show:b?"true":"false"}})},setError:(b="")=>{x({element:g},{className:b&&r?{add:"input-error"}:{remove:"input-error"}}),x({element:N},{dataset:{show:b&&r?"true":"false"},innerHTML:`
|
|
55
55
|
${k}
|
|
56
56
|
<span>${b||""}</span>
|
|
57
|
-
`})}}},ie=async(n,e={})=>{const{method:t="GET",headers:l={},body:
|
|
57
|
+
`})}}},ie=async(n,e={})=>{const{method:t="GET",headers:l={},body:a=null,...h}=e;try{const i={method:t,headers:{Accept:"*/*","Content-Type":"application/json",...l},...h};a&&["POST","PUT","PATCH","DELETE"].includes(t.toUpperCase())&&(i.body=typeof a=="string"?a:JSON.stringify(a));const c=await fetch(n,i),p=c.headers.get("content-type");let s;if(p?.includes("application/json")?s=await c.json():s=await c.text(),!c.ok){const r=s;throw new Error(r?.message||`HTTP error! status: ${c.status}`)}return{data:s,error:null}}catch(i){return{data:null,error:i instanceof Error?i.message:"An error occurred"}}},le=({title:n="",children:e,onClose:t,showBackBtn:l=!1,showCloseBtn:a=!0})=>{const h=u("button",{className:"back-btn",innerHTML:ee,dataset:{show:String(l)},events:{click:()=>m()}}),i=u("h3",{textContent:n}),c=u("button",{className:"close-btn",innerHTML:"×",dataset:{show:String(a)},attributes:{"aria-label":"Close modal"},events:{click:()=>m()}}),p=u("div",{className:"modal-header",children:[h,i,c]}),s=u("div",{className:"modal-content",children:[e]}),r=u("dialog",{className:"custom-modal",children:[p,s],events:{cancel:o=>{o.preventDefault(),m()}}}),m=()=>{r.close(),t?.()};return{element:r,setModalVisibility:o=>{o?r.showModal():r.close()}}},ce=({token:n,endpoint:e,beneficiaryCard:t=!1,isModal:l=!1,onCallback:a=()=>null})=>{const h=t?"Enter Recipient Debit Card Details":"Enter Your Debit Card Details",i=t?"Enter the debit card details of the recipient you're sending funds to.":"Linking an external account allows you to send and receive money to your account.",c=t?"Debit Card Number":"Your Debit Card Number",p=t?"Enter recipient's card number":"Enter your card number",s=`add-card-form-wrapper${t?" recipient-form":""}`,r={cardNumber:"",expiryDate:"",cvv:"",zipCode:""},{element:m,setError:d}=$({label:c,placeholder:p,id:"card-number-input",name:"cardNumber",maskType:"card",onChange(f){L("cardNumber",f,d)}}),{element:o,setError:v}=$({label:"Expiration Date",placeholder:"MM/YY",id:"expiry-input",name:"expiryDate",maskType:"expiry",onChange(f){L("expiryDate",f,v)}}),{element:y,setError:w}=$({label:"CVV",placeholder:"3-Digit",type:"number",maskType:"cvv",id:"cvv-input",name:"cvv",tooltip:"A CVV is a 3-digit number on your debit card. You can find it on the back side of the card.",onChange(f){L("cvv",f,w)}}),{element:g,setError:N}=$({label:"ZIP Code",placeholder:t?"ZIP Code":"Enter your ZIP Code",id:"zip-input",name:"zipCode",maskType:"zip",onChange(f){L("zipCode",f,N)}}),C=u("div",{className:t?"input-sections":"inputs",children:[m,o,y,g]}),A=u("p",{className:"submit-error",dataset:{show:"false"}}),{element:j,setDisabled:b,setLoading:D}=te({children:"Link Card",type:"submit",disabled:!0}),S=(f="")=>{x({element:A},{dataset:{show:String(!!f)},innerHTML:`
|
|
58
58
|
${k}
|
|
59
59
|
${f||""}
|
|
60
|
-
`})},B=(f=!0)=>{b(f),D(f)};function L(f,H,E){
|
|
61
|
-
<p>${
|
|
60
|
+
`})},B=(f=!0)=>{b(f),D(f)};function L(f,H,E){r[f]=H;const{isValid:I,errors:T}=se(r);T[f]?E(T[f]):E(""),b(!I)}const O=u("div",{className:"submit-button-wrapper",children:[A,j]});async function P(f){f.preventDefault();const H=new FormData(f.target),E=Object.fromEntries(H.entries());console.log(E);const I=E?.cardNumber,T=E?.expiryDate,_=E?.cvv,G=E?.zipCode,K=Number(T?.split("/")[0]),U=re(T?.split("/")[1]),J=V(I);B(!0),S("");const M=await ie(e,{method:"POST",body:{token:n,pan:J,expiry_month:K,expiry_year:U,cvv:V(_),address:{postal_code:V(G)}}});M.error?(console.error("Request failed:",M.error),B(!1),S(M.error),a?.({success:!1,error:M.error})):(console.log("Request success:",M.data),B(!1),a?.({success:!0,data:M.data}))}const Z=()=>u("form",{events:{submit:P},children:[C,O]}),W=()=>u("div",{className:"form-title",innerHTML:`
|
|
61
|
+
<p>${i}</p>
|
|
62
62
|
|
|
63
63
|
<div>
|
|
64
64
|
${Q}
|
|
65
65
|
|
|
66
66
|
<span>Secured with 256-bit encryption</span>
|
|
67
67
|
</div>
|
|
68
|
-
`}),z=()=>
|
|
68
|
+
`}),z=()=>u("div",{className:l?"":"non-modal-content",children:[W(),Z()]}),q=l?null:u("div",{className:`${s} non-modal`,children:[u("div",{className:"non-modal-header",innerHTML:`
|
|
69
69
|
<span></span>
|
|
70
70
|
<h3>${h}</h3>
|
|
71
71
|
<span></span>
|
|
72
|
-
`}),z()]}),{element:Y,setModalVisibility:F}=l?le({title:h,children:z()}):{element:null,setModalVisibility:()=>{}};function R(){Y&&(document.body.appendChild(
|
|
72
|
+
`}),z()]}),{element:Y,setModalVisibility:F}=l?le({title:h,children:z()}):{element:null,setModalVisibility:()=>{}};function R(){Y&&(document.body.appendChild(u("div",{className:s,children:[Y]})),F(!0))}return{renderFormWithModal:R,nonModalForm:q,closeModal:()=>F(!1)}};function de({token:n,endpoint:e,beneficiaryCard:t,isModal:l,onCallback:a,onModalClose:h}){const{renderFormWithModal:i,nonModalForm:c,closeModal:p}=ce({token:n,endpoint:e,beneficiaryCard:t,isModal:l,onCallback:a});return{mount(s){const r="className"in s?document.querySelector(s.className):"id"in s?document.getElementById(s.id):s.element;r&&c&&r.appendChild(c)},open(){i()},destroy(){p(),h?.()}}}exports.init=de;
|