@flash-pay/browser-sdk 2.0.0 → 2.0.2
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/dist/flashpay.cjs.js +11 -2
- package/dist/flashpay.cjs.js.map +1 -1
- package/dist/flashpay.d.mts +2 -0
- package/dist/flashpay.d.ts +2 -0
- package/dist/flashpay.es.js +11 -2
- package/dist/flashpay.es.js.map +1 -1
- package/dist/flashpay.umd.js +11 -2
- package/dist/flashpay.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/flashpay.cjs.js
CHANGED
|
@@ -26,9 +26,10 @@ module.exports = __toCommonJS(src_exports);
|
|
|
26
26
|
var DEFAULT_ORIGIN = "https://pay.flashpayweb.com";
|
|
27
27
|
var DEFAULT_STYLE = {
|
|
28
28
|
width: "100%",
|
|
29
|
-
|
|
29
|
+
minHeight: "450px",
|
|
30
30
|
border: "none",
|
|
31
|
-
borderRadius: "8px"
|
|
31
|
+
borderRadius: "8px",
|
|
32
|
+
overflowY: "auto"
|
|
32
33
|
};
|
|
33
34
|
function detectOrigin() {
|
|
34
35
|
if (typeof document === "undefined") return DEFAULT_ORIGIN;
|
|
@@ -66,6 +67,7 @@ function checkout(options) {
|
|
|
66
67
|
if (options.showAmount === false) url.searchParams.set("showAmount", "false");
|
|
67
68
|
if (options.showLogo === false) url.searchParams.set("showLogo", "false");
|
|
68
69
|
if (options.showTerms === false) url.searchParams.set("showTerms", "false");
|
|
70
|
+
if (options.qrEnabled === false) url.searchParams.set("qrEnabled", "false");
|
|
69
71
|
url.searchParams.set("parentOrigin", window.location.origin);
|
|
70
72
|
iframe.src = url.toString();
|
|
71
73
|
iframe.title = "Flashpay payment";
|
|
@@ -76,6 +78,13 @@ function checkout(options) {
|
|
|
76
78
|
});
|
|
77
79
|
function onMessage(event) {
|
|
78
80
|
if (event.origin !== origin) return;
|
|
81
|
+
if (event.data?.type === "flashpay:resize") {
|
|
82
|
+
const height = Number(event.data.height);
|
|
83
|
+
if (!isNaN(height) && height > 0) {
|
|
84
|
+
iframe.style.height = height + "px";
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
79
88
|
if (!event.data || event.data.type !== "flashpay:payment_status") return;
|
|
80
89
|
const status = event.data.status;
|
|
81
90
|
const data = {
|
package/dist/flashpay.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n /** Whether to show a QR code on desktop. Defaults to `true`. Set to `false` to always show bank selection. */\n qrEnabled?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n minHeight: \"450px\",\n border: \"none\",\n borderRadius: \"8px\",\n overflowY: \"auto\",\n};\n\n/**\n * Detect the Flashpay origin based on the current script src.\n * Called lazily inside checkout() so it runs after the DOM is ready.\n */\nfunction detectOrigin(): string {\n if (typeof document === \"undefined\") return DEFAULT_ORIGIN;\n\n const scripts = document.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n const src = scripts[i].src || \"\";\n if (src.indexOf(\"/sdk/flashpay\") !== -1 || src.indexOf(\"flashpay.umd.js\") !== -1) {\n try {\n const url = new URL(src);\n return url.origin;\n } catch (e) {}\n }\n }\n return DEFAULT_ORIGIN;\n}\n\n/**\n * Initialize a Flashpay checkout process.\n *\n * @param options - Configuration options for the checkout\n * @returns An instance that can be used to clean up the checkout\n */\nexport function checkout(options: FlashpayOptions): CheckoutInstance {\n if (!options || !options.transactionId) {\n throw new Error(\"Flashpay: transactionId is required\");\n }\n if (!options.container) {\n throw new Error(\"Flashpay: container is required\");\n }\n\n const container =\n typeof options.container === \"string\"\n ? document.querySelector<HTMLElement>(options.container)\n : options.container;\n\n if (!container) {\n const identifier = typeof options.container === \"string\" ? options.container : \"the provided HTMLElement\";\n throw new Error(`Flashpay: container element not found for ${identifier}`);\n }\n\n const style = Object.assign({}, DEFAULT_STYLE, options.style || {});\n const origin = options.origin || detectOrigin();\n\n const iframe = document.createElement(\"iframe\");\n const url = new URL(origin + \"/pay/\" + encodeURIComponent(options.transactionId));\n\n if (options.showTitle === false) url.searchParams.set(\"showTitle\", \"false\");\n if (options.showDescription === false) url.searchParams.set(\"showDescription\", \"false\");\n if (options.showAmount === false) url.searchParams.set(\"showAmount\", \"false\");\n if (options.showLogo === false) url.searchParams.set(\"showLogo\", \"false\");\n if (options.showTerms === false) url.searchParams.set(\"showTerms\", \"false\");\n if (options.qrEnabled === false) url.searchParams.set(\"qrEnabled\", \"false\");\n url.searchParams.set(\"parentOrigin\", window.location.origin);\n\n iframe.src = url.toString();\n iframe.title = \"Flashpay payment\";\n iframe.setAttribute(\"allow\", \"payment; popups\");\n iframe.setAttribute(\"loading\", \"lazy\");\n\n Object.keys(style).forEach((key) => {\n (iframe.style as any)[key] = (style as any)[key];\n });\n\n function onMessage(event: MessageEvent) {\n if (event.origin !== origin) return;\n\n if (event.data?.type === \"flashpay:resize\") {\n const height = Number(event.data.height);\n if (!isNaN(height) && height > 0) {\n iframe.style.height = height + \"px\";\n }\n return;\n }\n\n if (!event.data || event.data.type !== \"flashpay:payment_status\") return;\n\n const status = event.data.status as PaymentEventData[\"status\"];\n const data: PaymentEventData = {\n status,\n transactionId: event.data.transactionId,\n payment: event.data.payment,\n };\n\n if ((status === \"SUCCESSFUL\" || status === \"COMPLETED\") && typeof options.onSuccess === \"function\") {\n options.onSuccess(data);\n } else if (status === \"FAILED\" && typeof options.onFailure === \"function\") {\n options.onFailure(data);\n } else if ((status === \"CANCELLED\" || status === \"EXPIRED\") && typeof options.onClose === \"function\") {\n options.onClose(data);\n }\n }\n\n window.addEventListener(\"message\", onMessage);\n\n // Clear container using safe DOM removal instead of innerHTML\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n container.appendChild(iframe);\n\n return {\n destroy() {\n window.removeEventListener(\"message\", onMessage);\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/flashpay.d.mts
CHANGED
|
@@ -26,6 +26,8 @@ interface FlashpayOptions {
|
|
|
26
26
|
showLogo?: boolean;
|
|
27
27
|
/** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */
|
|
28
28
|
showTerms?: boolean;
|
|
29
|
+
/** Whether to show a QR code on desktop. Defaults to `true`. Set to `false` to always show bank selection. */
|
|
30
|
+
qrEnabled?: boolean;
|
|
29
31
|
style?: Partial<CSSStyleDeclaration>;
|
|
30
32
|
onSuccess?: (data: PaymentEventData) => void;
|
|
31
33
|
onFailure?: (data: PaymentEventData) => void;
|
package/dist/flashpay.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ interface FlashpayOptions {
|
|
|
26
26
|
showLogo?: boolean;
|
|
27
27
|
/** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */
|
|
28
28
|
showTerms?: boolean;
|
|
29
|
+
/** Whether to show a QR code on desktop. Defaults to `true`. Set to `false` to always show bank selection. */
|
|
30
|
+
qrEnabled?: boolean;
|
|
29
31
|
style?: Partial<CSSStyleDeclaration>;
|
|
30
32
|
onSuccess?: (data: PaymentEventData) => void;
|
|
31
33
|
onFailure?: (data: PaymentEventData) => void;
|
package/dist/flashpay.es.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
var DEFAULT_ORIGIN = "https://pay.flashpayweb.com";
|
|
3
3
|
var DEFAULT_STYLE = {
|
|
4
4
|
width: "100%",
|
|
5
|
-
|
|
5
|
+
minHeight: "450px",
|
|
6
6
|
border: "none",
|
|
7
|
-
borderRadius: "8px"
|
|
7
|
+
borderRadius: "8px",
|
|
8
|
+
overflowY: "auto"
|
|
8
9
|
};
|
|
9
10
|
function detectOrigin() {
|
|
10
11
|
if (typeof document === "undefined") return DEFAULT_ORIGIN;
|
|
@@ -42,6 +43,7 @@ function checkout(options) {
|
|
|
42
43
|
if (options.showAmount === false) url.searchParams.set("showAmount", "false");
|
|
43
44
|
if (options.showLogo === false) url.searchParams.set("showLogo", "false");
|
|
44
45
|
if (options.showTerms === false) url.searchParams.set("showTerms", "false");
|
|
46
|
+
if (options.qrEnabled === false) url.searchParams.set("qrEnabled", "false");
|
|
45
47
|
url.searchParams.set("parentOrigin", window.location.origin);
|
|
46
48
|
iframe.src = url.toString();
|
|
47
49
|
iframe.title = "Flashpay payment";
|
|
@@ -52,6 +54,13 @@ function checkout(options) {
|
|
|
52
54
|
});
|
|
53
55
|
function onMessage(event) {
|
|
54
56
|
if (event.origin !== origin) return;
|
|
57
|
+
if (event.data?.type === "flashpay:resize") {
|
|
58
|
+
const height = Number(event.data.height);
|
|
59
|
+
if (!isNaN(height) && height > 0) {
|
|
60
|
+
iframe.style.height = height + "px";
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
55
64
|
if (!event.data || event.data.type !== "flashpay:payment_status") return;
|
|
56
65
|
const status = event.data.status;
|
|
57
66
|
const data = {
|
package/dist/flashpay.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n /** Whether to show a QR code on desktop. Defaults to `true`. Set to `false` to always show bank selection. */\n qrEnabled?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n minHeight: \"450px\",\n border: \"none\",\n borderRadius: \"8px\",\n overflowY: \"auto\",\n};\n\n/**\n * Detect the Flashpay origin based on the current script src.\n * Called lazily inside checkout() so it runs after the DOM is ready.\n */\nfunction detectOrigin(): string {\n if (typeof document === \"undefined\") return DEFAULT_ORIGIN;\n\n const scripts = document.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n const src = scripts[i].src || \"\";\n if (src.indexOf(\"/sdk/flashpay\") !== -1 || src.indexOf(\"flashpay.umd.js\") !== -1) {\n try {\n const url = new URL(src);\n return url.origin;\n } catch (e) {}\n }\n }\n return DEFAULT_ORIGIN;\n}\n\n/**\n * Initialize a Flashpay checkout process.\n *\n * @param options - Configuration options for the checkout\n * @returns An instance that can be used to clean up the checkout\n */\nexport function checkout(options: FlashpayOptions): CheckoutInstance {\n if (!options || !options.transactionId) {\n throw new Error(\"Flashpay: transactionId is required\");\n }\n if (!options.container) {\n throw new Error(\"Flashpay: container is required\");\n }\n\n const container =\n typeof options.container === \"string\"\n ? document.querySelector<HTMLElement>(options.container)\n : options.container;\n\n if (!container) {\n const identifier = typeof options.container === \"string\" ? options.container : \"the provided HTMLElement\";\n throw new Error(`Flashpay: container element not found for ${identifier}`);\n }\n\n const style = Object.assign({}, DEFAULT_STYLE, options.style || {});\n const origin = options.origin || detectOrigin();\n\n const iframe = document.createElement(\"iframe\");\n const url = new URL(origin + \"/pay/\" + encodeURIComponent(options.transactionId));\n\n if (options.showTitle === false) url.searchParams.set(\"showTitle\", \"false\");\n if (options.showDescription === false) url.searchParams.set(\"showDescription\", \"false\");\n if (options.showAmount === false) url.searchParams.set(\"showAmount\", \"false\");\n if (options.showLogo === false) url.searchParams.set(\"showLogo\", \"false\");\n if (options.showTerms === false) url.searchParams.set(\"showTerms\", \"false\");\n if (options.qrEnabled === false) url.searchParams.set(\"qrEnabled\", \"false\");\n url.searchParams.set(\"parentOrigin\", window.location.origin);\n\n iframe.src = url.toString();\n iframe.title = \"Flashpay payment\";\n iframe.setAttribute(\"allow\", \"payment; popups\");\n iframe.setAttribute(\"loading\", \"lazy\");\n\n Object.keys(style).forEach((key) => {\n (iframe.style as any)[key] = (style as any)[key];\n });\n\n function onMessage(event: MessageEvent) {\n if (event.origin !== origin) return;\n\n if (event.data?.type === \"flashpay:resize\") {\n const height = Number(event.data.height);\n if (!isNaN(height) && height > 0) {\n iframe.style.height = height + \"px\";\n }\n return;\n }\n\n if (!event.data || event.data.type !== \"flashpay:payment_status\") return;\n\n const status = event.data.status as PaymentEventData[\"status\"];\n const data: PaymentEventData = {\n status,\n transactionId: event.data.transactionId,\n payment: event.data.payment,\n };\n\n if ((status === \"SUCCESSFUL\" || status === \"COMPLETED\") && typeof options.onSuccess === \"function\") {\n options.onSuccess(data);\n } else if (status === \"FAILED\" && typeof options.onFailure === \"function\") {\n options.onFailure(data);\n } else if ((status === \"CANCELLED\" || status === \"EXPIRED\") && typeof options.onClose === \"function\") {\n options.onClose(data);\n }\n }\n\n window.addEventListener(\"message\", onMessage);\n\n // Clear container using safe DOM removal instead of innerHTML\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n container.appendChild(iframe);\n\n return {\n destroy() {\n window.removeEventListener(\"message\", onMessage);\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/flashpay.umd.js
CHANGED
|
@@ -26,9 +26,10 @@ var Flashpay = (() => {
|
|
|
26
26
|
var DEFAULT_ORIGIN = "https://pay.flashpayweb.com";
|
|
27
27
|
var DEFAULT_STYLE = {
|
|
28
28
|
width: "100%",
|
|
29
|
-
|
|
29
|
+
minHeight: "450px",
|
|
30
30
|
border: "none",
|
|
31
|
-
borderRadius: "8px"
|
|
31
|
+
borderRadius: "8px",
|
|
32
|
+
overflowY: "auto"
|
|
32
33
|
};
|
|
33
34
|
function detectOrigin() {
|
|
34
35
|
if (typeof document === "undefined") return DEFAULT_ORIGIN;
|
|
@@ -66,6 +67,7 @@ var Flashpay = (() => {
|
|
|
66
67
|
if (options.showAmount === false) url.searchParams.set("showAmount", "false");
|
|
67
68
|
if (options.showLogo === false) url.searchParams.set("showLogo", "false");
|
|
68
69
|
if (options.showTerms === false) url.searchParams.set("showTerms", "false");
|
|
70
|
+
if (options.qrEnabled === false) url.searchParams.set("qrEnabled", "false");
|
|
69
71
|
url.searchParams.set("parentOrigin", window.location.origin);
|
|
70
72
|
iframe.src = url.toString();
|
|
71
73
|
iframe.title = "Flashpay payment";
|
|
@@ -76,6 +78,13 @@ var Flashpay = (() => {
|
|
|
76
78
|
});
|
|
77
79
|
function onMessage(event) {
|
|
78
80
|
if (event.origin !== origin) return;
|
|
81
|
+
if (event.data?.type === "flashpay:resize") {
|
|
82
|
+
const height = Number(event.data.height);
|
|
83
|
+
if (!isNaN(height) && height > 0) {
|
|
84
|
+
iframe.style.height = height + "px";
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
79
88
|
if (!event.data || event.data.type !== "flashpay:payment_status") return;
|
|
80
89
|
const status = event.data.status;
|
|
81
90
|
const data = {
|
package/dist/flashpay.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface PaymentData {\n id: string;\n status: string;\n amount?: number;\n currency?: string;\n description?: string;\n destinationAccountName?: string;\n callbackUrl?: string;\n [key: string]: unknown;\n}\n\nexport interface PaymentEventData {\n status: \"SUCCESSFUL\" | \"COMPLETED\" | \"FAILED\" | \"CANCELLED\" | \"EXPIRED\";\n transactionId: string;\n payment: PaymentData;\n}\n\nexport interface FlashpayOptions {\n transactionId: string;\n container: string | HTMLElement;\n /** Whether to show the payment title. Defaults to `true`. Set to `false` to hide. */\n showTitle?: boolean;\n /** Whether to show the payment description. Defaults to `true`. Set to `false` to hide. */\n showDescription?: boolean;\n /** Whether to show the payment amount. Defaults to `true`. Set to `false` to hide. */\n showAmount?: boolean;\n /** Whether to show the Flashpay logo. Defaults to `true`. Set to `false` to hide. */\n showLogo?: boolean;\n /** Whether to show the payment terms section. Defaults to `true`. Set to `false` to hide. */\n showTerms?: boolean;\n /** Whether to show a QR code on desktop. Defaults to `true`. Set to `false` to always show bank selection. */\n qrEnabled?: boolean;\n style?: Partial<CSSStyleDeclaration>;\n onSuccess?: (data: PaymentEventData) => void;\n onFailure?: (data: PaymentEventData) => void;\n onClose?: (data: PaymentEventData) => void;\n /** Custom origin for Flashpay (e.g. for testing) */\n origin?: string;\n}\n\nexport interface CheckoutInstance {\n destroy: () => void;\n}\n\nconst DEFAULT_ORIGIN = \"https://pay.flashpayweb.com\";\n\nconst DEFAULT_STYLE: Partial<CSSStyleDeclaration> = {\n width: \"100%\",\n minHeight: \"450px\",\n border: \"none\",\n borderRadius: \"8px\",\n overflowY: \"auto\",\n};\n\n/**\n * Detect the Flashpay origin based on the current script src.\n * Called lazily inside checkout() so it runs after the DOM is ready.\n */\nfunction detectOrigin(): string {\n if (typeof document === \"undefined\") return DEFAULT_ORIGIN;\n\n const scripts = document.getElementsByTagName(\"script\");\n for (let i = 0; i < scripts.length; i++) {\n const src = scripts[i].src || \"\";\n if (src.indexOf(\"/sdk/flashpay\") !== -1 || src.indexOf(\"flashpay.umd.js\") !== -1) {\n try {\n const url = new URL(src);\n return url.origin;\n } catch (e) {}\n }\n }\n return DEFAULT_ORIGIN;\n}\n\n/**\n * Initialize a Flashpay checkout process.\n *\n * @param options - Configuration options for the checkout\n * @returns An instance that can be used to clean up the checkout\n */\nexport function checkout(options: FlashpayOptions): CheckoutInstance {\n if (!options || !options.transactionId) {\n throw new Error(\"Flashpay: transactionId is required\");\n }\n if (!options.container) {\n throw new Error(\"Flashpay: container is required\");\n }\n\n const container =\n typeof options.container === \"string\"\n ? document.querySelector<HTMLElement>(options.container)\n : options.container;\n\n if (!container) {\n const identifier = typeof options.container === \"string\" ? options.container : \"the provided HTMLElement\";\n throw new Error(`Flashpay: container element not found for ${identifier}`);\n }\n\n const style = Object.assign({}, DEFAULT_STYLE, options.style || {});\n const origin = options.origin || detectOrigin();\n\n const iframe = document.createElement(\"iframe\");\n const url = new URL(origin + \"/pay/\" + encodeURIComponent(options.transactionId));\n\n if (options.showTitle === false) url.searchParams.set(\"showTitle\", \"false\");\n if (options.showDescription === false) url.searchParams.set(\"showDescription\", \"false\");\n if (options.showAmount === false) url.searchParams.set(\"showAmount\", \"false\");\n if (options.showLogo === false) url.searchParams.set(\"showLogo\", \"false\");\n if (options.showTerms === false) url.searchParams.set(\"showTerms\", \"false\");\n if (options.qrEnabled === false) url.searchParams.set(\"qrEnabled\", \"false\");\n url.searchParams.set(\"parentOrigin\", window.location.origin);\n\n iframe.src = url.toString();\n iframe.title = \"Flashpay payment\";\n iframe.setAttribute(\"allow\", \"payment; popups\");\n iframe.setAttribute(\"loading\", \"lazy\");\n\n Object.keys(style).forEach((key) => {\n (iframe.style as any)[key] = (style as any)[key];\n });\n\n function onMessage(event: MessageEvent) {\n if (event.origin !== origin) return;\n\n if (event.data?.type === \"flashpay:resize\") {\n const height = Number(event.data.height);\n if (!isNaN(height) && height > 0) {\n iframe.style.height = height + \"px\";\n }\n return;\n }\n\n if (!event.data || event.data.type !== \"flashpay:payment_status\") return;\n\n const status = event.data.status as PaymentEventData[\"status\"];\n const data: PaymentEventData = {\n status,\n transactionId: event.data.transactionId,\n payment: event.data.payment,\n };\n\n if ((status === \"SUCCESSFUL\" || status === \"COMPLETED\") && typeof options.onSuccess === \"function\") {\n options.onSuccess(data);\n } else if (status === \"FAILED\" && typeof options.onFailure === \"function\") {\n options.onFailure(data);\n } else if ((status === \"CANCELLED\" || status === \"EXPIRED\") && typeof options.onClose === \"function\") {\n options.onClose(data);\n }\n }\n\n window.addEventListener(\"message\", onMessage);\n\n // Clear container using safe DOM removal instead of innerHTML\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n container.appendChild(iframe);\n\n return {\n destroy() {\n window.removeEventListener(\"message\", onMessage);\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|