intrpay-payments 1.0.6 → 1.1.1
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 +19 -10
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -104,16 +104,25 @@ function App() {
|
|
|
104
104
|
|
|
105
105
|
### PaymentParams
|
|
106
106
|
|
|
107
|
-
| Param
|
|
108
|
-
|
|
|
109
|
-
| `amount`
|
|
110
|
-
| `firstName`
|
|
111
|
-
| `lastName`
|
|
112
|
-
| `email`
|
|
113
|
-
| `phone`
|
|
114
|
-
| `companyName`
|
|
115
|
-
| `showContactForm`
|
|
116
|
-
| `checkoutItems`
|
|
107
|
+
| Param | Type | Description |
|
|
108
|
+
| ---------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
109
|
+
| `amount` | `number` | Payment amount |
|
|
110
|
+
| `firstName` | `string` | Customer's first name |
|
|
111
|
+
| `lastName` | `string` | Customer's last name |
|
|
112
|
+
| `email` | `string` | Customer's email |
|
|
113
|
+
| `phone` | `string` | Customer's phone number |
|
|
114
|
+
| `companyName` | `string` | Company name |
|
|
115
|
+
| `showContactForm` | `boolean` | Whether to show the contact form |
|
|
116
|
+
| `checkoutItems` | `string[]` | Checkout item IDs (sent as `checkout_items`, comma-separated in the URL) |
|
|
117
|
+
| `allowPartialPayments` | `boolean` | Whether to allow partial payment |
|
|
118
|
+
| `description` | `string` | Payment description |
|
|
119
|
+
| `primaryColor` | `string` | Primary theme color (hex, e.g. `'#000076'`) |
|
|
120
|
+
| `secondaryColor` | `string` | Secondary theme color (hex, e.g. `'#4774c0'`) |
|
|
121
|
+
| `textColor` | `string` | Text color (hex, e.g. `'#f3fcff'`) |
|
|
122
|
+
| `logo` | `string` | Logo URL |
|
|
123
|
+
| `buttonText` | `string` | Custom button text |
|
|
124
|
+
| `showHeader` | `boolean` | Whether to show the header |
|
|
125
|
+
| `paymentMethod` | `'card' \| 'daf' \| 'ojc' \| 'pledger' \| 'donorsFund' \| 'matbia'` | Lock to a specific payment method |
|
|
117
126
|
|
|
118
127
|
## License
|
|
119
128
|
|
package/dist/index.cjs
CHANGED
|
@@ -35,13 +35,13 @@ var baseParams = {
|
|
|
35
35
|
showHeader: false
|
|
36
36
|
};
|
|
37
37
|
function buildPaymentUrl(paymentLinkId, params) {
|
|
38
|
-
const url = new URL(`${BASE_URL}/${paymentLinkId}`);
|
|
38
|
+
const url = new URL(`${BASE_URL}/pay/${paymentLinkId}`);
|
|
39
39
|
const combinedParams = { ...baseParams, ...params };
|
|
40
40
|
Object.entries(combinedParams).forEach(([key, value]) => {
|
|
41
41
|
if (value === void 0 || value === null) return;
|
|
42
42
|
if (key === "checkoutItems" && Array.isArray(value)) {
|
|
43
43
|
if (value.length > 0) {
|
|
44
|
-
url.searchParams.set("
|
|
44
|
+
url.searchParams.set("checkoutItems", value.join(","));
|
|
45
45
|
}
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
@@ -85,7 +85,7 @@ function PaymentDrawer({
|
|
|
85
85
|
onClose,
|
|
86
86
|
paymentLinkId,
|
|
87
87
|
params,
|
|
88
|
-
width =
|
|
88
|
+
width = 550,
|
|
89
89
|
position = "right",
|
|
90
90
|
showOverlay = true,
|
|
91
91
|
onSuccess,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/PaymentDrawer.tsx","../src/payment-shared.ts","../src/components/PaymentEmbed.tsx"],"sourcesContent":["export { PaymentDrawer } from './components/PaymentDrawer';\nexport { PaymentEmbed } from './components/PaymentEmbed';\nexport type { PaymentDrawerProps, PaymentParams } from './components/PaymentDrawer';\nexport type { PaymentEmbedProps } from './components/PaymentEmbed';\n","import React, { useEffect, useCallback, CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport type { PaymentParams };\n\nexport interface PaymentDrawerProps {\n /** Whether the drawer is open */\n open: boolean;\n /** Callback when the drawer should close */\n onClose: () => void;\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Width of the drawer (default: 400px) */\n width?: string | number;\n /** Position of the drawer */\n position?: \"left\" | \"right\";\n /** Whether to show overlay backdrop */\n showOverlay?: boolean;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Whether clicking overlay closes the drawer */\n closeOnOverlayClick?: boolean;\n /** Z-index for the drawer */\n zIndex?: number;\n}\n\nexport function PaymentDrawer({\n open,\n onClose,\n paymentLinkId,\n params,\n width = 500,\n position = \"right\",\n showOverlay = true,\n onSuccess,\n onFailure,\n closeOnOverlayClick = true,\n zIndex = 2000,\n}: PaymentDrawerProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && open) {\n onClose();\n }\n },\n [open, onClose],\n );\n\n useEffect(() => {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n document.body.style.overflow = \"hidden\";\n } else {\n document.body.style.overflow = \"\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open]);\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n onClose();\n }\n };\n\n const drawerWidth = typeof width === \"number\" ? `${width}px` : width;\n\n const styles: Record<string, CSSProperties> = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n zIndex,\n opacity: open ? 1 : 0,\n visibility: open ? \"visible\" : \"hidden\",\n transition: \"opacity 0.3s ease, visibility 0.3s ease\",\n },\n drawer: {\n position: \"fixed\",\n top: 0,\n bottom: 0,\n [position]: 0,\n width: drawerWidth,\n maxWidth: \"100%\",\n backgroundColor: \"#ffffff\",\n zIndex: zIndex + 1,\n boxShadow:\n position === \"right\"\n ? \"-4px 0 20px rgba(0, 0, 0, 0.15)\"\n : \"4px 0 20px rgba(0, 0, 0, 0.15)\",\n transform: open\n ? \"translateX(0)\"\n : `translateX(${position === \"right\" ? \"100%\" : \"-100%\"})`,\n transition: \"transform 0.3s ease\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n closeButton: {\n position: \"absolute\",\n top: 12,\n right: 12,\n width: 36,\n height: 36,\n border: \"1px solid rgba(0, 0, 0, 0.2)\",\n backgroundColor: \"#ffffff\",\n borderRadius: \"50%\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#000000\",\n zIndex: 10,\n boxShadow: \"0 1px 4px rgba(0, 0, 0, 0.2)\",\n },\n content: {\n flex: 1,\n overflow: \"hidden\",\n },\n iframe: {\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n },\n };\n\n return (\n <>\n {showOverlay && (\n <div\n style={styles.overlay}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <div\n style={styles.drawer}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Payment\"\n >\n <button\n style={styles.closeButton}\n onClick={onClose}\n aria-label=\"Close drawer\"\n type=\"button\"\n onMouseEnter={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.color = \"#000000\";\n }}\n onMouseLeave={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#ffffff\";\n e.currentTarget.style.color = \"#000000\";\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n <div style={styles.content}>\n <iframe\n src={open ? iframeUrl : \"about:blank\"}\n title=\"Payment\"\n style={styles.iframe}\n allow=\"payment; clipboard-write\"\n />\n </div>\n </div>\n </>\n );\n}\n","import { useEffect, useMemo } from \"react\";\n\nexport const BASE_URL = \"https://pay.intrpay.us\";\n\nconst baseParams = {\n showHeader: false,\n};\n\nexport interface PaymentParams {\n /** Payment amount */\n amount?: number;\n /** Customer's first name */\n firstName?: string;\n /** Customer's last name */\n lastName?: string;\n /** Customer's email */\n email?: string;\n /** Customer's phone number */\n phone?: string;\n /** Company name */\n companyName?: string;\n /** Whether to show the contact form */\n showContactForm?: boolean;\n /** Checkout item IDs (sent as checkout_items, comma-separated) */\n checkoutItems?: string[];\n}\n\nexport function buildPaymentUrl(\n paymentLinkId: string,\n params?: PaymentParams\n): string {\n const url = new URL(`${BASE_URL}/${paymentLinkId}`);\n const combinedParams = { ...baseParams, ...params };\n\n Object.entries(combinedParams).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (key === \"checkoutItems\" && Array.isArray(value)) {\n if (value.length > 0) {\n url.searchParams.set(\"checkout_items\", value.join(\",\"));\n }\n return;\n }\n if (value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n });\n\n return url.toString();\n}\n\nexport interface UsePaymentIframeOptions {\n paymentLinkId: string;\n params?: PaymentParams;\n onSuccess?: (data: unknown) => void;\n onFailure?: (data: unknown) => void;\n}\n\nexport function usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n}: UsePaymentIframeOptions) {\n const iframeUrl = useMemo(\n () => buildPaymentUrl(paymentLinkId, params),\n [paymentLinkId, params]\n );\n\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== BASE_URL) return;\n\n const data = event.data ?? {};\n const { type } = data as { type?: string };\n\n if (type === \"payment_success\") {\n onSuccess?.(data);\n } else if (type === \"payment_failure\") {\n onFailure?.(data);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [onSuccess, onFailure]);\n\n return { iframeUrl };\n}\n","import React, { CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport interface PaymentEmbedProps {\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Height of the iframe (default: 400px) */\n height?: string | number;\n /** Width of the iframe (default: 100%) */\n width?: string | number;\n /** Optional CSS class name */\n className?: string;\n /** Optional inline styles for the container */\n style?: CSSProperties;\n}\n\nexport function PaymentEmbed({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n height = 400,\n width = \"100%\",\n className,\n style,\n}: PaymentEmbedProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const iframeHeight = typeof height === \"number\" ? `${height}px` : height;\n const iframeWidth = typeof width === \"number\" ? `${width}px` : width;\n\n return (\n <div className={className} style={style}>\n <iframe\n src={iframeUrl}\n title=\"Payment\"\n style={{\n width: iframeWidth,\n height: iframeHeight,\n border: \"none\",\n }}\n allow=\"payment; clipboard-write\"\n />\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/PaymentDrawer.tsx","../src/payment-shared.ts","../src/components/PaymentEmbed.tsx"],"sourcesContent":["export { PaymentDrawer } from './components/PaymentDrawer';\nexport { PaymentEmbed } from './components/PaymentEmbed';\nexport type { PaymentDrawerProps, PaymentParams } from './components/PaymentDrawer';\nexport type { PaymentEmbedProps } from './components/PaymentEmbed';\n","import React, { useEffect, useCallback, CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport type { PaymentParams };\n\nexport interface PaymentDrawerProps {\n /** Whether the drawer is open */\n open: boolean;\n /** Callback when the drawer should close */\n onClose: () => void;\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Width of the drawer (default: 400px) */\n width?: string | number;\n /** Position of the drawer */\n position?: \"left\" | \"right\";\n /** Whether to show overlay backdrop */\n showOverlay?: boolean;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Whether clicking overlay closes the drawer */\n closeOnOverlayClick?: boolean;\n /** Z-index for the drawer */\n zIndex?: number;\n}\n\nexport function PaymentDrawer({\n open,\n onClose,\n paymentLinkId,\n params,\n width = 550,\n position = \"right\",\n showOverlay = true,\n onSuccess,\n onFailure,\n closeOnOverlayClick = true,\n zIndex = 2000,\n}: PaymentDrawerProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && open) {\n onClose();\n }\n },\n [open, onClose],\n );\n\n useEffect(() => {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n document.body.style.overflow = \"hidden\";\n } else {\n document.body.style.overflow = \"\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open]);\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n onClose();\n }\n };\n\n const drawerWidth = typeof width === \"number\" ? `${width}px` : width;\n\n const styles: Record<string, CSSProperties> = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n zIndex,\n opacity: open ? 1 : 0,\n visibility: open ? \"visible\" : \"hidden\",\n transition: \"opacity 0.3s ease, visibility 0.3s ease\",\n },\n drawer: {\n position: \"fixed\",\n top: 0,\n bottom: 0,\n [position]: 0,\n width: drawerWidth,\n maxWidth: \"100%\",\n backgroundColor: \"#ffffff\",\n zIndex: zIndex + 1,\n boxShadow:\n position === \"right\"\n ? \"-4px 0 20px rgba(0, 0, 0, 0.15)\"\n : \"4px 0 20px rgba(0, 0, 0, 0.15)\",\n transform: open\n ? \"translateX(0)\"\n : `translateX(${position === \"right\" ? \"100%\" : \"-100%\"})`,\n transition: \"transform 0.3s ease\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n closeButton: {\n position: \"absolute\",\n top: 12,\n right: 12,\n width: 36,\n height: 36,\n border: \"1px solid rgba(0, 0, 0, 0.2)\",\n backgroundColor: \"#ffffff\",\n borderRadius: \"50%\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#000000\",\n zIndex: 10,\n boxShadow: \"0 1px 4px rgba(0, 0, 0, 0.2)\",\n },\n content: {\n flex: 1,\n overflow: \"hidden\",\n },\n iframe: {\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n },\n };\n\n return (\n <>\n {showOverlay && (\n <div\n style={styles.overlay}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <div\n style={styles.drawer}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Payment\"\n >\n <button\n style={styles.closeButton}\n onClick={onClose}\n aria-label=\"Close drawer\"\n type=\"button\"\n onMouseEnter={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.color = \"#000000\";\n }}\n onMouseLeave={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#ffffff\";\n e.currentTarget.style.color = \"#000000\";\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n <div style={styles.content}>\n <iframe\n src={open ? iframeUrl : \"about:blank\"}\n title=\"Payment\"\n style={styles.iframe}\n allow=\"payment; clipboard-write\"\n />\n </div>\n </div>\n </>\n );\n}\n","import { useEffect, useMemo } from \"react\";\n\nexport const BASE_URL = \"https://pay.intrpay.us\";\n\nconst baseParams = {\n showHeader: false,\n};\n\nexport interface PaymentParams {\n /** Payment amount */\n amount?: number;\n /** Customer's first name */\n firstName?: string;\n /** Customer's last name */\n lastName?: string;\n /** Customer's email */\n email?: string;\n /** Customer's phone number */\n phone?: string;\n /** Company name */\n companyName?: string;\n /** Whether to show the contact form */\n showContactForm?: boolean;\n /** Checkout item IDs (sent as checkout_items, comma-separated) */\n checkoutItems?: string[];\n /** Whether to allow partial payment */\n allowPartialPayments?: boolean;\n /** Payment description */\n description?: string;\n /** Primary theme color (hex, e.g. '#000076') */\n primaryColor?: string;\n /** Secondary theme color (hex, e.g. '#4774c0') */\n secondaryColor?: string;\n /** Text color (hex, e.g. '#f3fcff') */\n textColor?: string;\n /** Logo URL */\n logo?: string;\n /** Custom button text */\n buttonText?: string;\n /** Whether to show the header */\n showHeader?: boolean;\n /** Lock to a specific payment method */\n paymentMethod?: 'card' | 'daf' | 'ojc' | 'pledger' | 'donorsFund' | 'matbia';\n}\n\nexport function buildPaymentUrl(\n paymentLinkId: string,\n params?: PaymentParams\n): string {\n const url = new URL(`${BASE_URL}/pay/${paymentLinkId}`);\n const combinedParams = { ...baseParams, ...params };\n\n Object.entries(combinedParams).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (key === \"checkoutItems\" && Array.isArray(value)) {\n if (value.length > 0) {\n url.searchParams.set(\"checkoutItems\", value.join(\",\"));\n }\n return;\n }\n if (value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n });\n\n return url.toString();\n}\n\nexport interface UsePaymentIframeOptions {\n paymentLinkId: string;\n params?: PaymentParams;\n onSuccess?: (data: unknown) => void;\n onFailure?: (data: unknown) => void;\n}\n\nexport function usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n}: UsePaymentIframeOptions) {\n const iframeUrl = useMemo(\n () => buildPaymentUrl(paymentLinkId, params),\n [paymentLinkId, params]\n );\n\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== BASE_URL) return;\n\n const data = event.data ?? {};\n const { type } = data as { type?: string };\n\n if (type === \"payment_success\") {\n onSuccess?.(data);\n } else if (type === \"payment_failure\") {\n onFailure?.(data);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [onSuccess, onFailure]);\n\n return { iframeUrl };\n}\n","import React, { CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport interface PaymentEmbedProps {\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Height of the iframe (default: 400px) */\n height?: string | number;\n /** Width of the iframe (default: 100%) */\n width?: string | number;\n /** Optional CSS class name */\n className?: string;\n /** Optional inline styles for the container */\n style?: CSSProperties;\n}\n\nexport function PaymentEmbed({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n height = 400,\n width = \"100%\",\n className,\n style,\n}: PaymentEmbedProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const iframeHeight = typeof height === \"number\" ? `${height}px` : height;\n const iframeWidth = typeof width === \"number\" ? `${width}px` : width;\n\n return (\n <div className={className} style={style}>\n <iframe\n src={iframeUrl}\n title=\"Payment\"\n style={{\n width: iframeWidth,\n height: iframeHeight,\n border: \"none\",\n }}\n allow=\"payment; clipboard-write\"\n />\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -18,6 +18,24 @@ interface PaymentParams {
|
|
|
18
18
|
showContactForm?: boolean;
|
|
19
19
|
/** Checkout item IDs (sent as checkout_items, comma-separated) */
|
|
20
20
|
checkoutItems?: string[];
|
|
21
|
+
/** Whether to allow partial payment */
|
|
22
|
+
allowPartialPayments?: boolean;
|
|
23
|
+
/** Payment description */
|
|
24
|
+
description?: string;
|
|
25
|
+
/** Primary theme color (hex, e.g. '#000076') */
|
|
26
|
+
primaryColor?: string;
|
|
27
|
+
/** Secondary theme color (hex, e.g. '#4774c0') */
|
|
28
|
+
secondaryColor?: string;
|
|
29
|
+
/** Text color (hex, e.g. '#f3fcff') */
|
|
30
|
+
textColor?: string;
|
|
31
|
+
/** Logo URL */
|
|
32
|
+
logo?: string;
|
|
33
|
+
/** Custom button text */
|
|
34
|
+
buttonText?: string;
|
|
35
|
+
/** Whether to show the header */
|
|
36
|
+
showHeader?: boolean;
|
|
37
|
+
/** Lock to a specific payment method */
|
|
38
|
+
paymentMethod?: 'card' | 'daf' | 'ojc' | 'pledger' | 'donorsFund' | 'matbia';
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
interface PaymentDrawerProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,24 @@ interface PaymentParams {
|
|
|
18
18
|
showContactForm?: boolean;
|
|
19
19
|
/** Checkout item IDs (sent as checkout_items, comma-separated) */
|
|
20
20
|
checkoutItems?: string[];
|
|
21
|
+
/** Whether to allow partial payment */
|
|
22
|
+
allowPartialPayments?: boolean;
|
|
23
|
+
/** Payment description */
|
|
24
|
+
description?: string;
|
|
25
|
+
/** Primary theme color (hex, e.g. '#000076') */
|
|
26
|
+
primaryColor?: string;
|
|
27
|
+
/** Secondary theme color (hex, e.g. '#4774c0') */
|
|
28
|
+
secondaryColor?: string;
|
|
29
|
+
/** Text color (hex, e.g. '#f3fcff') */
|
|
30
|
+
textColor?: string;
|
|
31
|
+
/** Logo URL */
|
|
32
|
+
logo?: string;
|
|
33
|
+
/** Custom button text */
|
|
34
|
+
buttonText?: string;
|
|
35
|
+
/** Whether to show the header */
|
|
36
|
+
showHeader?: boolean;
|
|
37
|
+
/** Lock to a specific payment method */
|
|
38
|
+
paymentMethod?: 'card' | 'daf' | 'ojc' | 'pledger' | 'donorsFund' | 'matbia';
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
interface PaymentDrawerProps {
|
package/dist/index.js
CHANGED
|
@@ -8,13 +8,13 @@ var baseParams = {
|
|
|
8
8
|
showHeader: false
|
|
9
9
|
};
|
|
10
10
|
function buildPaymentUrl(paymentLinkId, params) {
|
|
11
|
-
const url = new URL(`${BASE_URL}/${paymentLinkId}`);
|
|
11
|
+
const url = new URL(`${BASE_URL}/pay/${paymentLinkId}`);
|
|
12
12
|
const combinedParams = { ...baseParams, ...params };
|
|
13
13
|
Object.entries(combinedParams).forEach(([key, value]) => {
|
|
14
14
|
if (value === void 0 || value === null) return;
|
|
15
15
|
if (key === "checkoutItems" && Array.isArray(value)) {
|
|
16
16
|
if (value.length > 0) {
|
|
17
|
-
url.searchParams.set("
|
|
17
|
+
url.searchParams.set("checkoutItems", value.join(","));
|
|
18
18
|
}
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
@@ -58,7 +58,7 @@ function PaymentDrawer({
|
|
|
58
58
|
onClose,
|
|
59
59
|
paymentLinkId,
|
|
60
60
|
params,
|
|
61
|
-
width =
|
|
61
|
+
width = 550,
|
|
62
62
|
position = "right",
|
|
63
63
|
showOverlay = true,
|
|
64
64
|
onSuccess,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/PaymentDrawer.tsx","../src/payment-shared.ts","../src/components/PaymentEmbed.tsx"],"sourcesContent":["import React, { useEffect, useCallback, CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport type { PaymentParams };\n\nexport interface PaymentDrawerProps {\n /** Whether the drawer is open */\n open: boolean;\n /** Callback when the drawer should close */\n onClose: () => void;\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Width of the drawer (default: 400px) */\n width?: string | number;\n /** Position of the drawer */\n position?: \"left\" | \"right\";\n /** Whether to show overlay backdrop */\n showOverlay?: boolean;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Whether clicking overlay closes the drawer */\n closeOnOverlayClick?: boolean;\n /** Z-index for the drawer */\n zIndex?: number;\n}\n\nexport function PaymentDrawer({\n open,\n onClose,\n paymentLinkId,\n params,\n width = 500,\n position = \"right\",\n showOverlay = true,\n onSuccess,\n onFailure,\n closeOnOverlayClick = true,\n zIndex = 2000,\n}: PaymentDrawerProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && open) {\n onClose();\n }\n },\n [open, onClose],\n );\n\n useEffect(() => {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n document.body.style.overflow = \"hidden\";\n } else {\n document.body.style.overflow = \"\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open]);\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n onClose();\n }\n };\n\n const drawerWidth = typeof width === \"number\" ? `${width}px` : width;\n\n const styles: Record<string, CSSProperties> = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n zIndex,\n opacity: open ? 1 : 0,\n visibility: open ? \"visible\" : \"hidden\",\n transition: \"opacity 0.3s ease, visibility 0.3s ease\",\n },\n drawer: {\n position: \"fixed\",\n top: 0,\n bottom: 0,\n [position]: 0,\n width: drawerWidth,\n maxWidth: \"100%\",\n backgroundColor: \"#ffffff\",\n zIndex: zIndex + 1,\n boxShadow:\n position === \"right\"\n ? \"-4px 0 20px rgba(0, 0, 0, 0.15)\"\n : \"4px 0 20px rgba(0, 0, 0, 0.15)\",\n transform: open\n ? \"translateX(0)\"\n : `translateX(${position === \"right\" ? \"100%\" : \"-100%\"})`,\n transition: \"transform 0.3s ease\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n closeButton: {\n position: \"absolute\",\n top: 12,\n right: 12,\n width: 36,\n height: 36,\n border: \"1px solid rgba(0, 0, 0, 0.2)\",\n backgroundColor: \"#ffffff\",\n borderRadius: \"50%\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#000000\",\n zIndex: 10,\n boxShadow: \"0 1px 4px rgba(0, 0, 0, 0.2)\",\n },\n content: {\n flex: 1,\n overflow: \"hidden\",\n },\n iframe: {\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n },\n };\n\n return (\n <>\n {showOverlay && (\n <div\n style={styles.overlay}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <div\n style={styles.drawer}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Payment\"\n >\n <button\n style={styles.closeButton}\n onClick={onClose}\n aria-label=\"Close drawer\"\n type=\"button\"\n onMouseEnter={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.color = \"#000000\";\n }}\n onMouseLeave={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#ffffff\";\n e.currentTarget.style.color = \"#000000\";\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n <div style={styles.content}>\n <iframe\n src={open ? iframeUrl : \"about:blank\"}\n title=\"Payment\"\n style={styles.iframe}\n allow=\"payment; clipboard-write\"\n />\n </div>\n </div>\n </>\n );\n}\n","import { useEffect, useMemo } from \"react\";\n\nexport const BASE_URL = \"https://pay.intrpay.us\";\n\nconst baseParams = {\n showHeader: false,\n};\n\nexport interface PaymentParams {\n /** Payment amount */\n amount?: number;\n /** Customer's first name */\n firstName?: string;\n /** Customer's last name */\n lastName?: string;\n /** Customer's email */\n email?: string;\n /** Customer's phone number */\n phone?: string;\n /** Company name */\n companyName?: string;\n /** Whether to show the contact form */\n showContactForm?: boolean;\n /** Checkout item IDs (sent as checkout_items, comma-separated) */\n checkoutItems?: string[];\n}\n\nexport function buildPaymentUrl(\n paymentLinkId: string,\n params?: PaymentParams\n): string {\n const url = new URL(`${BASE_URL}/${paymentLinkId}`);\n const combinedParams = { ...baseParams, ...params };\n\n Object.entries(combinedParams).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (key === \"checkoutItems\" && Array.isArray(value)) {\n if (value.length > 0) {\n url.searchParams.set(\"checkout_items\", value.join(\",\"));\n }\n return;\n }\n if (value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n });\n\n return url.toString();\n}\n\nexport interface UsePaymentIframeOptions {\n paymentLinkId: string;\n params?: PaymentParams;\n onSuccess?: (data: unknown) => void;\n onFailure?: (data: unknown) => void;\n}\n\nexport function usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n}: UsePaymentIframeOptions) {\n const iframeUrl = useMemo(\n () => buildPaymentUrl(paymentLinkId, params),\n [paymentLinkId, params]\n );\n\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== BASE_URL) return;\n\n const data = event.data ?? {};\n const { type } = data as { type?: string };\n\n if (type === \"payment_success\") {\n onSuccess?.(data);\n } else if (type === \"payment_failure\") {\n onFailure?.(data);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [onSuccess, onFailure]);\n\n return { iframeUrl };\n}\n","import React, { CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport interface PaymentEmbedProps {\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Height of the iframe (default: 400px) */\n height?: string | number;\n /** Width of the iframe (default: 100%) */\n width?: string | number;\n /** Optional CSS class name */\n className?: string;\n /** Optional inline styles for the container */\n style?: CSSProperties;\n}\n\nexport function PaymentEmbed({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n height = 400,\n width = \"100%\",\n className,\n style,\n}: PaymentEmbedProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const iframeHeight = typeof height === \"number\" ? `${height}px` : height;\n const iframeWidth = typeof width === \"number\" ? `${width}px` : width;\n\n return (\n <div className={className} style={style}>\n <iframe\n src={iframeUrl}\n title=\"Payment\"\n style={{\n width: iframeWidth,\n height: iframeHeight,\n border: \"none\",\n }}\n allow=\"payment; clipboard-write\"\n />\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useEffect","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/PaymentDrawer.tsx","../src/payment-shared.ts","../src/components/PaymentEmbed.tsx"],"sourcesContent":["import React, { useEffect, useCallback, CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport type { PaymentParams };\n\nexport interface PaymentDrawerProps {\n /** Whether the drawer is open */\n open: boolean;\n /** Callback when the drawer should close */\n onClose: () => void;\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Width of the drawer (default: 400px) */\n width?: string | number;\n /** Position of the drawer */\n position?: \"left\" | \"right\";\n /** Whether to show overlay backdrop */\n showOverlay?: boolean;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Whether clicking overlay closes the drawer */\n closeOnOverlayClick?: boolean;\n /** Z-index for the drawer */\n zIndex?: number;\n}\n\nexport function PaymentDrawer({\n open,\n onClose,\n paymentLinkId,\n params,\n width = 550,\n position = \"right\",\n showOverlay = true,\n onSuccess,\n onFailure,\n closeOnOverlayClick = true,\n zIndex = 2000,\n}: PaymentDrawerProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && open) {\n onClose();\n }\n },\n [open, onClose],\n );\n\n useEffect(() => {\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [handleKeyDown]);\n\n useEffect(() => {\n if (open) {\n document.body.style.overflow = \"hidden\";\n } else {\n document.body.style.overflow = \"\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open]);\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n onClose();\n }\n };\n\n const drawerWidth = typeof width === \"number\" ? `${width}px` : width;\n\n const styles: Record<string, CSSProperties> = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n zIndex,\n opacity: open ? 1 : 0,\n visibility: open ? \"visible\" : \"hidden\",\n transition: \"opacity 0.3s ease, visibility 0.3s ease\",\n },\n drawer: {\n position: \"fixed\",\n top: 0,\n bottom: 0,\n [position]: 0,\n width: drawerWidth,\n maxWidth: \"100%\",\n backgroundColor: \"#ffffff\",\n zIndex: zIndex + 1,\n boxShadow:\n position === \"right\"\n ? \"-4px 0 20px rgba(0, 0, 0, 0.15)\"\n : \"4px 0 20px rgba(0, 0, 0, 0.15)\",\n transform: open\n ? \"translateX(0)\"\n : `translateX(${position === \"right\" ? \"100%\" : \"-100%\"})`,\n transition: \"transform 0.3s ease\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n closeButton: {\n position: \"absolute\",\n top: 12,\n right: 12,\n width: 36,\n height: 36,\n border: \"1px solid rgba(0, 0, 0, 0.2)\",\n backgroundColor: \"#ffffff\",\n borderRadius: \"50%\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#000000\",\n zIndex: 10,\n boxShadow: \"0 1px 4px rgba(0, 0, 0, 0.2)\",\n },\n content: {\n flex: 1,\n overflow: \"hidden\",\n },\n iframe: {\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n },\n };\n\n return (\n <>\n {showOverlay && (\n <div\n style={styles.overlay}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <div\n style={styles.drawer}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Payment\"\n >\n <button\n style={styles.closeButton}\n onClick={onClose}\n aria-label=\"Close drawer\"\n type=\"button\"\n onMouseEnter={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.color = \"#000000\";\n }}\n onMouseLeave={(e: React.MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.backgroundColor = \"#ffffff\";\n e.currentTarget.style.color = \"#000000\";\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n <div style={styles.content}>\n <iframe\n src={open ? iframeUrl : \"about:blank\"}\n title=\"Payment\"\n style={styles.iframe}\n allow=\"payment; clipboard-write\"\n />\n </div>\n </div>\n </>\n );\n}\n","import { useEffect, useMemo } from \"react\";\n\nexport const BASE_URL = \"https://pay.intrpay.us\";\n\nconst baseParams = {\n showHeader: false,\n};\n\nexport interface PaymentParams {\n /** Payment amount */\n amount?: number;\n /** Customer's first name */\n firstName?: string;\n /** Customer's last name */\n lastName?: string;\n /** Customer's email */\n email?: string;\n /** Customer's phone number */\n phone?: string;\n /** Company name */\n companyName?: string;\n /** Whether to show the contact form */\n showContactForm?: boolean;\n /** Checkout item IDs (sent as checkout_items, comma-separated) */\n checkoutItems?: string[];\n /** Whether to allow partial payment */\n allowPartialPayments?: boolean;\n /** Payment description */\n description?: string;\n /** Primary theme color (hex, e.g. '#000076') */\n primaryColor?: string;\n /** Secondary theme color (hex, e.g. '#4774c0') */\n secondaryColor?: string;\n /** Text color (hex, e.g. '#f3fcff') */\n textColor?: string;\n /** Logo URL */\n logo?: string;\n /** Custom button text */\n buttonText?: string;\n /** Whether to show the header */\n showHeader?: boolean;\n /** Lock to a specific payment method */\n paymentMethod?: 'card' | 'daf' | 'ojc' | 'pledger' | 'donorsFund' | 'matbia';\n}\n\nexport function buildPaymentUrl(\n paymentLinkId: string,\n params?: PaymentParams\n): string {\n const url = new URL(`${BASE_URL}/pay/${paymentLinkId}`);\n const combinedParams = { ...baseParams, ...params };\n\n Object.entries(combinedParams).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (key === \"checkoutItems\" && Array.isArray(value)) {\n if (value.length > 0) {\n url.searchParams.set(\"checkoutItems\", value.join(\",\"));\n }\n return;\n }\n if (value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n });\n\n return url.toString();\n}\n\nexport interface UsePaymentIframeOptions {\n paymentLinkId: string;\n params?: PaymentParams;\n onSuccess?: (data: unknown) => void;\n onFailure?: (data: unknown) => void;\n}\n\nexport function usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n}: UsePaymentIframeOptions) {\n const iframeUrl = useMemo(\n () => buildPaymentUrl(paymentLinkId, params),\n [paymentLinkId, params]\n );\n\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== BASE_URL) return;\n\n const data = event.data ?? {};\n const { type } = data as { type?: string };\n\n if (type === \"payment_success\") {\n onSuccess?.(data);\n } else if (type === \"payment_failure\") {\n onFailure?.(data);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [onSuccess, onFailure]);\n\n return { iframeUrl };\n}\n","import React, { CSSProperties } from \"react\";\nimport { usePaymentIframe } from \"../payment-shared\";\nimport type { PaymentParams } from \"../payment-shared\";\n\nexport interface PaymentEmbedProps {\n /** Payment link ID */\n paymentLinkId: string;\n /** Payment parameters to pass as URL query params */\n params?: PaymentParams;\n /** Callback when payment succeeds; receives the message data from the iframe */\n onSuccess?: (data: unknown) => void;\n /** Callback when payment fails; receives the message data from the iframe */\n onFailure?: (data: unknown) => void;\n /** Height of the iframe (default: 400px) */\n height?: string | number;\n /** Width of the iframe (default: 100%) */\n width?: string | number;\n /** Optional CSS class name */\n className?: string;\n /** Optional inline styles for the container */\n style?: CSSProperties;\n}\n\nexport function PaymentEmbed({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n height = 400,\n width = \"100%\",\n className,\n style,\n}: PaymentEmbedProps) {\n const { iframeUrl } = usePaymentIframe({\n paymentLinkId,\n params,\n onSuccess,\n onFailure,\n });\n\n const iframeHeight = typeof height === \"number\" ? `${height}px` : height;\n const iframeWidth = typeof width === \"number\" ? `${width}px` : width;\n\n return (\n <div className={className} style={style}>\n <iframe\n src={iframeUrl}\n title=\"Payment\"\n style={{\n width: iframeWidth,\n height: iframeHeight,\n border: \"none\",\n }}\n allow=\"payment; clipboard-write\"\n />\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useEffect","jsx"]}
|