@payinto/checkout-sdk 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- const e="undefined"!=typeof window,t=e?"https://checkout.payinto.co":"",o="/v1".replace(/\/+$/,""),n=`${t}${o}/popup`,i="https://checkout.payinto.co,https://go.payinto.co".split(",").map(e=>e.trim()).filter(Boolean),r=e?new URL(n).origin:"",c=/* @__PURE__ */new Set([r,...i]),s=e=>{try{const t=new URL(e.checkout_url),o=e.checkout_version||(e=>{try{const t=new URL(e).pathname.split("/").filter(Boolean)[0];return/^v[0-9]+$/i.test(t||"")?t:void 0}catch{return}})(e.checkout_url);return o?`${t.origin}/${o}/popup`:`${t.origin}/popup`}catch{return n}};const a=new class{container=null;iframe=null;messageListener=null;callbacks={};initRetryTimer=null;open(e){const t=(e=>{if("token"===e.mode)return e;if("public_key"===e.mode)return e;throw new Error('Payinto Checkout: invalid options. Provide a valid mode ("token" or "public_key").')})(e);this.container&&this.close(),this.callbacks={onClose:t.onClose,onSuccess:t.onSuccess,onError:t.onError,callback:t.callback},this.mountOverlay();(async()=>{try{const e="token"===t.mode?this.validateTokenMode(t):await this.initializePublicKeyMode(t);this.bindMessageListener(),this.initializeIframe(e)}catch(e){const t=e instanceof Error?e.message:"Unable to initialize checkout.";this.handleError({type:"checkout.error",code:"initialization_failed",message:t})}})()}pay(e){this.open(e)}close=()=>{this.clearInitRetry(),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.container&&document.body.contains(this.container)&&document.body.removeChild(this.container),this.container=null,this.iframe=null,document.body.classList.remove("payinto-checkout-open")};clearInitRetry(){null!==this.initRetryTimer&&(window.clearInterval(this.initRetryTimer),this.initRetryTimer=null)}mountOverlay(){const e=document.createElement("div");e.id="payinto-checkout-container",e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.right="0",e.style.bottom="0",e.style.width="100%",e.style.minHeight="100vh",e.style.height="100%",e.style.backgroundColor="rgba(0, 0, 0, 0.85)",e.style.zIndex="9999",e.style.display="flex",e.style.alignItems="flex-start",e.style.justifyContent="center",e.style.overflowY="auto",e.style.paddingTop="6rem",e.style.paddingBottom="2rem",e.style.boxSizing="border-box";const t=document.createElement("div");t.className="payinto-preloader",t.style.display="flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.position="absolute",t.style.top="6rem",t.style.left="50%",t.style.transform="translateX(-50%)",t.style.width="100%",t.style.maxWidth="650px",t.style.padding="4rem 0",t.style.zIndex="10",t.style.fontFamily="system-ui, -apple-system, sans-serif";const o=document.createElement("div");o.style.width="40px",o.style.height="40px",o.style.borderRadius="50%",o.style.border="2px solid transparent",o.style.borderBottom="2px solid #ffffff",o.style.marginBottom="16px",o.style.animation="spin 1s linear infinite";const i=document.createElement("p");i.id="payinto-checkout-subtitle",i.innerText="Initializing Secure Checkout...",i.style.fontSize="12px",i.style.color="#e5e7eb",i.style.margin="0",t.appendChild(o),t.appendChild(i),e.appendChild(t);const r=document.createElement("iframe");if(r.src=n,r.style.width="100%",r.style.maxWidth="650px",r.style.height="auto",r.style.border="none",r.style.backgroundColor="transparent",r.style.opacity="0",r.style.transition="opacity 0.25s ease",r.allow="payment; clipboard-read; clipboard-write",e.appendChild(r),!document.getElementById("payinto-checkout-styles")){const e=document.createElement("style");e.id="payinto-checkout-styles",e.innerHTML="\n @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n body.payinto-checkout-open { overflow: hidden !important; }\n @media (max-width: 767px) {\n #payinto-checkout-container {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n height: 100% !important;\n min-height: 100vh !important;\n overflow-y: auto !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .payinto-preloader { top: 2rem !important; }\n }\n ",document.head.appendChild(e)}document.body.appendChild(e),document.body.classList.add("payinto-checkout-open"),this.container=e,this.iframe=r}validateTokenMode(e){if(!e.token||"string"!=typeof e.token)throw new Error('Payinto Checkout: token is required for mode="token".');if(!e.checkout_url||"string"!=typeof e.checkout_url)throw new Error('Payinto Checkout: checkout_url is required for mode="token".');if(!new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: invalid checkout_url.");return{token:e.token,checkout_url:e.checkout_url,merchant_reference:e.merchant_reference,checkout_version:e.checkout_version}}async initializePublicKeyMode(e){if(!e.public_key)throw new Error('Payinto Checkout: public_key is required for mode="public_key".');if(!e.customer?.email)throw new Error('Payinto Checkout: customer.email is required for mode="public_key".');if(!e.amount||e.amount<=0)throw new Error('Payinto Checkout: amount must be greater than zero for mode="public_key".');const t={merchant_reference:e.merchant_reference,amount:e.amount,currency:e.currency,customer:e.customer,redirect_url:e.redirect_url,metadata:e.metadata,checkout_version:e.checkout_version},o=await fetch("https://api.payinto.co/api/v1/checkout/initialize",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",Authorization:`Bearer ${e.public_key}`},body:JSON.stringify(t)});if(!o.ok){const e=(e=>{try{return JSON.parse(e)}catch{return null}})(await o.text());throw new Error(e?.message||"Failed to initialize transaction.")}const n=await o.json(),i=n.data||(n.token&&n.checkout_url?{token:n.token,checkout_url:n.checkout_url,merchant_reference:n.merchant_reference,checkout_version:n.checkout_version}:void 0);if(!i?.token||!i?.checkout_url)throw new Error("Payinto Checkout: invalid initialize response.");return{token:i.token,checkout_url:i.checkout_url,merchant_reference:i.merchant_reference,checkout_version:i.checkout_version}}initializeIframe(e){if(!this.iframe||!this.container)return;const t=this.container.querySelector("#payinto-checkout-subtitle"),o=this.container.querySelector(".payinto-preloader"),n=s(e),i=new URL(n).origin,r=new URL(e.checkout_url).origin,a=Array.from(/* @__PURE__ */new Set([i,r]));if(!c.has(i)&&i!==new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: target origin is not in allowlist.");this.iframe.src=`${n}?updated=${Date.now()}`,this.iframe.onload=()=>{o&&(o.style.display="none"),this.iframe&&(this.iframe.style.opacity="1");const t=()=>{const t={type:"checkout.init",token:e.token,merchant_reference:e.merchant_reference,checkout_url:e.checkout_url};for(const e of a)this.iframe?.contentWindow?.postMessage(t,e)};t(),this.clearInitRetry();let n=0;this.initRetryTimer=window.setInterval(()=>{n+=1,n>=8?this.clearInitRetry():t()},500)},t&&(t.innerText="Loading checkout...")}bindMessageListener(){const e=e=>{if(!c.has(e.origin))return;this.clearInitRetry();const t=e.data;if("object"==typeof t&&"checkout.resize"===t?.type&&this.iframe)this.iframe.style.height=`${Math.max(300,t.height||0)}px`;else{if("object"==typeof t&&"checkout.close"===t?.type)return this.callbacks.onClose?.(),void this.close();if("object"==typeof t&&"checkout.success"===t?.type||"checkout.success"===t){const e="object"==typeof t?t:{type:"checkout.success",status:"success"};return this.callbacks.onSuccess?.(e),this.callbacks.callback?.(e),void this.close()}"object"==typeof t&&"checkout.error"===t?.type&&this.handleError(t)}};this.messageListener=e,window.addEventListener("message",e)}handleError(e){if(this.callbacks.onError?.(e),this.container){const t=this.container.querySelector(".payinto-preloader"),o=this.container.querySelector("#payinto-checkout-subtitle");t&&(t.style.display="flex"),o&&(o.innerText=e.message,o.style.color="#ff4444")}setTimeout(()=>{this.close()},1800)}},l={open:e=>a.open(e),pay:e=>a.pay(e),close:()=>a.close()},h=e=>{a.open(e)};h.open=e=>a.open(e),h.pay=e=>a.pay(e),h.close=()=>a.close(),e&&(window.PayintoCheckout=h);export{l as PayintoCheckoutApi,l as default};
1
+ const e="undefined"!=typeof window,t=e?"https://checkout.payinto.co":"",o="/v1".replace(/\/+$/,""),n=`${t}${o}/popup`,i="https://checkout.payinto.co,https://go.payinto.co".split(",").map(e=>e.trim()).filter(Boolean),r=e?new URL(n).origin:"",c=/* @__PURE__ */new Set([r,...i]),s=e=>{try{const t=new URL(e.checkout_url),o=e.checkout_version||(e=>{try{const t=new URL(e).pathname.split("/").filter(Boolean)[0];return/^v[0-9]+$/i.test(t||"")?t:void 0}catch{return}})(e.checkout_url);return o?`${t.origin}/${o}/popup`:`${t.origin}/popup`}catch{return n}};const a=new class{container=null;iframe=null;messageListener=null;callbacks={};initRetryTimer=null;open(e){const t=(e=>{if("token"===e.mode)return e;if("public_key"===e.mode)return e;throw new Error('Payinto Checkout: invalid options. Provide a valid mode ("token" or "public_key").')})(e);this.container&&this.close(),this.callbacks={onClose:t.onClose,onSuccess:t.onSuccess,onError:t.onError,callback:t.callback},this.mountOverlay();(async()=>{try{const e="token"===t.mode?this.validateTokenMode(t):await this.initializePublicKeyMode(t);this.bindMessageListener(),this.initializeIframe(e)}catch(e){const t=e instanceof Error?e.message:"Unable to initialize checkout.";this.handleError({type:"checkout.error",code:"initialization_failed",message:t})}})()}pay(e){this.open(e)}close=()=>{this.clearInitRetry(),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.container&&document.body.contains(this.container)&&document.body.removeChild(this.container),this.container=null,this.iframe=null,document.body.classList.remove("payinto-checkout-open")};clearInitRetry(){null!==this.initRetryTimer&&(window.clearInterval(this.initRetryTimer),this.initRetryTimer=null)}mountOverlay(){const e=document.createElement("div");e.id="payinto-checkout-container",e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.right="0",e.style.bottom="0",e.style.width="100%",e.style.minHeight="100vh",e.style.height="100%",e.style.backgroundColor="rgba(0, 0, 0, 0.85)",e.style.zIndex="9999",e.style.display="flex",e.style.alignItems="flex-start",e.style.justifyContent="center",e.style.overflowY="auto",e.style.paddingTop="6rem",e.style.paddingBottom="2rem",e.style.boxSizing="border-box";const t=document.createElement("div");t.className="payinto-preloader",t.style.display="flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.position="absolute",t.style.top="6rem",t.style.left="50%",t.style.transform="translateX(-50%)",t.style.width="100%",t.style.maxWidth="720px",t.style.padding="4rem 0",t.style.zIndex="10",t.style.fontFamily="system-ui, -apple-system, sans-serif";const o=document.createElement("div");o.style.width="40px",o.style.height="40px",o.style.borderRadius="50%",o.style.border="2px solid transparent",o.style.borderBottom="2px solid #ffffff",o.style.marginBottom="16px",o.style.animation="spin 1s linear infinite";const i=document.createElement("p");i.id="payinto-checkout-subtitle",i.innerText="Initializing Secure Checkout...",i.style.fontSize="12px",i.style.color="#e5e7eb",i.style.margin="0",t.appendChild(o),t.appendChild(i),e.appendChild(t);const r=document.createElement("iframe");if(r.src=n,r.style.width="100%",r.style.maxWidth="720px",r.style.height="auto",r.style.border="none",r.style.backgroundColor="transparent",r.style.opacity="0",r.style.transition="opacity 0.25s ease",r.allow="payment; clipboard-read; clipboard-write",e.appendChild(r),!document.getElementById("payinto-checkout-styles")){const e=document.createElement("style");e.id="payinto-checkout-styles",e.innerHTML="\n @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n body.payinto-checkout-open { overflow: hidden !important; }\n @media (max-width: 767px) {\n #payinto-checkout-container {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n height: 100% !important;\n min-height: 100vh !important;\n overflow-y: auto !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .payinto-preloader { top: 2rem !important; }\n }\n ",document.head.appendChild(e)}document.body.appendChild(e),document.body.classList.add("payinto-checkout-open"),this.container=e,this.iframe=r}validateTokenMode(e){if(!e.token||"string"!=typeof e.token)throw new Error('Payinto Checkout: token is required for mode="token".');if(!e.checkout_url||"string"!=typeof e.checkout_url)throw new Error('Payinto Checkout: checkout_url is required for mode="token".');if(!new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: invalid checkout_url.");return{token:e.token,checkout_url:e.checkout_url,merchant_reference:e.merchant_reference,checkout_version:e.checkout_version}}async initializePublicKeyMode(e){if(!e.public_key)throw new Error('Payinto Checkout: public_key is required for mode="public_key".');if(!e.customer?.email)throw new Error('Payinto Checkout: customer.email is required for mode="public_key".');if(!e.amount||e.amount<=0)throw new Error('Payinto Checkout: amount must be greater than zero for mode="public_key".');const t={merchant_reference:e.merchant_reference,amount:e.amount,currency:e.currency,customer:e.customer,redirect_url:e.redirect_url,metadata:e.metadata,checkout_version:e.checkout_version},o=await fetch("https://api.payinto.co/api/v1/checkout/initialize",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",Authorization:`Bearer ${e.public_key}`},body:JSON.stringify(t)});if(!o.ok){const e=(e=>{try{return JSON.parse(e)}catch{return null}})(await o.text());throw new Error(e?.message||"Failed to initialize transaction.")}const n=await o.json(),i=n.data||(n.token&&n.checkout_url?{token:n.token,checkout_url:n.checkout_url,merchant_reference:n.merchant_reference,checkout_version:n.checkout_version}:void 0);if(!i?.token||!i?.checkout_url)throw new Error("Payinto Checkout: invalid initialize response.");return{token:i.token,checkout_url:i.checkout_url,merchant_reference:i.merchant_reference,checkout_version:i.checkout_version}}initializeIframe(e){if(!this.iframe||!this.container)return;const t=this.container.querySelector("#payinto-checkout-subtitle"),o=this.container.querySelector(".payinto-preloader"),n=s(e),i=new URL(n).origin,r=new URL(e.checkout_url).origin,a=Array.from(/* @__PURE__ */new Set([i,r]));if(!c.has(i)&&i!==new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: target origin is not in allowlist.");this.iframe.src=`${n}?updated=${Date.now()}`,this.iframe.onload=()=>{o&&(o.style.display="none"),this.iframe&&(this.iframe.style.opacity="1");const t=()=>{const t={type:"checkout.init",token:e.token,merchant_reference:e.merchant_reference,checkout_url:e.checkout_url};for(const e of a)this.iframe?.contentWindow?.postMessage(t,e)};t(),this.clearInitRetry();let n=0;this.initRetryTimer=window.setInterval(()=>{n+=1,n>=8?this.clearInitRetry():t()},500)},t&&(t.innerText="Loading checkout...")}bindMessageListener(){const e=e=>{if(!c.has(e.origin))return;this.clearInitRetry();const t=e.data;if("object"==typeof t&&"checkout.resize"===t?.type&&this.iframe)this.iframe.style.height=`${Math.max(300,t.height||0)}px`;else{if("object"==typeof t&&"checkout.close"===t?.type)return this.callbacks.onClose?.(),void this.close();if("object"==typeof t&&"checkout.success"===t?.type||"checkout.success"===t){const e="object"==typeof t?t:{type:"checkout.success",status:"success"};return this.callbacks.onSuccess?.(e),this.callbacks.callback?.(e),void this.close()}"object"==typeof t&&"checkout.error"===t?.type&&this.handleError(t)}};this.messageListener=e,window.addEventListener("message",e)}handleError(e){if(this.callbacks.onError?.(e),this.container){const t=this.container.querySelector(".payinto-preloader"),o=this.container.querySelector("#payinto-checkout-subtitle");t&&(t.style.display="flex"),o&&(o.innerText=e.message,o.style.color="#ff4444")}setTimeout(()=>{this.close()},1800)}},l={open:e=>a.open(e),pay:e=>a.pay(e),close:()=>a.close()},h=e=>{a.open(e)};h.open=e=>a.open(e),h.pay=e=>a.pay(e),h.close=()=>a.close(),e&&(window.PayintoCheckout=h);export{l as PayintoCheckoutApi,l as default};
@@ -1 +1 @@
1
- var PayintoCheckout=function(e){"use strict";const t="undefined"!=typeof window,o=t?"https://checkout.payinto.co":"",n="/v1".replace(/\/+$/,""),i=`${o}${n}/popup`,r="https://checkout.payinto.co,https://go.payinto.co".split(",").map(e=>e.trim()).filter(Boolean),c=t?new URL(i).origin:"",s=new Set([c,...r]),a=e=>{try{const t=new URL(e.checkout_url),o=e.checkout_version||(e=>{try{const t=new URL(e).pathname.split("/").filter(Boolean)[0];return/^v[0-9]+$/i.test(t||"")?t:void 0}catch{return}})(e.checkout_url);return o?`${t.origin}/${o}/popup`:`${t.origin}/popup`}catch{return i}};const l=new class{container=null;iframe=null;messageListener=null;callbacks={};initRetryTimer=null;open(e){const t=(e=>{if("token"===e.mode)return e;if("public_key"===e.mode)return e;throw new Error('Payinto Checkout: invalid options. Provide a valid mode ("token" or "public_key").')})(e);this.container&&this.close(),this.callbacks={onClose:t.onClose,onSuccess:t.onSuccess,onError:t.onError,callback:t.callback},this.mountOverlay();(async()=>{try{const e="token"===t.mode?this.validateTokenMode(t):await this.initializePublicKeyMode(t);this.bindMessageListener(),this.initializeIframe(e)}catch(e){const t=e instanceof Error?e.message:"Unable to initialize checkout.";this.handleError({type:"checkout.error",code:"initialization_failed",message:t})}})()}pay(e){this.open(e)}close=()=>{this.clearInitRetry(),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.container&&document.body.contains(this.container)&&document.body.removeChild(this.container),this.container=null,this.iframe=null,document.body.classList.remove("payinto-checkout-open")};clearInitRetry(){null!==this.initRetryTimer&&(window.clearInterval(this.initRetryTimer),this.initRetryTimer=null)}mountOverlay(){const e=document.createElement("div");e.id="payinto-checkout-container",e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.right="0",e.style.bottom="0",e.style.width="100%",e.style.minHeight="100vh",e.style.height="100%",e.style.backgroundColor="rgba(0, 0, 0, 0.85)",e.style.zIndex="9999",e.style.display="flex",e.style.alignItems="flex-start",e.style.justifyContent="center",e.style.overflowY="auto",e.style.paddingTop="6rem",e.style.paddingBottom="2rem",e.style.boxSizing="border-box";const t=document.createElement("div");t.className="payinto-preloader",t.style.display="flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.position="absolute",t.style.top="6rem",t.style.left="50%",t.style.transform="translateX(-50%)",t.style.width="100%",t.style.maxWidth="650px",t.style.padding="4rem 0",t.style.zIndex="10",t.style.fontFamily="system-ui, -apple-system, sans-serif";const o=document.createElement("div");o.style.width="40px",o.style.height="40px",o.style.borderRadius="50%",o.style.border="2px solid transparent",o.style.borderBottom="2px solid #ffffff",o.style.marginBottom="16px",o.style.animation="spin 1s linear infinite";const n=document.createElement("p");n.id="payinto-checkout-subtitle",n.innerText="Initializing Secure Checkout...",n.style.fontSize="12px",n.style.color="#e5e7eb",n.style.margin="0",t.appendChild(o),t.appendChild(n),e.appendChild(t);const r=document.createElement("iframe");if(r.src=i,r.style.width="100%",r.style.maxWidth="650px",r.style.height="auto",r.style.border="none",r.style.backgroundColor="transparent",r.style.opacity="0",r.style.transition="opacity 0.25s ease",r.allow="payment; clipboard-read; clipboard-write",e.appendChild(r),!document.getElementById("payinto-checkout-styles")){const e=document.createElement("style");e.id="payinto-checkout-styles",e.innerHTML="\n @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n body.payinto-checkout-open { overflow: hidden !important; }\n @media (max-width: 767px) {\n #payinto-checkout-container {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n height: 100% !important;\n min-height: 100vh !important;\n overflow-y: auto !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .payinto-preloader { top: 2rem !important; }\n }\n ",document.head.appendChild(e)}document.body.appendChild(e),document.body.classList.add("payinto-checkout-open"),this.container=e,this.iframe=r}validateTokenMode(e){if(!e.token||"string"!=typeof e.token)throw new Error('Payinto Checkout: token is required for mode="token".');if(!e.checkout_url||"string"!=typeof e.checkout_url)throw new Error('Payinto Checkout: checkout_url is required for mode="token".');if(!new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: invalid checkout_url.");return{token:e.token,checkout_url:e.checkout_url,merchant_reference:e.merchant_reference,checkout_version:e.checkout_version}}async initializePublicKeyMode(e){if(!e.public_key)throw new Error('Payinto Checkout: public_key is required for mode="public_key".');if(!e.customer?.email)throw new Error('Payinto Checkout: customer.email is required for mode="public_key".');if(!e.amount||e.amount<=0)throw new Error('Payinto Checkout: amount must be greater than zero for mode="public_key".');const t={merchant_reference:e.merchant_reference,amount:e.amount,currency:e.currency,customer:e.customer,redirect_url:e.redirect_url,metadata:e.metadata,checkout_version:e.checkout_version},o=await fetch("https://api.payinto.co/api/v1/checkout/initialize",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",Authorization:`Bearer ${e.public_key}`},body:JSON.stringify(t)});if(!o.ok){const e=(e=>{try{return JSON.parse(e)}catch{return null}})(await o.text());throw new Error(e?.message||"Failed to initialize transaction.")}const n=await o.json(),i=n.data||(n.token&&n.checkout_url?{token:n.token,checkout_url:n.checkout_url,merchant_reference:n.merchant_reference,checkout_version:n.checkout_version}:void 0);if(!i?.token||!i?.checkout_url)throw new Error("Payinto Checkout: invalid initialize response.");return{token:i.token,checkout_url:i.checkout_url,merchant_reference:i.merchant_reference,checkout_version:i.checkout_version}}initializeIframe(e){if(!this.iframe||!this.container)return;const t=this.container.querySelector("#payinto-checkout-subtitle"),o=this.container.querySelector(".payinto-preloader"),n=a(e),i=new URL(n).origin,r=new URL(e.checkout_url).origin,c=Array.from(new Set([i,r]));if(!s.has(i)&&i!==new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: target origin is not in allowlist.");this.iframe.src=`${n}?updated=${Date.now()}`,this.iframe.onload=()=>{o&&(o.style.display="none"),this.iframe&&(this.iframe.style.opacity="1");const t=()=>{const t={type:"checkout.init",token:e.token,merchant_reference:e.merchant_reference,checkout_url:e.checkout_url};for(const e of c)this.iframe?.contentWindow?.postMessage(t,e)};t(),this.clearInitRetry();let n=0;this.initRetryTimer=window.setInterval(()=>{n+=1,n>=8?this.clearInitRetry():t()},500)},t&&(t.innerText="Loading checkout...")}bindMessageListener(){const e=e=>{if(!s.has(e.origin))return;this.clearInitRetry();const t=e.data;if("object"==typeof t&&"checkout.resize"===t?.type&&this.iframe)this.iframe.style.height=`${Math.max(300,t.height||0)}px`;else{if("object"==typeof t&&"checkout.close"===t?.type)return this.callbacks.onClose?.(),void this.close();if("object"==typeof t&&"checkout.success"===t?.type||"checkout.success"===t){const e="object"==typeof t?t:{type:"checkout.success",status:"success"};return this.callbacks.onSuccess?.(e),this.callbacks.callback?.(e),void this.close()}"object"==typeof t&&"checkout.error"===t?.type&&this.handleError(t)}};this.messageListener=e,window.addEventListener("message",e)}handleError(e){if(this.callbacks.onError?.(e),this.container){const t=this.container.querySelector(".payinto-preloader"),o=this.container.querySelector("#payinto-checkout-subtitle");t&&(t.style.display="flex"),o&&(o.innerText=e.message,o.style.color="#ff4444")}setTimeout(()=>{this.close()},1800)}},u={open:e=>l.open(e),pay:e=>l.pay(e),close:()=>l.close()},h=e=>{l.open(e)};return h.open=e=>l.open(e),h.pay=e=>l.pay(e),h.close=()=>l.close(),t&&(window.PayintoCheckout=h),e.PayintoCheckoutApi=u,e.default=u,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),e}({});
1
+ var PayintoCheckoutBundle=function(e){"use strict";const t="undefined"!=typeof window,o=t?"https://checkout.payinto.co":"",n="/v1".replace(/\/+$/,""),i=`${o}${n}/popup`,r="https://checkout.payinto.co,https://go.payinto.co".split(",").map(e=>e.trim()).filter(Boolean),c=t?new URL(i).origin:"",s=new Set([c,...r]),a=e=>{try{const t=new URL(e.checkout_url),o=e.checkout_version||(e=>{try{const t=new URL(e).pathname.split("/").filter(Boolean)[0];return/^v[0-9]+$/i.test(t||"")?t:void 0}catch{return}})(e.checkout_url);return o?`${t.origin}/${o}/popup`:`${t.origin}/popup`}catch{return i}};const l=new class{container=null;iframe=null;messageListener=null;callbacks={};initRetryTimer=null;open(e){const t=(e=>{if("token"===e.mode)return e;if("public_key"===e.mode)return e;throw new Error('Payinto Checkout: invalid options. Provide a valid mode ("token" or "public_key").')})(e);this.container&&this.close(),this.callbacks={onClose:t.onClose,onSuccess:t.onSuccess,onError:t.onError,callback:t.callback},this.mountOverlay();(async()=>{try{const e="token"===t.mode?this.validateTokenMode(t):await this.initializePublicKeyMode(t);this.bindMessageListener(),this.initializeIframe(e)}catch(e){const t=e instanceof Error?e.message:"Unable to initialize checkout.";this.handleError({type:"checkout.error",code:"initialization_failed",message:t})}})()}pay(e){this.open(e)}close=()=>{this.clearInitRetry(),this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.container&&document.body.contains(this.container)&&document.body.removeChild(this.container),this.container=null,this.iframe=null,document.body.classList.remove("payinto-checkout-open")};clearInitRetry(){null!==this.initRetryTimer&&(window.clearInterval(this.initRetryTimer),this.initRetryTimer=null)}mountOverlay(){const e=document.createElement("div");e.id="payinto-checkout-container",e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.right="0",e.style.bottom="0",e.style.width="100%",e.style.minHeight="100vh",e.style.height="100%",e.style.backgroundColor="rgba(0, 0, 0, 0.85)",e.style.zIndex="9999",e.style.display="flex",e.style.alignItems="flex-start",e.style.justifyContent="center",e.style.overflowY="auto",e.style.paddingTop="6rem",e.style.paddingBottom="2rem",e.style.boxSizing="border-box";const t=document.createElement("div");t.className="payinto-preloader",t.style.display="flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.position="absolute",t.style.top="6rem",t.style.left="50%",t.style.transform="translateX(-50%)",t.style.width="100%",t.style.maxWidth="720px",t.style.padding="4rem 0",t.style.zIndex="10",t.style.fontFamily="system-ui, -apple-system, sans-serif";const o=document.createElement("div");o.style.width="40px",o.style.height="40px",o.style.borderRadius="50%",o.style.border="2px solid transparent",o.style.borderBottom="2px solid #ffffff",o.style.marginBottom="16px",o.style.animation="spin 1s linear infinite";const n=document.createElement("p");n.id="payinto-checkout-subtitle",n.innerText="Initializing Secure Checkout...",n.style.fontSize="12px",n.style.color="#e5e7eb",n.style.margin="0",t.appendChild(o),t.appendChild(n),e.appendChild(t);const r=document.createElement("iframe");if(r.src=i,r.style.width="100%",r.style.maxWidth="720px",r.style.height="auto",r.style.border="none",r.style.backgroundColor="transparent",r.style.opacity="0",r.style.transition="opacity 0.25s ease",r.allow="payment; clipboard-read; clipboard-write",e.appendChild(r),!document.getElementById("payinto-checkout-styles")){const e=document.createElement("style");e.id="payinto-checkout-styles",e.innerHTML="\n @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n body.payinto-checkout-open { overflow: hidden !important; }\n @media (max-width: 767px) {\n #payinto-checkout-container {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n height: 100% !important;\n min-height: 100vh !important;\n overflow-y: auto !important;\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .payinto-preloader { top: 2rem !important; }\n }\n ",document.head.appendChild(e)}document.body.appendChild(e),document.body.classList.add("payinto-checkout-open"),this.container=e,this.iframe=r}validateTokenMode(e){if(!e.token||"string"!=typeof e.token)throw new Error('Payinto Checkout: token is required for mode="token".');if(!e.checkout_url||"string"!=typeof e.checkout_url)throw new Error('Payinto Checkout: checkout_url is required for mode="token".');if(!new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: invalid checkout_url.");return{token:e.token,checkout_url:e.checkout_url,merchant_reference:e.merchant_reference,checkout_version:e.checkout_version}}async initializePublicKeyMode(e){if(!e.public_key)throw new Error('Payinto Checkout: public_key is required for mode="public_key".');if(!e.customer?.email)throw new Error('Payinto Checkout: customer.email is required for mode="public_key".');if(!e.amount||e.amount<=0)throw new Error('Payinto Checkout: amount must be greater than zero for mode="public_key".');const t={merchant_reference:e.merchant_reference,amount:e.amount,currency:e.currency,customer:e.customer,redirect_url:e.redirect_url,metadata:e.metadata,checkout_version:e.checkout_version},o=await fetch("https://api.payinto.co/api/v1/checkout/initialize",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json",Authorization:`Bearer ${e.public_key}`},body:JSON.stringify(t)});if(!o.ok){const e=(e=>{try{return JSON.parse(e)}catch{return null}})(await o.text());throw new Error(e?.message||"Failed to initialize transaction.")}const n=await o.json(),i=n.data||(n.token&&n.checkout_url?{token:n.token,checkout_url:n.checkout_url,merchant_reference:n.merchant_reference,checkout_version:n.checkout_version}:void 0);if(!i?.token||!i?.checkout_url)throw new Error("Payinto Checkout: invalid initialize response.");return{token:i.token,checkout_url:i.checkout_url,merchant_reference:i.merchant_reference,checkout_version:i.checkout_version}}initializeIframe(e){if(!this.iframe||!this.container)return;const t=this.container.querySelector("#payinto-checkout-subtitle"),o=this.container.querySelector(".payinto-preloader"),n=a(e),i=new URL(n).origin,r=new URL(e.checkout_url).origin,c=Array.from(new Set([i,r]));if(!s.has(i)&&i!==new URL(e.checkout_url).origin)throw new Error("Payinto Checkout: target origin is not in allowlist.");this.iframe.src=`${n}?updated=${Date.now()}`,this.iframe.onload=()=>{o&&(o.style.display="none"),this.iframe&&(this.iframe.style.opacity="1");const t=()=>{const t={type:"checkout.init",token:e.token,merchant_reference:e.merchant_reference,checkout_url:e.checkout_url};for(const e of c)this.iframe?.contentWindow?.postMessage(t,e)};t(),this.clearInitRetry();let n=0;this.initRetryTimer=window.setInterval(()=>{n+=1,n>=8?this.clearInitRetry():t()},500)},t&&(t.innerText="Loading checkout...")}bindMessageListener(){const e=e=>{if(!s.has(e.origin))return;this.clearInitRetry();const t=e.data;if("object"==typeof t&&"checkout.resize"===t?.type&&this.iframe)this.iframe.style.height=`${Math.max(300,t.height||0)}px`;else{if("object"==typeof t&&"checkout.close"===t?.type)return this.callbacks.onClose?.(),void this.close();if("object"==typeof t&&"checkout.success"===t?.type||"checkout.success"===t){const e="object"==typeof t?t:{type:"checkout.success",status:"success"};return this.callbacks.onSuccess?.(e),this.callbacks.callback?.(e),void this.close()}"object"==typeof t&&"checkout.error"===t?.type&&this.handleError(t)}};this.messageListener=e,window.addEventListener("message",e)}handleError(e){if(this.callbacks.onError?.(e),this.container){const t=this.container.querySelector(".payinto-preloader"),o=this.container.querySelector("#payinto-checkout-subtitle");t&&(t.style.display="flex"),o&&(o.innerText=e.message,o.style.color="#ff4444")}setTimeout(()=>{this.close()},1800)}},u={open:e=>l.open(e),pay:e=>l.pay(e),close:()=>l.close()},h=e=>{l.open(e)};return h.open=e=>l.open(e),h.pay=e=>l.pay(e),h.close=()=>l.close(),t&&(window.PayintoCheckout=h),e.PayintoCheckoutApi=u,e.default=u,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),e}({});
package/dist/v1/demo.html CHANGED
@@ -44,12 +44,51 @@
44
44
  font-size: 14px;
45
45
  }
46
46
 
47
- .button-group {
48
- display: flex;
49
- flex-direction: column;
47
+ form {
48
+ display: grid;
49
+ gap: 16px;
50
+ }
51
+
52
+ .field-grid {
53
+ display: grid;
54
+ grid-template-columns: 1fr 1fr;
50
55
  gap: 12px;
51
56
  }
52
57
 
58
+ label {
59
+ display: grid;
60
+ gap: 6px;
61
+ color: #4a5568;
62
+ font-size: 12px;
63
+ font-weight: 700;
64
+ }
65
+
66
+ input,
67
+ select,
68
+ textarea {
69
+ width: 100%;
70
+ border: 1px solid #cbd5e0;
71
+ border-radius: 8px;
72
+ padding: 12px;
73
+ color: #1a202c;
74
+ font: inherit;
75
+ font-size: 14px;
76
+ outline: none;
77
+ transition: border-color 0.2s, box-shadow 0.2s;
78
+ }
79
+
80
+ input:focus,
81
+ select:focus,
82
+ textarea:focus {
83
+ border-color: #1a202c;
84
+ box-shadow: 0 0 0 3px rgba(26, 32, 44, 0.12);
85
+ }
86
+
87
+ textarea {
88
+ min-height: 82px;
89
+ resize: vertical;
90
+ }
91
+
53
92
  button {
54
93
  background: #1a202c;
55
94
  color: white;
@@ -72,6 +111,16 @@
72
111
  transform: translateY(0);
73
112
  }
74
113
 
114
+ .form-error {
115
+ display: none;
116
+ padding: 10px 12px;
117
+ border-radius: 8px;
118
+ background: #fff5f5;
119
+ color: #c53030;
120
+ font-size: 13px;
121
+ font-weight: 600;
122
+ }
123
+
75
124
  .code-block {
76
125
  background: #f7fafc;
77
126
  border: 1px solid #e2e8f0;
@@ -101,6 +150,16 @@
101
150
  text-transform: uppercase;
102
151
  margin-bottom: 16px;
103
152
  }
153
+
154
+ @media (max-width: 560px) {
155
+ .demo-container {
156
+ padding: 24px;
157
+ }
158
+
159
+ .field-grid {
160
+ grid-template-columns: 1fr;
161
+ }
162
+ }
104
163
  </style>
105
164
  </head>
106
165
 
@@ -108,40 +167,73 @@
108
167
  <div class="demo-container">
109
168
  <span class="badge">Demo</span>
110
169
  <h1>Payinto Checkout</h1>
111
- <p>Click the button below to test the payment checkout integration.</p>
170
+ <p>Enter checkout details and launch the local popup integration.</p>
171
+
172
+ <form id="checkout-form">
173
+ <label>
174
+ Public Key
175
+ <input id="public-key" name="public_key" value="pk_live_784683f25db04c05838ee730ce489e27e46e" required>
176
+ </label>
177
+
178
+ <div class="field-grid">
179
+ <label>
180
+ Amount
181
+ <input id="amount" name="amount" type="number" min="1" step="1" value="100000" required>
182
+ </label>
183
+
184
+ <label>
185
+ Currency
186
+ <select id="currency" name="currency">
187
+ <option value="NGN" selected>NGN</option>
188
+ <option value="USD">USD</option>
189
+ <option value="GBP">GBP</option>
190
+ </select>
191
+ </label>
192
+ </div>
193
+
194
+ <label>
195
+ Merchant Reference
196
+ <input id="merchant-reference" name="merchant_reference" value="TRANS_123456" required>
197
+ </label>
112
198
 
113
- <div class="button-group">
114
- <button onclick="openCheckout()">
115
- Pay NGN 10,000
199
+ <div class="field-grid">
200
+ <label>
201
+ Customer Name
202
+ <input id="customer-name" name="customer_name" value="John Doe">
203
+ </label>
204
+
205
+ <label>
206
+ Customer Email
207
+ <input id="customer-email" name="customer_email" type="email" value="john.doe@example.com" required>
208
+ </label>
209
+ </div>
210
+
211
+ <div class="field-grid">
212
+ <label>
213
+ Phone Number
214
+ <input id="phone-number" name="phone_number" value="08123456789">
215
+ </label>
216
+
217
+ <label>
218
+ Redirect URL
219
+ <input id="redirect-url" name="redirect_url" type="url" value="https://example.com/redirect">
220
+ </label>
221
+ </div>
222
+
223
+ <label>
224
+ Metadata JSON
225
+ <textarea id="metadata" name="metadata">{"custom_field":"custom_value"}</textarea>
226
+ </label>
227
+
228
+ <div id="form-error" class="form-error"></div>
229
+
230
+ <button type="submit">
231
+ Open Checkout
116
232
  </button>
117
- </div>
233
+ </form>
118
234
 
119
235
  <div class="code-block">
120
- <pre>PayintoCheckout({
121
- mode: 'public_key',
122
- public_key: 'pk_test_123456789',
123
- merchant_reference: 'TRANS_123456',
124
- amount: 100000,
125
- currency: 'NGN',
126
- customer: {
127
- email: 'customer@example.com',
128
- name: 'John Doe',
129
- phone_number: '08123456789'
130
- },
131
- metadata: {
132
- custom_field: 'custom_value'
133
- },
134
- // With Redirect URL to redirect to after payment
135
- redirect_url: 'https://example.com/redirect', // URL
136
- // OR Alternatively, you can specify a callback function to handle payment response
137
- onClose: function () {
138
- console.log('Checkout closed');
139
- },
140
- callback: function (response) {
141
- console.log('Payment successful:', response);
142
- }
143
-
144
- });</pre>
236
+ <pre id="payload-preview"></pre>
145
237
  </div>
146
238
  </div>
147
239
 
@@ -149,31 +241,90 @@
149
241
  <script src="/checkout.js"></script>
150
242
 
151
243
  <script>
152
- function openCheckout() {
153
- PayintoCheckout({
244
+ const form = document.getElementById('checkout-form');
245
+ const errorBox = document.getElementById('form-error');
246
+ const payloadPreview = document.getElementById('payload-preview');
247
+
248
+ function setError(message) {
249
+ errorBox.textContent = message;
250
+ errorBox.style.display = message ? 'block' : 'none';
251
+ }
252
+
253
+ function getMetadata() {
254
+ const value = document.getElementById('metadata').value.trim();
255
+ if (!value) return {};
256
+
257
+ try {
258
+ return JSON.parse(value);
259
+ } catch {
260
+ throw new Error('Metadata must be valid JSON.');
261
+ }
262
+ }
263
+
264
+ function getCheckoutPayload() {
265
+ return {
154
266
  mode: 'public_key',
155
- public_key: 'pk_live_784683f25db04c05838ee730ce489e27e46e', // Example public key
156
- merchant_reference: 'TRANS_123456',
157
- amount: 100000,
158
- currency: 'NGN',
267
+ public_key: document.getElementById('public-key').value.trim(),
268
+ merchant_reference: document.getElementById('merchant-reference').value.trim(),
269
+ amount: Number(document.getElementById('amount').value),
270
+ currency: document.getElementById('currency').value,
159
271
  customer: {
160
- name: 'John Doe',
161
- email: 'john.doe@example.com',
162
- phone_number: '08123456789'
163
- },
164
- redirect_url: 'https://example.com/redirect',
165
- metadata: {
166
- custom_field: 'custom_value'
272
+ name: document.getElementById('customer-name').value.trim(),
273
+ email: document.getElementById('customer-email').value.trim(),
274
+ phone_number: document.getElementById('phone-number').value.trim()
167
275
  },
276
+ redirect_url: document.getElementById('redirect-url').value.trim(),
277
+ metadata: getMetadata()
278
+ };
279
+ }
280
+
281
+ function updatePayloadPreview() {
282
+ try {
283
+ const payload = getCheckoutPayload();
284
+ payloadPreview.textContent = `PayintoCheckout(${JSON.stringify(payload, null, 4).replace(/\n/g, '\n ')});
285
+
286
+ // callbacks are attached by the demo:
287
+ // onClose, onError, callback`;
288
+ } catch {
289
+ payloadPreview.textContent = 'Metadata must be valid JSON to preview the payload.';
290
+ }
291
+ }
292
+
293
+ form.addEventListener('input', updatePayloadPreview);
294
+ updatePayloadPreview();
295
+
296
+ form.addEventListener('submit', function (event) {
297
+ event.preventDefault();
298
+ setError('');
299
+
300
+ let payload;
301
+ try {
302
+ payload = getCheckoutPayload();
303
+ } catch (error) {
304
+ setError(error.message);
305
+ return;
306
+ }
307
+
308
+ if (!Number.isFinite(payload.amount) || payload.amount <= 0) {
309
+ setError('Amount must be greater than zero.');
310
+ return;
311
+ }
312
+
313
+ PayintoCheckout({
314
+ ...payload,
168
315
  onClose: function () {
169
316
  console.log('Checkout closed');
170
317
  },
318
+ onError: function (error) {
319
+ console.error('Checkout error:', error);
320
+ setError(error.message || 'Checkout failed to initialize.');
321
+ },
171
322
  callback: function (response) {
172
323
  console.log('Payment successful:', response);
173
324
  // alert('Payment successful! ' + JSON.stringify(response));
174
325
  }
175
326
  });
176
- }
327
+ });
177
328
  </script>
178
329
  </body>
179
330
 
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@payinto/checkout-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
- "description": "Payinto Checkout SDK for popup payments (token and public_key modes)",
5
+ "description": "Payinto Checkout SDK for popup payments",
6
6
  "main": "./dist/v1/checkout.es.js",
7
7
  "module": "./dist/v1/checkout.es.js",
8
8
  "types": "./dist/v1/types/checkout-sdk.d.ts",