@payinto/checkout-sdk 1.1.0 → 1.3.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.
- package/README.md +2 -0
- package/dist/v1/checkout.es.js +1 -1
- package/dist/v1/checkout.js +1 -1
- package/dist/v1/demo.html +208 -47
- package/dist/v1/types/checkout-sdk.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@ const handlePayment = () => {
|
|
|
32
32
|
email: 'customer@example.com',
|
|
33
33
|
name: 'John Doe'
|
|
34
34
|
},
|
|
35
|
+
settlement_account_id: '01964316-57cb-7284-8651-c53d3fcee694',
|
|
35
36
|
onSuccess: (response) => {
|
|
36
37
|
console.log('Payment successful:', response);
|
|
37
38
|
},
|
|
@@ -66,6 +67,7 @@ window.PayintoCheckout.open({
|
|
|
66
67
|
| `customer` | `object` | Yes | Customer details (`email` is required). |
|
|
67
68
|
| `merchant_reference` | `string` | No | Unique merchant transaction reference. |
|
|
68
69
|
| `metadata` | `object` | No | Additional data for the transaction. |
|
|
70
|
+
| `settlement_account_id` | `string` | No | The ID of the settlement account to receive funds for this checkout. If omitted, your Payinto Main account is used. |
|
|
69
71
|
| `redirect_url`| `string` | No | URL to redirect to after successful payment. |
|
|
70
72
|
| `onSuccess` | `function`| No | Callback on successful payment. |
|
|
71
73
|
| `onClose` | `function`| No | Callback when the checkout is closed. |
|
package/dist/v1/checkout.es.js
CHANGED
|
@@ -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="
|
|
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,settlement_account_id:e.settlement_account_id,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};
|
package/dist/v1/checkout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
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,settlement_account_id:e.settlement_account_id,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
|
-
|
|
48
|
-
display:
|
|
49
|
-
|
|
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,78 @@
|
|
|
108
167
|
<div class="demo-container">
|
|
109
168
|
<span class="badge">Demo</span>
|
|
110
169
|
<h1>Payinto Checkout</h1>
|
|
111
|
-
<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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
199
|
+
<label>
|
|
200
|
+
Settlement Account ID
|
|
201
|
+
<input id="settlement-account-id" name="settlement_account_id" placeholder="Optional local accounts.id">
|
|
202
|
+
</label>
|
|
203
|
+
|
|
204
|
+
<div class="field-grid">
|
|
205
|
+
<label>
|
|
206
|
+
Customer Name
|
|
207
|
+
<input id="customer-name" name="customer_name" value="John Doe">
|
|
208
|
+
</label>
|
|
209
|
+
|
|
210
|
+
<label>
|
|
211
|
+
Customer Email
|
|
212
|
+
<input id="customer-email" name="customer_email" type="email" value="john.doe@example.com" required>
|
|
213
|
+
</label>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div class="field-grid">
|
|
217
|
+
<label>
|
|
218
|
+
Phone Number
|
|
219
|
+
<input id="phone-number" name="phone_number" value="08123456789">
|
|
220
|
+
</label>
|
|
221
|
+
|
|
222
|
+
<label>
|
|
223
|
+
Redirect URL
|
|
224
|
+
<input id="redirect-url" name="redirect_url" type="url" value="https://example.com/redirect">
|
|
225
|
+
</label>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<label>
|
|
229
|
+
Metadata JSON
|
|
230
|
+
<textarea id="metadata" name="metadata">{"custom_field":"custom_value"}</textarea>
|
|
231
|
+
</label>
|
|
232
|
+
|
|
233
|
+
<div id="form-error" class="form-error"></div>
|
|
234
|
+
|
|
235
|
+
<button type="submit">
|
|
236
|
+
Open Checkout
|
|
116
237
|
</button>
|
|
117
|
-
</
|
|
238
|
+
</form>
|
|
118
239
|
|
|
119
240
|
<div class="code-block">
|
|
120
|
-
<pre>
|
|
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>
|
|
241
|
+
<pre id="payload-preview"></pre>
|
|
145
242
|
</div>
|
|
146
243
|
</div>
|
|
147
244
|
|
|
@@ -149,31 +246,95 @@
|
|
|
149
246
|
<script src="/checkout.js"></script>
|
|
150
247
|
|
|
151
248
|
<script>
|
|
152
|
-
|
|
153
|
-
|
|
249
|
+
const form = document.getElementById('checkout-form');
|
|
250
|
+
const errorBox = document.getElementById('form-error');
|
|
251
|
+
const payloadPreview = document.getElementById('payload-preview');
|
|
252
|
+
|
|
253
|
+
function setError(message) {
|
|
254
|
+
errorBox.textContent = message;
|
|
255
|
+
errorBox.style.display = message ? 'block' : 'none';
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function getMetadata() {
|
|
259
|
+
const value = document.getElementById('metadata').value.trim();
|
|
260
|
+
if (!value) return {};
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
return JSON.parse(value);
|
|
264
|
+
} catch {
|
|
265
|
+
throw new Error('Metadata must be valid JSON.');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function getCheckoutPayload() {
|
|
270
|
+
const settlementAccountId = document.getElementById('settlement-account-id').value.trim();
|
|
271
|
+
const payload = {
|
|
154
272
|
mode: 'public_key',
|
|
155
|
-
public_key: '
|
|
156
|
-
merchant_reference: '
|
|
157
|
-
amount:
|
|
158
|
-
currency: '
|
|
273
|
+
public_key: document.getElementById('public-key').value.trim(),
|
|
274
|
+
merchant_reference: document.getElementById('merchant-reference').value.trim(),
|
|
275
|
+
amount: Number(document.getElementById('amount').value),
|
|
276
|
+
currency: document.getElementById('currency').value,
|
|
159
277
|
customer: {
|
|
160
|
-
name: '
|
|
161
|
-
email: '
|
|
162
|
-
phone_number: '
|
|
163
|
-
},
|
|
164
|
-
redirect_url: 'https://example.com/redirect',
|
|
165
|
-
metadata: {
|
|
166
|
-
custom_field: 'custom_value'
|
|
278
|
+
name: document.getElementById('customer-name').value.trim(),
|
|
279
|
+
email: document.getElementById('customer-email').value.trim(),
|
|
280
|
+
phone_number: document.getElementById('phone-number').value.trim()
|
|
167
281
|
},
|
|
282
|
+
redirect_url: document.getElementById('redirect-url').value.trim(),
|
|
283
|
+
metadata: getMetadata()
|
|
284
|
+
};
|
|
285
|
+
if (settlementAccountId) {
|
|
286
|
+
payload.settlement_account_id = settlementAccountId;
|
|
287
|
+
}
|
|
288
|
+
return payload;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function updatePayloadPreview() {
|
|
292
|
+
try {
|
|
293
|
+
const payload = getCheckoutPayload();
|
|
294
|
+
payloadPreview.textContent = `PayintoCheckout(${JSON.stringify(payload, null, 4).replace(/\n/g, '\n ')});
|
|
295
|
+
|
|
296
|
+
// callbacks are attached by the demo:
|
|
297
|
+
// onClose, onError, callback`;
|
|
298
|
+
} catch {
|
|
299
|
+
payloadPreview.textContent = 'Metadata must be valid JSON to preview the payload.';
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
form.addEventListener('input', updatePayloadPreview);
|
|
304
|
+
updatePayloadPreview();
|
|
305
|
+
|
|
306
|
+
form.addEventListener('submit', function (event) {
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
setError('');
|
|
309
|
+
|
|
310
|
+
let payload;
|
|
311
|
+
try {
|
|
312
|
+
payload = getCheckoutPayload();
|
|
313
|
+
} catch (error) {
|
|
314
|
+
setError(error.message);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (!Number.isFinite(payload.amount) || payload.amount <= 0) {
|
|
319
|
+
setError('Amount must be greater than zero.');
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
PayintoCheckout({
|
|
324
|
+
...payload,
|
|
168
325
|
onClose: function () {
|
|
169
326
|
console.log('Checkout closed');
|
|
170
327
|
},
|
|
328
|
+
onError: function (error) {
|
|
329
|
+
console.error('Checkout error:', error);
|
|
330
|
+
setError(error.message || 'Checkout failed to initialize.');
|
|
331
|
+
},
|
|
171
332
|
callback: function (response) {
|
|
172
333
|
console.log('Payment successful:', response);
|
|
173
334
|
// alert('Payment successful! ' + JSON.stringify(response));
|
|
174
335
|
}
|
|
175
336
|
});
|
|
176
|
-
}
|
|
337
|
+
});
|
|
177
338
|
</script>
|
|
178
339
|
</body>
|
|
179
340
|
|
|
@@ -36,6 +36,7 @@ type PublicKeyModeOptions = CheckoutCallbacks & {
|
|
|
36
36
|
};
|
|
37
37
|
redirect_url?: string;
|
|
38
38
|
metadata?: Record<string, unknown>;
|
|
39
|
+
settlement_account_id?: string;
|
|
39
40
|
checkout_version?: string;
|
|
40
41
|
};
|
|
41
42
|
export type CheckoutOpenOptions = TokenModeOptions | PublicKeyModeOptions;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payinto/checkout-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Payinto Checkout SDK for popup payments
|
|
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",
|