@loofta/pay-sdk 1.0.1 → 1.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/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -74,7 +74,7 @@ function PayButton({
|
|
|
74
74
|
const [isHovered, setIsHovered] = react.useState(false);
|
|
75
75
|
const effectiveButtonBgColor = buttonBgColor || bgColor;
|
|
76
76
|
const getCheckoutUrl = react.useCallback(() => {
|
|
77
|
-
const defaultBase = "https://pay.loofta.
|
|
77
|
+
const defaultBase = "https://pay.loofta.xyz";
|
|
78
78
|
const base = checkoutBaseUrl != null && checkoutBaseUrl !== "" ? checkoutBaseUrl.replace(/\/$/, "") : defaultBase;
|
|
79
79
|
const path = base.endsWith("/checkout") ? base : `${base}/checkout`;
|
|
80
80
|
const params = new URLSearchParams();
|
|
@@ -181,7 +181,7 @@ function generateEmbedCode(props) {
|
|
|
181
181
|
}
|
|
182
182
|
function generateScriptEmbed(props) {
|
|
183
183
|
const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;
|
|
184
|
-
const base = checkoutBaseUrl || "https://pay.loofta.
|
|
184
|
+
const base = checkoutBaseUrl || "https://pay.loofta.xyz";
|
|
185
185
|
return `<!-- Loofta Pay Button -->
|
|
186
186
|
<script src="${base}/sdk/loofta-pay.js"></script>
|
|
187
187
|
<div
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/PayButton.tsx"],"names":["jsxs","jsx","useState","useCallback","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["import { useState, useCallback } from 'react';\n\nexport interface PayButtonProps {\n /**\n * Organization ID (required). Must be set up with Loofta — your destination wallet, network, and token are configured in your organization.\n * If you don't have an organization ID, contact Loofta to get one.\n */\n organizationId: string;\n /** Payment amount in USD (optional) */\n amount?: number | string;\n /** Button background color (optional) */\n buttonBgColor?: string;\n /** Checkout page background color (optional - falls back to org settings) */\n pageBgColor?: string;\n /** @deprecated Use buttonBgColor instead */\n bgColor?: string;\n /** Callback URL after payment (optional) */\n callbackUrl?: string;\n /** Callback function after payment (optional) */\n onSuccess?: (paymentId: string) => void;\n /** Button text (optional) */\n buttonText?: string;\n /** Success text shown after payment (optional) */\n successText?: string;\n /** Custom className for button styling */\n className?: string;\n /** Open checkout in new tab vs popup (default: popup) */\n openMode?: 'popup' | 'redirect' | 'tab';\n /** Disable button */\n disabled?: boolean;\n /**\n * Base URL of the Loofta Pay hosted checkout page. Checkout is always Loofta's — this is only needed if the button is embedded on a different domain than the default Loofta Pay app. Usually omit; default is used.\n */\n checkoutBaseUrl?: string;\n}\n\nconst DEFAULT_STYLE: React.CSSProperties = {\n background: 'linear-gradient(to right, #FF0F00, #EAB308)',\n color: '#ffffff',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 24px',\n fontSize: '16px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n minWidth: '160px',\n transition: 'transform 0.2s, box-shadow 0.2s',\n boxShadow: '0 4px 14px rgba(255, 15, 0, 0.25)',\n};\n\nconst HOVER_STYLE: React.CSSProperties = {\n transform: 'scale(1.02)',\n boxShadow: '0 6px 20px rgba(255, 15, 0, 0.35)',\n};\n\nfunction LoaderIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity={0.25} />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n style={{ transformOrigin: '12px 12px' }}\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nfunction PayIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" />\n </svg>\n );\n}\n\n/**\n * Loofta Pay Button – opens your Loofta Pay checkout (same API as your app).\n */\nexport function PayButton({\n organizationId,\n amount,\n buttonBgColor,\n pageBgColor,\n bgColor,\n callbackUrl,\n onSuccess,\n buttonText = 'Pay with Loofta',\n successText = 'Paid Successfully',\n className,\n openMode = 'popup',\n disabled = false,\n checkoutBaseUrl,\n}: PayButtonProps) {\n const [loading, setLoading] = useState(false);\n const [paid, setPaid] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n\n const effectiveButtonBgColor = buttonBgColor || bgColor;\n\n const getCheckoutUrl = useCallback(() => {\n const defaultBase = 'https://pay.loofta.com';\n const base =\n checkoutBaseUrl != null && checkoutBaseUrl !== ''\n ? checkoutBaseUrl.replace(/\\/$/, '')\n : defaultBase;\n\n const path = base.endsWith('/checkout') ? base : `${base}/checkout`;\n const params = new URLSearchParams();\n params.set('organizationId', organizationId);\n if (amount) params.set('amount', String(amount));\n if (pageBgColor) params.set('bgColor', encodeURIComponent(pageBgColor));\n if (callbackUrl) params.set('callback', encodeURIComponent(callbackUrl));\n\n return `${path}?${params.toString()}`;\n }, [checkoutBaseUrl, organizationId, amount, pageBgColor, callbackUrl]);\n\n const handleClick = useCallback(() => {\n if (disabled || loading || paid) return;\n\n setLoading(true);\n const url = getCheckoutUrl();\n\n if (openMode === 'redirect') {\n window.location.href = url;\n return;\n }\n\n if (openMode === 'tab') {\n window.open(url, '_blank', 'noopener,noreferrer');\n setLoading(false);\n return;\n }\n\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n url,\n 'loofta-pay-checkout',\n `width=${width},height=${height},left=${left},top=${top},scrollbars=yes,resizable=yes`\n );\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === 'loofta-payment-success') {\n setLoading(false);\n setPaid(true);\n onSuccess?.(event.data.paymentId);\n popup?.close();\n window.removeEventListener('message', handleMessage);\n }\n };\n window.addEventListener('message', handleMessage);\n\n const checkClosed = setInterval(() => {\n if (popup?.closed) {\n clearInterval(checkClosed);\n setLoading(false);\n window.removeEventListener('message', handleMessage);\n }\n }, 500);\n }, [disabled, loading, paid, getCheckoutUrl, openMode, onSuccess]);\n\n const successStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n background: 'linear-gradient(to right, #10B981, #059669)',\n boxShadow: '0 4px 14px rgba(16, 185, 129, 0.25)',\n cursor: 'default',\n };\n\n const buttonStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n ...(effectiveButtonBgColor ? { background: effectiveButtonBgColor } : {}),\n ...(isHovered && !disabled && !paid ? HOVER_STYLE : {}),\n ...(disabled ? { opacity: 0.6, cursor: 'not-allowed' as const } : {}),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading || paid}\n className={className}\n style={className ? undefined : paid ? successStyle : buttonStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {paid ? (\n <>\n <CheckIcon />\n {successText}\n </>\n ) : loading ? (\n <>\n <LoaderIcon />\n Processing...\n </>\n ) : (\n <>\n <PayIcon />\n {buttonText}\n </>\n )}\n </button>\n );\n}\n\nexport function generateEmbedCode(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n\n const propsStr = [\n `organizationId=\"${organizationId || 'your-org-id'}\"`,\n amount ? `amount={${amount}}` : null,\n buttonBgColor ? `buttonBgColor=\"${buttonBgColor}\"` : null,\n pageBgColor ? `pageBgColor=\"${pageBgColor}\"` : null,\n callbackUrl ? `callbackUrl=\"${callbackUrl}\"` : null,\n buttonText ? `buttonText=\"${buttonText}\"` : null,\n checkoutBaseUrl ? `checkoutBaseUrl=\"${checkoutBaseUrl}\"` : null,\n ]\n .filter(Boolean)\n .join('\\n ');\n\n return `import { PayButton } from '@loofta/pay-sdk';\n\n<PayButton\n ${propsStr}\n onSuccess={(paymentId) => {\n console.log('Payment completed:', paymentId);\n }}\n/>`;\n}\n\nexport function generateScriptEmbed(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n const base = checkoutBaseUrl || 'https://pay.loofta.com';\n\n return `<!-- Loofta Pay Button -->\n<script src=\"${base}/sdk/loofta-pay.js\"></script>\n<div \n id=\"loofta-pay-button\"\n data-organization-id=\"${organizationId || 'your-org-id'}\"\n data-checkout-base-url=\"${base}\"\n ${amount ? `data-amount=\"${amount}\"` : ''}\n ${buttonBgColor ? `data-button-bg-color=\"${buttonBgColor}\"` : ''}\n ${pageBgColor ? `data-page-bg-color=\"${pageBgColor}\"` : ''}\n ${buttonText ? `data-button-text=\"${buttonText}\"` : ''}\n ${callbackUrl ? `data-callback=\"${callbackUrl}\"` : ''}\n></div>\n<script>\n LooftaPay.mount('#loofta-pay-button');\n</script>`;\n}\n\nexport default PayButton;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/PayButton.tsx"],"names":["jsxs","jsx","useState","useCallback","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["import { useState, useCallback } from 'react';\n\nexport interface PayButtonProps {\n /**\n * Organization ID (required). Must be set up with Loofta — your destination wallet, network, and token are configured in your organization.\n * If you don't have an organization ID, contact Loofta to get one.\n */\n organizationId: string;\n /** Payment amount in USD (optional) */\n amount?: number | string;\n /** Button background color (optional) */\n buttonBgColor?: string;\n /** Checkout page background color (optional - falls back to org settings) */\n pageBgColor?: string;\n /** @deprecated Use buttonBgColor instead */\n bgColor?: string;\n /** Callback URL after payment (optional) */\n callbackUrl?: string;\n /** Callback function after payment (optional) */\n onSuccess?: (paymentId: string) => void;\n /** Button text (optional) */\n buttonText?: string;\n /** Success text shown after payment (optional) */\n successText?: string;\n /** Custom className for button styling */\n className?: string;\n /** Open checkout in new tab vs popup (default: popup) */\n openMode?: 'popup' | 'redirect' | 'tab';\n /** Disable button */\n disabled?: boolean;\n /**\n * Base URL of the Loofta Pay hosted checkout page. Checkout is always Loofta's — this is only needed if the button is embedded on a different domain than the default Loofta Pay app. Usually omit; default is used.\n */\n checkoutBaseUrl?: string;\n}\n\nconst DEFAULT_STYLE: React.CSSProperties = {\n background: 'linear-gradient(to right, #FF0F00, #EAB308)',\n color: '#ffffff',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 24px',\n fontSize: '16px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n minWidth: '160px',\n transition: 'transform 0.2s, box-shadow 0.2s',\n boxShadow: '0 4px 14px rgba(255, 15, 0, 0.25)',\n};\n\nconst HOVER_STYLE: React.CSSProperties = {\n transform: 'scale(1.02)',\n boxShadow: '0 6px 20px rgba(255, 15, 0, 0.35)',\n};\n\nfunction LoaderIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity={0.25} />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n style={{ transformOrigin: '12px 12px' }}\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nfunction PayIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" />\n </svg>\n );\n}\n\n/**\n * Loofta Pay Button – opens your Loofta Pay checkout (same API as your app).\n */\nexport function PayButton({\n organizationId,\n amount,\n buttonBgColor,\n pageBgColor,\n bgColor,\n callbackUrl,\n onSuccess,\n buttonText = 'Pay with Loofta',\n successText = 'Paid Successfully',\n className,\n openMode = 'popup',\n disabled = false,\n checkoutBaseUrl,\n}: PayButtonProps) {\n const [loading, setLoading] = useState(false);\n const [paid, setPaid] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n\n const effectiveButtonBgColor = buttonBgColor || bgColor;\n\n const getCheckoutUrl = useCallback(() => {\n const defaultBase = 'https://pay.loofta.xyz';\n const base =\n checkoutBaseUrl != null && checkoutBaseUrl !== ''\n ? checkoutBaseUrl.replace(/\\/$/, '')\n : defaultBase;\n\n const path = base.endsWith('/checkout') ? base : `${base}/checkout`;\n const params = new URLSearchParams();\n params.set('organizationId', organizationId);\n if (amount) params.set('amount', String(amount));\n if (pageBgColor) params.set('bgColor', encodeURIComponent(pageBgColor));\n if (callbackUrl) params.set('callback', encodeURIComponent(callbackUrl));\n\n return `${path}?${params.toString()}`;\n }, [checkoutBaseUrl, organizationId, amount, pageBgColor, callbackUrl]);\n\n const handleClick = useCallback(() => {\n if (disabled || loading || paid) return;\n\n setLoading(true);\n const url = getCheckoutUrl();\n\n if (openMode === 'redirect') {\n window.location.href = url;\n return;\n }\n\n if (openMode === 'tab') {\n window.open(url, '_blank', 'noopener,noreferrer');\n setLoading(false);\n return;\n }\n\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n url,\n 'loofta-pay-checkout',\n `width=${width},height=${height},left=${left},top=${top},scrollbars=yes,resizable=yes`\n );\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === 'loofta-payment-success') {\n setLoading(false);\n setPaid(true);\n onSuccess?.(event.data.paymentId);\n popup?.close();\n window.removeEventListener('message', handleMessage);\n }\n };\n window.addEventListener('message', handleMessage);\n\n const checkClosed = setInterval(() => {\n if (popup?.closed) {\n clearInterval(checkClosed);\n setLoading(false);\n window.removeEventListener('message', handleMessage);\n }\n }, 500);\n }, [disabled, loading, paid, getCheckoutUrl, openMode, onSuccess]);\n\n const successStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n background: 'linear-gradient(to right, #10B981, #059669)',\n boxShadow: '0 4px 14px rgba(16, 185, 129, 0.25)',\n cursor: 'default',\n };\n\n const buttonStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n ...(effectiveButtonBgColor ? { background: effectiveButtonBgColor } : {}),\n ...(isHovered && !disabled && !paid ? HOVER_STYLE : {}),\n ...(disabled ? { opacity: 0.6, cursor: 'not-allowed' as const } : {}),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading || paid}\n className={className}\n style={className ? undefined : paid ? successStyle : buttonStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {paid ? (\n <>\n <CheckIcon />\n {successText}\n </>\n ) : loading ? (\n <>\n <LoaderIcon />\n Processing...\n </>\n ) : (\n <>\n <PayIcon />\n {buttonText}\n </>\n )}\n </button>\n );\n}\n\nexport function generateEmbedCode(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n\n const propsStr = [\n `organizationId=\"${organizationId || 'your-org-id'}\"`,\n amount ? `amount={${amount}}` : null,\n buttonBgColor ? `buttonBgColor=\"${buttonBgColor}\"` : null,\n pageBgColor ? `pageBgColor=\"${pageBgColor}\"` : null,\n callbackUrl ? `callbackUrl=\"${callbackUrl}\"` : null,\n buttonText ? `buttonText=\"${buttonText}\"` : null,\n checkoutBaseUrl ? `checkoutBaseUrl=\"${checkoutBaseUrl}\"` : null,\n ]\n .filter(Boolean)\n .join('\\n ');\n\n return `import { PayButton } from '@loofta/pay-sdk';\n\n<PayButton\n ${propsStr}\n onSuccess={(paymentId) => {\n console.log('Payment completed:', paymentId);\n }}\n/>`;\n}\n\nexport function generateScriptEmbed(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n const base = checkoutBaseUrl || 'https://pay.loofta.xyz';\n\n return `<!-- Loofta Pay Button -->\n<script src=\"${base}/sdk/loofta-pay.js\"></script>\n<div \n id=\"loofta-pay-button\"\n data-organization-id=\"${organizationId || 'your-org-id'}\"\n data-checkout-base-url=\"${base}\"\n ${amount ? `data-amount=\"${amount}\"` : ''}\n ${buttonBgColor ? `data-button-bg-color=\"${buttonBgColor}\"` : ''}\n ${pageBgColor ? `data-page-bg-color=\"${pageBgColor}\"` : ''}\n ${buttonText ? `data-button-text=\"${buttonText}\"` : ''}\n ${callbackUrl ? `data-callback=\"${callbackUrl}\"` : ''}\n></div>\n<script>\n LooftaPay.mount('#loofta-pay-button');\n</script>`;\n}\n\nexport default PayButton;\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -72,7 +72,7 @@ function PayButton({
|
|
|
72
72
|
const [isHovered, setIsHovered] = useState(false);
|
|
73
73
|
const effectiveButtonBgColor = buttonBgColor || bgColor;
|
|
74
74
|
const getCheckoutUrl = useCallback(() => {
|
|
75
|
-
const defaultBase = "https://pay.loofta.
|
|
75
|
+
const defaultBase = "https://pay.loofta.xyz";
|
|
76
76
|
const base = checkoutBaseUrl != null && checkoutBaseUrl !== "" ? checkoutBaseUrl.replace(/\/$/, "") : defaultBase;
|
|
77
77
|
const path = base.endsWith("/checkout") ? base : `${base}/checkout`;
|
|
78
78
|
const params = new URLSearchParams();
|
|
@@ -179,7 +179,7 @@ function generateEmbedCode(props) {
|
|
|
179
179
|
}
|
|
180
180
|
function generateScriptEmbed(props) {
|
|
181
181
|
const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;
|
|
182
|
-
const base = checkoutBaseUrl || "https://pay.loofta.
|
|
182
|
+
const base = checkoutBaseUrl || "https://pay.loofta.xyz";
|
|
183
183
|
return `<!-- Loofta Pay Button -->
|
|
184
184
|
<script src="${base}/sdk/loofta-pay.js"></script>
|
|
185
185
|
<div
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/PayButton.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { useState, useCallback } from 'react';\n\nexport interface PayButtonProps {\n /**\n * Organization ID (required). Must be set up with Loofta — your destination wallet, network, and token are configured in your organization.\n * If you don't have an organization ID, contact Loofta to get one.\n */\n organizationId: string;\n /** Payment amount in USD (optional) */\n amount?: number | string;\n /** Button background color (optional) */\n buttonBgColor?: string;\n /** Checkout page background color (optional - falls back to org settings) */\n pageBgColor?: string;\n /** @deprecated Use buttonBgColor instead */\n bgColor?: string;\n /** Callback URL after payment (optional) */\n callbackUrl?: string;\n /** Callback function after payment (optional) */\n onSuccess?: (paymentId: string) => void;\n /** Button text (optional) */\n buttonText?: string;\n /** Success text shown after payment (optional) */\n successText?: string;\n /** Custom className for button styling */\n className?: string;\n /** Open checkout in new tab vs popup (default: popup) */\n openMode?: 'popup' | 'redirect' | 'tab';\n /** Disable button */\n disabled?: boolean;\n /**\n * Base URL of the Loofta Pay hosted checkout page. Checkout is always Loofta's — this is only needed if the button is embedded on a different domain than the default Loofta Pay app. Usually omit; default is used.\n */\n checkoutBaseUrl?: string;\n}\n\nconst DEFAULT_STYLE: React.CSSProperties = {\n background: 'linear-gradient(to right, #FF0F00, #EAB308)',\n color: '#ffffff',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 24px',\n fontSize: '16px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n minWidth: '160px',\n transition: 'transform 0.2s, box-shadow 0.2s',\n boxShadow: '0 4px 14px rgba(255, 15, 0, 0.25)',\n};\n\nconst HOVER_STYLE: React.CSSProperties = {\n transform: 'scale(1.02)',\n boxShadow: '0 6px 20px rgba(255, 15, 0, 0.35)',\n};\n\nfunction LoaderIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity={0.25} />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n style={{ transformOrigin: '12px 12px' }}\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nfunction PayIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" />\n </svg>\n );\n}\n\n/**\n * Loofta Pay Button – opens your Loofta Pay checkout (same API as your app).\n */\nexport function PayButton({\n organizationId,\n amount,\n buttonBgColor,\n pageBgColor,\n bgColor,\n callbackUrl,\n onSuccess,\n buttonText = 'Pay with Loofta',\n successText = 'Paid Successfully',\n className,\n openMode = 'popup',\n disabled = false,\n checkoutBaseUrl,\n}: PayButtonProps) {\n const [loading, setLoading] = useState(false);\n const [paid, setPaid] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n\n const effectiveButtonBgColor = buttonBgColor || bgColor;\n\n const getCheckoutUrl = useCallback(() => {\n const defaultBase = 'https://pay.loofta.com';\n const base =\n checkoutBaseUrl != null && checkoutBaseUrl !== ''\n ? checkoutBaseUrl.replace(/\\/$/, '')\n : defaultBase;\n\n const path = base.endsWith('/checkout') ? base : `${base}/checkout`;\n const params = new URLSearchParams();\n params.set('organizationId', organizationId);\n if (amount) params.set('amount', String(amount));\n if (pageBgColor) params.set('bgColor', encodeURIComponent(pageBgColor));\n if (callbackUrl) params.set('callback', encodeURIComponent(callbackUrl));\n\n return `${path}?${params.toString()}`;\n }, [checkoutBaseUrl, organizationId, amount, pageBgColor, callbackUrl]);\n\n const handleClick = useCallback(() => {\n if (disabled || loading || paid) return;\n\n setLoading(true);\n const url = getCheckoutUrl();\n\n if (openMode === 'redirect') {\n window.location.href = url;\n return;\n }\n\n if (openMode === 'tab') {\n window.open(url, '_blank', 'noopener,noreferrer');\n setLoading(false);\n return;\n }\n\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n url,\n 'loofta-pay-checkout',\n `width=${width},height=${height},left=${left},top=${top},scrollbars=yes,resizable=yes`\n );\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === 'loofta-payment-success') {\n setLoading(false);\n setPaid(true);\n onSuccess?.(event.data.paymentId);\n popup?.close();\n window.removeEventListener('message', handleMessage);\n }\n };\n window.addEventListener('message', handleMessage);\n\n const checkClosed = setInterval(() => {\n if (popup?.closed) {\n clearInterval(checkClosed);\n setLoading(false);\n window.removeEventListener('message', handleMessage);\n }\n }, 500);\n }, [disabled, loading, paid, getCheckoutUrl, openMode, onSuccess]);\n\n const successStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n background: 'linear-gradient(to right, #10B981, #059669)',\n boxShadow: '0 4px 14px rgba(16, 185, 129, 0.25)',\n cursor: 'default',\n };\n\n const buttonStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n ...(effectiveButtonBgColor ? { background: effectiveButtonBgColor } : {}),\n ...(isHovered && !disabled && !paid ? HOVER_STYLE : {}),\n ...(disabled ? { opacity: 0.6, cursor: 'not-allowed' as const } : {}),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading || paid}\n className={className}\n style={className ? undefined : paid ? successStyle : buttonStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {paid ? (\n <>\n <CheckIcon />\n {successText}\n </>\n ) : loading ? (\n <>\n <LoaderIcon />\n Processing...\n </>\n ) : (\n <>\n <PayIcon />\n {buttonText}\n </>\n )}\n </button>\n );\n}\n\nexport function generateEmbedCode(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n\n const propsStr = [\n `organizationId=\"${organizationId || 'your-org-id'}\"`,\n amount ? `amount={${amount}}` : null,\n buttonBgColor ? `buttonBgColor=\"${buttonBgColor}\"` : null,\n pageBgColor ? `pageBgColor=\"${pageBgColor}\"` : null,\n callbackUrl ? `callbackUrl=\"${callbackUrl}\"` : null,\n buttonText ? `buttonText=\"${buttonText}\"` : null,\n checkoutBaseUrl ? `checkoutBaseUrl=\"${checkoutBaseUrl}\"` : null,\n ]\n .filter(Boolean)\n .join('\\n ');\n\n return `import { PayButton } from '@loofta/pay-sdk';\n\n<PayButton\n ${propsStr}\n onSuccess={(paymentId) => {\n console.log('Payment completed:', paymentId);\n }}\n/>`;\n}\n\nexport function generateScriptEmbed(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n const base = checkoutBaseUrl || 'https://pay.loofta.com';\n\n return `<!-- Loofta Pay Button -->\n<script src=\"${base}/sdk/loofta-pay.js\"></script>\n<div \n id=\"loofta-pay-button\"\n data-organization-id=\"${organizationId || 'your-org-id'}\"\n data-checkout-base-url=\"${base}\"\n ${amount ? `data-amount=\"${amount}\"` : ''}\n ${buttonBgColor ? `data-button-bg-color=\"${buttonBgColor}\"` : ''}\n ${pageBgColor ? `data-page-bg-color=\"${pageBgColor}\"` : ''}\n ${buttonText ? `data-button-text=\"${buttonText}\"` : ''}\n ${callbackUrl ? `data-callback=\"${callbackUrl}\"` : ''}\n></div>\n<script>\n LooftaPay.mount('#loofta-pay-button');\n</script>`;\n}\n\nexport default PayButton;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/PayButton.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { useState, useCallback } from 'react';\n\nexport interface PayButtonProps {\n /**\n * Organization ID (required). Must be set up with Loofta — your destination wallet, network, and token are configured in your organization.\n * If you don't have an organization ID, contact Loofta to get one.\n */\n organizationId: string;\n /** Payment amount in USD (optional) */\n amount?: number | string;\n /** Button background color (optional) */\n buttonBgColor?: string;\n /** Checkout page background color (optional - falls back to org settings) */\n pageBgColor?: string;\n /** @deprecated Use buttonBgColor instead */\n bgColor?: string;\n /** Callback URL after payment (optional) */\n callbackUrl?: string;\n /** Callback function after payment (optional) */\n onSuccess?: (paymentId: string) => void;\n /** Button text (optional) */\n buttonText?: string;\n /** Success text shown after payment (optional) */\n successText?: string;\n /** Custom className for button styling */\n className?: string;\n /** Open checkout in new tab vs popup (default: popup) */\n openMode?: 'popup' | 'redirect' | 'tab';\n /** Disable button */\n disabled?: boolean;\n /**\n * Base URL of the Loofta Pay hosted checkout page. Checkout is always Loofta's — this is only needed if the button is embedded on a different domain than the default Loofta Pay app. Usually omit; default is used.\n */\n checkoutBaseUrl?: string;\n}\n\nconst DEFAULT_STYLE: React.CSSProperties = {\n background: 'linear-gradient(to right, #FF0F00, #EAB308)',\n color: '#ffffff',\n border: 'none',\n borderRadius: '12px',\n padding: '12px 24px',\n fontSize: '16px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n minWidth: '160px',\n transition: 'transform 0.2s, box-shadow 0.2s',\n boxShadow: '0 4px 14px rgba(255, 15, 0, 0.25)',\n};\n\nconst HOVER_STYLE: React.CSSProperties = {\n transform: 'scale(1.02)',\n boxShadow: '0 6px 20px rgba(255, 15, 0, 0.35)',\n};\n\nfunction LoaderIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity={0.25} />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n style={{ transformOrigin: '12px 12px' }}\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nfunction PayIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\" />\n </svg>\n );\n}\n\n/**\n * Loofta Pay Button – opens your Loofta Pay checkout (same API as your app).\n */\nexport function PayButton({\n organizationId,\n amount,\n buttonBgColor,\n pageBgColor,\n bgColor,\n callbackUrl,\n onSuccess,\n buttonText = 'Pay with Loofta',\n successText = 'Paid Successfully',\n className,\n openMode = 'popup',\n disabled = false,\n checkoutBaseUrl,\n}: PayButtonProps) {\n const [loading, setLoading] = useState(false);\n const [paid, setPaid] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n\n const effectiveButtonBgColor = buttonBgColor || bgColor;\n\n const getCheckoutUrl = useCallback(() => {\n const defaultBase = 'https://pay.loofta.xyz';\n const base =\n checkoutBaseUrl != null && checkoutBaseUrl !== ''\n ? checkoutBaseUrl.replace(/\\/$/, '')\n : defaultBase;\n\n const path = base.endsWith('/checkout') ? base : `${base}/checkout`;\n const params = new URLSearchParams();\n params.set('organizationId', organizationId);\n if (amount) params.set('amount', String(amount));\n if (pageBgColor) params.set('bgColor', encodeURIComponent(pageBgColor));\n if (callbackUrl) params.set('callback', encodeURIComponent(callbackUrl));\n\n return `${path}?${params.toString()}`;\n }, [checkoutBaseUrl, organizationId, amount, pageBgColor, callbackUrl]);\n\n const handleClick = useCallback(() => {\n if (disabled || loading || paid) return;\n\n setLoading(true);\n const url = getCheckoutUrl();\n\n if (openMode === 'redirect') {\n window.location.href = url;\n return;\n }\n\n if (openMode === 'tab') {\n window.open(url, '_blank', 'noopener,noreferrer');\n setLoading(false);\n return;\n }\n\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n url,\n 'loofta-pay-checkout',\n `width=${width},height=${height},left=${left},top=${top},scrollbars=yes,resizable=yes`\n );\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === 'loofta-payment-success') {\n setLoading(false);\n setPaid(true);\n onSuccess?.(event.data.paymentId);\n popup?.close();\n window.removeEventListener('message', handleMessage);\n }\n };\n window.addEventListener('message', handleMessage);\n\n const checkClosed = setInterval(() => {\n if (popup?.closed) {\n clearInterval(checkClosed);\n setLoading(false);\n window.removeEventListener('message', handleMessage);\n }\n }, 500);\n }, [disabled, loading, paid, getCheckoutUrl, openMode, onSuccess]);\n\n const successStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n background: 'linear-gradient(to right, #10B981, #059669)',\n boxShadow: '0 4px 14px rgba(16, 185, 129, 0.25)',\n cursor: 'default',\n };\n\n const buttonStyle: React.CSSProperties = {\n ...DEFAULT_STYLE,\n ...(effectiveButtonBgColor ? { background: effectiveButtonBgColor } : {}),\n ...(isHovered && !disabled && !paid ? HOVER_STYLE : {}),\n ...(disabled ? { opacity: 0.6, cursor: 'not-allowed' as const } : {}),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading || paid}\n className={className}\n style={className ? undefined : paid ? successStyle : buttonStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {paid ? (\n <>\n <CheckIcon />\n {successText}\n </>\n ) : loading ? (\n <>\n <LoaderIcon />\n Processing...\n </>\n ) : (\n <>\n <PayIcon />\n {buttonText}\n </>\n )}\n </button>\n );\n}\n\nexport function generateEmbedCode(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n\n const propsStr = [\n `organizationId=\"${organizationId || 'your-org-id'}\"`,\n amount ? `amount={${amount}}` : null,\n buttonBgColor ? `buttonBgColor=\"${buttonBgColor}\"` : null,\n pageBgColor ? `pageBgColor=\"${pageBgColor}\"` : null,\n callbackUrl ? `callbackUrl=\"${callbackUrl}\"` : null,\n buttonText ? `buttonText=\"${buttonText}\"` : null,\n checkoutBaseUrl ? `checkoutBaseUrl=\"${checkoutBaseUrl}\"` : null,\n ]\n .filter(Boolean)\n .join('\\n ');\n\n return `import { PayButton } from '@loofta/pay-sdk';\n\n<PayButton\n ${propsStr}\n onSuccess={(paymentId) => {\n console.log('Payment completed:', paymentId);\n }}\n/>`;\n}\n\nexport function generateScriptEmbed(props: Partial<PayButtonProps>): string {\n const { organizationId, amount, buttonBgColor, pageBgColor, callbackUrl, buttonText, checkoutBaseUrl } = props;\n const base = checkoutBaseUrl || 'https://pay.loofta.xyz';\n\n return `<!-- Loofta Pay Button -->\n<script src=\"${base}/sdk/loofta-pay.js\"></script>\n<div \n id=\"loofta-pay-button\"\n data-organization-id=\"${organizationId || 'your-org-id'}\"\n data-checkout-base-url=\"${base}\"\n ${amount ? `data-amount=\"${amount}\"` : ''}\n ${buttonBgColor ? `data-button-bg-color=\"${buttonBgColor}\"` : ''}\n ${pageBgColor ? `data-page-bg-color=\"${pageBgColor}\"` : ''}\n ${buttonText ? `data-button-text=\"${buttonText}\"` : ''}\n ${callbackUrl ? `data-callback=\"${callbackUrl}\"` : ''}\n></div>\n<script>\n LooftaPay.mount('#loofta-pay-button');\n</script>`;\n}\n\nexport default PayButton;\n"]}
|